Load balancing based on ASP SessionID
Problem this snippet solves:
The code separates into 2 irules, one for request and one for response. The app in question only issues out 1 cookie. The al_start.asp? starts the session adn teh session will end with al_stop.asp or with a timeout so this what the irules rotate around
Code :
#request irule when RULE_INIT { #initialize the arrays the first time the irule is called array set ::sessiontrackingarray {} array unset ::sessiontrackingarray array set ::sessionlbarray {} array unset ::sessionlbarray } when HTTP_REQUEST { set debug 0 #scan http header for asp session cookies if the cookie exists set sessionid to the cookie value set sessioncookie [findstr [HTTP::cookie names] "ASPSESSION" 0 20] set sessionid [HTTP::cookie $sessioncookie] #set the time to current, set the idle time to current -121 seconds. set currtime [clock seconds] set expiredtime [expr {$currtime} - 121] set poolname nameofpool set server1lb 0 set server1ip "x.x.x.x" #ip address omitted this would be the ip address of the first pool member set server2lb 0 set server2ip "x.x.x.x" #ip address omitted this would be the ip address of the second pool member set server3lb 0 set server3ip "x.x.x.x" #ip address omitted this would be the ip address of the third pool member set server4lb 0 set server4ip "x.x.x.x" #ip address omitted this would be the ip address of the fourth pool member # Search for ASP Session Cookie if { not ([HTTP::cookie exists "$sessioncookie"])} { # If request is not "al_start.asp?", exit iRule and follow default pool and LB Method if { not ([HTTP::uri] contains "al_start.asp?") } { return } else { # if there are no values in the sessionlbarray - i.e al_start.asp? seen, exit irule and just use the lb method for the pool # if {not [array names ::sessionlbarray]} { # pool $poolname # return # } # else { # Scan array and delete old/hung sessions. Any session that has a timestamp in the sessiontracking array older than the $expiredtime variable will be deleted # from both the session tracking array and lbtracking array so that it is not considered when making the lb decision foreach sesskey [array names ::sessiontrackingarray] { set sessiontime $::sessiontrackingarray($sesskey) if { $debug }{ log local0.info "for session $sesskey sessiontime is $sessiontime and expiredtime is $expiredtime" } if { $sessiontime < $expiredtime } { if { $debug }{ log local0.info "session last touched time of $sessiontime for session $sessionid is over 121 seconds old. removing session from tracking arrays" } unset ::sessiontrackingarray($sesskey) unset ::sessionlbarray($sesskey) } } # Session on each server count if { $debug }{ log local0.info "array sessionlbarray [array size ::sessionlbarray]" } foreach lbentry [array names ::sessionlbarray] { if { $debug }{log local0.info "lbentry is $lbentry sessionarraylb is $::sessionlbarray($lbentry)"} switch $::sessionlbarray($lbentry) { # masking ip addresses at customer request "x.x.x.x" {set server1lb [expr {$server1lb} + 1]} "y.y.y.y" {set server2lb [expr {$server2lb} + 1]} "z.z.z.z" {set server3lb [expr {$server3lb} + 1]} "w.w.w.w" {set server4lb [expr {$server4lb} + 1]} } } # Set Count Array to hold session count and server IP. set counterarray($server1ip) $server1lb set counterarray($server2ip) $server2lb set counterarray($server3ip) $server3lb set counterarray($server4ip) $server4lb if { $debug }{ log local0.info "server1count is $server1lb, server2count is $server2lb, server3count is $server3lb, server4count is $server4lb" } #test the pool member status. If a pool member is down, remove it from the temporary array counterarray so that is #is not considered when making the lb decision foreach membercheck [array names counterarray] { if { $debug }{log local0.info "membercheck is $membercheck, array element value is $counterarray($membercheck)"} if { not ([LB::status pool $poolname member $membercheck 80] eq "up") }{ if { $debug }{log local0.info "pool status is [LB::status pool $poolname member $membercheck 80]"} unset counterarray($membercheck) if { $debug }{ log local0.info "removing server $membercheck from the counterarray"} } } set lbholder 1000000000 foreach lbcounter [ array names counterarray ] { if { $lbholder > $counterarray($lbcounter) }{ set lbholder $counterarray($lbcounter) set ipholder $lbcounter } } # set the variable winner to the lowest value of the server session counters # set winner [lindex [lsort -integer { array get counterarray }] 0] if { $debug }{ log local0.info " load balancing to $ipholder"} # persist cookie insert cookie_cco if { $debug }{log local0.info "setting pool $poolname to lb to member $ipholder"} pool $poolname member $ipholder 80 if { $debug }{ log local0.info "pool member $ipholder status is [LB::status]"} return } #} } else { pool $poolname persist uie [HTTP::cookie "$sessioncookie"] 1200 # When cookie exists and it's NOT "AL_STOP.asp", reset session timestamp if { not ([string tolower [HTTP::uri]] contains "al_stop.asp")} { set ::sessiontrackingarray($sessionid) $currtime if { $debug }{ log local0.info "new timestamp for session $sessionid is $::sessiontrackingarray($sessionid)" } } else { if { $debug }{ log local0.info "al_stop seen. removing $sessionid entries from both arrays" } unset ::sessiontrackingarray($sessionid) unset ::sessionlbarray($sessionid) } } } #response irule when HTTP_RESPONSE { set debug 0 set currtime [clock seconds] set sessioncookie [findstr [HTTP::cookie names] "ASPSESSION" 0 20] set sessionid [HTTP::cookie $sessioncookie] if { $debug } { log local0.info "sessionid is $sessionid"} if { $debug }{ log local0.info "asp session cookie name is $sessioncookie " } # test to see if the IIS server is setting a cookie if { not [HTTP::header exists "Set-Cookie"] } { if { $debug }{log local0.info "no set cookie in http response, exiting"} return } else { if { [HTTP::cookie exists "$sessioncookie"] } { persist add uie [HTTP::cookie "$sessioncookie"] 1200 } # add sessionid and time to the session time tracking array set ::sessiontrackingarray($sessionid) $currtime if { $debug }{log local0.info "adding sessionid [HTTP::cookie "$sessioncookie"] to sessiontracking array with clock value $currtime"} # add sessionid and lb server to the array tracking sessions to server set ::sessionlbarray($sessionid) [LB::server addr] if { $debug }{log local0.info "adding session [HTTP::cookie "$sessioncookie"] to array sessionlbarray with server value [LB::server addr]"} } }
Published Mar 18, 2015
Version 1.0spark_86682
Historic F5 Account
Joined August 11, 2006
spark_86682
Historic F5 Account
Joined August 11, 2006
No CommentsBe the first to comment