Consider the process of conducting a transaction in your application - perhaps your user is uploading and annotating an image, or concluding a shopping cart transaction.
This process may entail a number of individual operations - for example, several HTTP POSTs to upload and annotate the image - and you may want to ensure that these network transactions are routed to the same back-end server. Your application design may mandate this (because intermediate state is not shared between nodes in a cluster), or it just may be highly desireable (for performance and cache-hit reasons).
Traffic Manager's Load Balancing (Feature Brief: Load Balancing in Traffic Manager) will work against you. Traffic Manager will process each network operation independently, and it's very likely that the network transactions will be routed to different machines in your cluster. In this case, you need to be firm with Traffic Manager and require that all transactions in the same 'session' are routed to the same machine.
Enter 'Session Persistence' - the means to override the load balancing decision and pin 'sessions' to the same server machine.
Traffic Manager employs a range of session persistence methods, each with a different way to identify a session. You should generally select the session persistence method that most accurately identifies user sessions for the application you are load balancing.
Persistence Type |
Session identifier |
Session data store |
---|---|---|
IP-based persistence |
Source IP address |
Internal session cache |
Universal session persistence |
TrafficScript-generated key |
Internal session cache |
Named Node session persistence |
TrafficScript specifies node |
None |
Transparent session affinity |
HTTP browser session |
Client-side Cookie (set by Stingray) |
Monitor application cookies |
Named application cookie |
Client-side Cookie (set by Stingray) |
J2EE session persistence |
J2EE session identifier |
Internal session cache |
ASP and ASP.NET session persistence |
ASP/ASP.Net session identifiers |
Internal session cache |
X-Zeus-Backend cookies |
Provided by backend node |
Client-side Cookie (set by backend) |
SSL Session ID persistence |
SSL Session ID |
Internal session cache |
For a detailed description of the various session persistence methods, please refer to the User Manual (Product Documentation).
Traffic Manager will issue a Set-Cookie header to store the name of the desired node in a client-side cookie. The cookie identifier and the name of the node are both hashed to prevent tampering or information leakage:
Session data is stored in Traffic Manager in a fixed-size cache, and replicated across the cluster according to the ‘State Synchronization Settings’ (Global Settings).
All session persistence classes of the same type will share the same cache space. The session persistence caches function in a ‘Least Recently Used’ fashion: each time an entry is accessed, its timestamp is updated. When an entry must be removed to make room for a new session, the entry with the oldest timestamp is dropped.
Session persistence ties the requests from one client (ie, in one 'session') to the same back-end server node. It defeats the intelligence of the load-balancing algorithm, which tries to select the fastest, most available node for each request.
In a web session, often it's only necessary to tie some requests to the same server node. For example, you may want to tie requests that begin "/servlet" to a server node, but let Traffic Manager be free to load-balance all other requests (images, static content) as appropriate.
Session Persistence may be a property of a pool - all requests processed by that pool are assigned to a session and routed accordingly - but if you want more control you can control it using TrafficScript.
Configure a session persistence class with the desired configuration for your /servlet requests, then use the following request rule:
if( string.startswith( http.getPath(), "/servlet" ) ) { connection.setPersistenceClass( "servlet persistence" ); }
If a client connects and no session persistence entry exists in the internal table, then the connection will be handled as if it were a new session. Traffic Manager will apply load-balancing to select the most appropriate node, and then record the selection in the session table. The record will be broadcast to other Traffic Manager machines in the cluster.
If the session data (client cookie or internal table) references a node that is not available (it has failed or has been removed), then the default behavior is to delete the session record and load-balance to a working node.
This behavior may be modified on a Persistence class basis, to send a ‘sorry’ message or just drop the connection:
Configure how to respond and how to manage the session if a target node cannot be reached
If a node is marked as draining then existing sessions will be directed to that node, but no new sessions will be established. Once the existing sessions have completed, it is safe to remove the node without interrupting connections or sessions.
Traffic Manager provides a counter indicating when the node was last used. If you wish to time sessions out after 10 minutes of activity, then you can remove the node once the counter passes 10 minutes:
The ‘Connection Draining’ report indicates how long ago the last session was active on a node
If a node is marked as disabled, no connections are sent to it. Existing connections will continue until they are closed. In addition, Traffic Manager stops running health monitors against the disabled node. Disabling a node is a convenient way to take it out of service temporarily (for example, to apply a software update) without removing it completely from the configuration.
SNMP and Activity Monitor counters may be used to monitor the behavior of the session cache. You will observe that the cache gradually fills up as sessions are added, and then remains full. The max age of cache entries will likely follow a fine saw-tooth pattern as the oldest entry gradually ages and then is either dropped or refreshed, although this is only visible if new entries are added infrequently:
In the first 4 minutes, traffic is steady at 300 new sessions per minute and the session cache fills. Initially, the max age grows steadily but when the cache fills (after 2 minutes) the max age remains fairly stable as older entries are dropped. In the last minute, no new entries were added, so the cache remains full and the max-age increases steadily.
The ‘Current Connections’ table will display the node that was selected for each transaction that the traffic manager processed:
Observe that requests have been evenly distributed between nodes 201, 202 and 203 because no session persistence is active
Transaction logging can give additional information. Access logs support webserver-style macros, and the following macros are useful:
Macro |
Description |
---|---|
%F |
The favored node; this is a hint to the load-balancing algorithm to optimize node cache usage |
%N |
The required node (may be blank): defined by a session persistence method |
%n |
The actual node used by the connection; may differ from %F if the favoured node is overloaded, and differ from %N if the required node has failed |
Finally, TrafficScript can be used to annotate pages with the name of the node they were served from:
if( http.getResponseHeader( "Content-Type" ) != "text/html" ) break; $body = http.getResponseBody(); $html = '<div style="position:absolute;top:0;left:0;border:1px solid black;background:white">'. 'Served by ' . connection.getNode() . '</div>'; $body = string.regexsub( $body, "(<body[^>]*>)", "$1\n".$html."\n", "i" ); http.setResponseBody( $body );
Like caching, session persistence breaks the simple model of load-balancing each transaction to the least-loaded server. If used without a full understanding of the consequences, it can provoke strange and unexpected behavior.
The built-in session persistence methods in Traffic Manager are suitable for a wide range of applications, but it’s always possible to construct situations with fragile applications or small numbers of clients where session persistence is not the right solution for the problem at hand.
Session persistence should be regarded as a performance optimization, ensuring that users are directed to a node that has their session data ready and fresh in a local cache. No application should absolutely depend upon session persistence, because to do so would introduce a single point of failure for every users’ session.
Pragmatically, it is not always possible to achieve this. Traffic Manager's TrafficScript language provides the means to fine-tune session persistence to accurately recognize individual sessions, apply session persistence judiciously to the transactions that require it, and implement timeouts if required.