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