For a background on session persistence in Stingray, please refer to the document Feature Brief: Session Persistence in Stingray Traffic Manager.
Stingray Traffic Manager does not implement explicit session persistence timeouts, whether you use on either client-side cookies or entries in the internal session table. Client-side cookies will typically remain for the duration of the browser session, and internal session table entries will time-out in a least-recently-used fashion as the session table fills up and spaces are recycled.
However, in most cases, the behavior of Stingray Traffic Manager results in the same behavior as if a session timeout existed. For example, consider the following flow that tried to emulate a 10-minute timeout for session data:
Operation |
With 10 minute countdown |
Stingray behavior (internal session cache) |
---|---|---|
Normal operation |
||
Client establishes new session |
Session with 10 minute countdown is created |
Session data is created |
Client submits requests in that session |
Requests directed to correct node. Session countdown reset to 10 minutes |
Requests directed to correct node. Session last-used time is reset to ‘now’ |
Client submits request after more than 10 minutes of inactivity |
Session is broken; Load balancer has forgotten client session |
Session continues (unless session cache is too small and entries are dropped out in less than 10 minutes) |
Draining a node |
||
Node is marked as ‘draining’ |
Session is maintained against that node for as long as the session is active |
Session is maintained against that node for as long as the session is active |
Can I remove the node after 10 minutes? |
No: Sessions may still be active. |
No: Sessions may still be active. |
All clients are inactive for more than 10 minutes |
All sessions will have been dropped. Node may be removed |
Last-used timer for node exceeds 10 minutes. Node may be removed |
Client reconnects with existing session after 10 minutes. |
Session is broken because record has been dropped |
Session is only broken if node has been removed; is valid if node is still present |
Session is broken |
||
Session times out, is dropped from cache, or target node has failed |
Load Balancer selects new node based on load balancing method |
Stingray selects |
Stingray’s behavior is very similar if a client-cookie session method is used; sessions last for the duration of the browser session and there is no risk that a session may be dropped because an internal table fills up.
There may be exceptional circumstances where a service requires explicit session persistence timeouts. These may be implemented using client-side cookies that expire after the timeout period.
The following TrafficScript rule illustrates the principle simply. The rule should be assigned as both a Request and Response rule, and the pool should be configured to use a Named Node session persistence class:
# Assign this rule as both a Request and Response rule # Session expiry time (in seconds) $expires = 10; $cookiename = "X-Session-ID"; if( rule.getState() == "REQUEST" ) { $node = http.getCookie( $cookiename ); if( $node ) { # Make sure that you use a 'named node' persistence class connection.setPersistenceNode( $node ); } } if( rule.getState() == "RESPONSE" ) { # generate the cookie each time to refresh the timeout http.setResponseCookie( $cookiename, connection.getNode(), "max-age=".$expires ); }
In practice, you may wish to use a more sophisticated rule that:
# Assign this rule as both a Request and Response rule # Session expiry time (in seconds) $expires = 10; # Optional - if you don't want to apply session persistence to this request, exit the rule now $path = http.getPath(); string.regexMatch( $path, '\.([^/]*)$' ); $ext = $1; if( array.contains( ['jpg', 'gif', 'png', 'js', 'css'], $ext ) ) break; # Generate a unique cooke for each virtual server and encrypt the node name to obscure it $cookiename = "X-Session-".string.hexencode(string.hash(connection.getVirtualServer())); $encnode = http.getCookie( $cookiename ); $node = string.decrypt( $encnode, $cookiename ); if( rule.getState() == "REQUEST" ) { if( $node ) { # Make sure that you use a 'named node' persistence class connection.setPersistenceNode( $node ); } } if( rule.getState() == "RESPONSE" ) { # generate the cookie each time to refresh the timeout if( !$encnode || $node != connection.getNode() ) $encnode = string.encrypt( connection.getNode(), $cookiename ); http.setResponseCookie( $cookiename, $encnode, "max-age=".$expires ); }