Jason_Hook_4092
Feb 15, 2012Nimbostratus
1 VS, 2 pool routing requirements...help?
I have the following iRule. It's working as needed. It might be clumbsy, but it works. (thoughts on a cleaner implementation?).
It chooses a pool based on a cookie, or a response from the server in the pool it it hit the wrong pool.
What I need...is to add more pool-selection logic to it to choose a pool (after determining which client it is) based on URI in order to separate some apps from the rest due to performance/capacity concerns.
Thoughts on how I can accoplish this in the most effective/maintainable way?
I hope copy/paste looks ok, not sure how to paste 'code' and make it look pretty here:
set iRule priority higher than the default to better it's functionality
priority 300
when HTTP_REQUEST {
Look for existing pool cookie otherwise determine where to go based on
a lookup of client IP in the Client 'proxy' Server addresses datalist
set to 1 to enable LTM logging, 0 to disable LTM logging
set debugWPPBF 0
init flag whether to run iRule or just exit
set ShouldExitWPPBF 0
if {[string tolower [HTTP::path]] starts_with "/streamer"} {
stop running the iRule since PERSIST profile will pick up /streamer calls
set ShouldExitWPPBF 1
return
}
if {$debugWPPBF}{log local0.info "Cookie TFPoolId Exists: [HTTP::cookie exists "TFPoolId"]"}
if {[HTTP::cookie exists "TFPoolId"] && ![info exists retriesWPPBF]} {
Pool cookie exists...just send the request
switch [HTTP::cookie "TFPoolId"] {
"1" { set PoolIdWPPBF "BLTCP_WEB" }
"2" { set PoolIdWPPBF "WSI_WEB" }
default { set PoolIdWPPBF "BLTCP_WEB" }
}
pool $PoolIdWPPBF
if {$debugWPPBF}{log local0.info "Cookie Pooling [IP::client_addr] to $PoolIdWPPBF"}
} else {
no pool cookie so we need to determine where to go
if { [info exists retriesWPPBF] } {
We are in retry so just send it to the new pool
if {$debugWPPBF}{log local0.info "isRetry to $NewPoolIdWPPBF"}
Update content length header with updated payload length
HTTP::header replace Content-Length [string length [HTTP::payload]]
pool $NewPoolIdWPPBF
} else {
we have no pool cookie and are in the 1st request...get setup to determine if we need to retry to a new pool
if {$debugWPPBF}{log local0.info "No Cookie"}
set noCookie 1
Set request, HTTP post header.
set requestWPPBF [HTTP::request]
if {$debugWPPBF}{log local0.info "HTTP::request: $requestWPPBF"}
Set payload content legth to capture.
if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 4000000}{
set content_lengthWPPBF [HTTP::header "Content-Length"]
} else {
set content_lengthWPPBF 4000000
}
Capture HTTP payload from request, HTTP::collect triggers event HTTP_REQUEST_DATA
if { [info exists content_lengthWPPBF] && $content_lengthWPPBF > 0} {
if {$debugWPPBF}{log local0.info "Collecting Payload"}
HTTP::collect $content_lengthWPPBF
}
set PoolIdWPPBF ""
set isMatchWPPBF [class match [IP::client_addr] equals WFAPriceServerList]
if {$debugWPPBF}{log local0.info "Returned '$isMatchWPPBF' from WFA price server lookup"}
if {$isMatchWPPBF} {
pool WSI_WEB
if {$debugWPPBF}{log local0.info "Pooling to WSI_WEB"}
} else {
pool BLTCP_WEB
if {$debugWPPBF}{log local0.info "Pooling to BLTCP_WEB"}
}
}
}
}
when HTTP_REQUEST_DATA {
Set payload, depends on HTTP::collect done in HTTP_REQUEST event.
set payloadWPPBF [HTTP::payload]
Append HTTP payload to HTTP request header to form a complete HTTP post request (request + payload)
append requestWPPBF [HTTP::payload [HTTP::payload length]]
Log payload
if {$debugWPPBF} { log local0.info "Payload: $payloadWPPBF - length: [HTTP::payload length]" }
}
when HTTP_RESPONSE {
Watch for a response status of 307 from a misdirected pool
and change the cookie value accordingly
otherwise set the cookie to the selected pool
if {$ShouldExitWPPBF} { return }
if {$debugWPPBF}{log local0.info "status: '[HTTP::status]' - header: '[HTTP::header "WMErrorID"]'"}
if {[HTTP::status] eq "307" && [HTTP::header "WMErrorID"] eq "307" } {
HTTP::cookie remove "TFPoolId"
if {[HTTP::header value "FirmRoute"] eq 901} {
set NewCookieValueWPPBF "2"
HTTP::cookie insert name "TFPoolId" value $NewCookieValueWPPBF path "/"
set NewPoolIdWPPBF "WSI_WEB"
if {$debugWPPBF}{log local0.info "Wrong Pool, Changing to WSI_WEB"}
} else {
set NewCookieValueWPPBF "1"
HTTP::cookie insert name "TFPoolId" value $NewCookieValueWPPBF path "/"
set NewPoolIdWPPBF "BLTCP_WEB"
if {$debugWPPBF}{log local0.info "Wrong Pool, Changing to BLTCP_WEB"}
}
if { ![info exists retriesWPPBF] } {
Set retries to activate the retry logic
set retriesWPPBF 1
Retry HTTP request/payload to another pool.
if {[info exists requestWPPBF] && $requestWPPBF ne ""} {
if {$debugWPPBF}{log local0.info "Retrying: $requestWPPBF"}
HTTP::retry "$requestWPPBF"
return
} else {
if {$debugWPPBF}{log local0.info "No collected request - responding to client"}
HTTP::cookie remove "TFPoolId"
}
}
} else {
if {$debugWPPBF}{log local0.info "PoolIdWPPBF: $PoolIdWPPBF"}
if {[info exists noCookie] || [info exists retriesWPPBF]} {
switch [LB::server pool] {
"BLTCP_WEB" { HTTP::cookie insert name "TFPoolId" value "1" path "/" }
"WSI_WEB" { HTTP::cookie insert name "TFPoolId" value "2" path "/" }
default { HTTP::cookie insert name "TFPoolId" value "1" path "/" }
}
Update content length header with updated payload length
REMOVED HTTP::header replace Content-Length [string length [HTTP::payload]]
if {$debugWPPBF}{log local0.info "No 307, Setting Cookie for [LB::server pool] - Client: [IP::client_addr]"}
if {[info exists noCookie]}{ unset noCookie }
}
if {[info exists retriesWPPBF]}{
if {$debugWPPBF}{log local0.info "unsetting retriesWPPBF"}
unset retriesWPPBF
}
}
Insert header with responding server IP
HTTP::header replace "serverIP" [IP::server_addr]
}
when LB_SELECTED {
if {$ShouldExitWPPBF} { return }
if { [info exists retriesWPPBF] } {
if {$debugWPPBF}{log local0.info "Redirecting Request to $NewPoolIdWPPBF - member: [LB::server]"}
LB::reselect pool $NewPoolIdWPPBF
}
}