Forum Discussion
Kenny_Lussier_5
Jun 13, 2011Nimbostratus
Tracking triggers in an iRule
Hi All,
I have the following iRule which checks a data group to see if the server is marked as online or off-line. If it is marked as online, traffic passes as normal, if it is off-line, it sends back a 503. If the proxy is online, but the back end pool is unavailable (using LB_FAILED), it sends back a 502. The pool is actually a single node, so there is no need for LB::reselect (which I don't think would work anyway). I have a tcp profile assigned to the virtual server that sets max syn retry to 1 so that LB_FAILED is immediate.
This has worked fairly well so far, except that LB_FAILED is being triggered intermittently, and I don't know why. One request will get a 502, while another request, received within milliseconds, goes through. If I were using a built-in health check, there would be logging on member up/down, and failures to select pools. But since I am doing passive checking, there isn't much info that I can find. Is there a way to see what is causing the failures from the LTMs point of view?
Thanks,
Kenny
when RULE_INIT {
log local0.info "proxystatushttp v1.0 $static::tcl_platform(os) $static::tcl_platform(osVersion)"
set static::DEBUG 0
set static::offlineFlag "offline"
set static::proxyStatus proxystatus
if { $static::DEBUG } { log local0.debug "$static::proxyStatus:\n[class get $static::proxyStatus]" }
set static::privateNetworkAddresses private_net
set static::externalMonitoringAddresses external_monitoring_addresses
if { $static::DEBUG } { log local0.debug "$static::privateNetworkAddresses:\n[class get $static::privateNetworkAddresses]" }
if { $static::DEBUG } { log local0.debug "$static::externalMonitoringAddresses:\n[class get $static::externalMonitoringAddresses]" }
}
when HTTP_REQUEST {
if { [class lookup $static::offlineFlag $static::proxyStatus] } {
if { (not [class match [IP::client_addr] equals $static::externalMonitoringAddresses]) &&
(not [class match [IP::client_addr] equals $static::privateNetworkAddresses]) } {
set response "ForbiddenNOTICE: Service unavailable at this time."
HTTP::respond 503 content $response noserver "Connection" "close" "Content-Length" [string length $response]
if { $static::DEBUG } { log local0.debug "Sent HTTP Status Code 503 due to proxy status offline to [IP::client_addr]" }
log -noname local0. "[virtual name] MyIP=[IP::local_addr] SrcIP=[IP::client_addr] - - \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] - \"[HTTP::method] [HTTP::uri] HTTP/[HTTP::version]\" 503 [HTTP::payload length]"
return
}
else {
if { $static::DEBUG } { log local0.debug "Processing HTTP request with proxy status offline from [IP::client_addr]" }
}
}
}
when LB_FAILED {
set response "Server ErrorNOTICE: Site has experienced an error."
HTTP::respond 502 content $response noserver "Connection" "close"
log -noname local0. "[virtual name] MyIP=[IP::local_addr] SrcIP=[IP::client_addr] - - \[[clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"]\] - \"[HTTP::method] [HTTP::uri] HTTP/[HTTP::version]\" 502 [HTTP::payload length]"
}
- The_BhattmanNimbostratusHI Kenny,
- hooleylistCirrostratusHi Kenny,
- Kenny_Lussier_5NimbostratusThanks for the pointers. Tracking connections is a little tough, since there are thousands of connections to the front end, and the pool/node is a load balancer. finding the one SYN that isn't ACKd is like finding a needle in a needle stack :-)
- Colin_Walker_12Historic F5 AccountI don't think you'd need a LB::reselect, if you just want to try again to the same server, you could use HTTP::retry.
- hooleylistCirrostratusWith a default TCP profile, TMM tries 5 times over 45 seconds to establish a TCP connection. If that's not enough attempts you could increase the Maximum Syn Retransmissions" option in the TCP profile.
- Kenny_Lussier_5NimbostratusProblem Solved!! The problem isn't connections being refused, it's connections being closed on the back ent. Our tomcat servers have a timeout of 60 seconds. The LTM has a 300 second TCP timeout. So, if the client connects, sends a request, gets a response, and does not properly close a connection, it stays open for 300 seconds as far as the LTM is concerned. However, the tomcat server kills the thread servicing that connection after 60 idle seconds. That makes the LTM think that the pool member has failed, triggering LB_FAILED the next time it tries to use that connection. I solved it with this:
when RULE_INIT { log local0.info "keepalivetimeout v0.1 $static::tcl_platform(os) $static::tcl_platform(osVersion)" set static::keepalivetimeoutDEBUG 0 set static::keepAliveTimeout [class lookup "keepAliveTimeout" httpdefaults] } when HTTP_REQUEST { (re)set the TCP idle timeout for the current connection to the profile default IP::idle_timeout [PROFILE::tcp idle_timeout] if { $static::keepalivetimeoutDEBUG } { log local0.debug "[IP::client_addr]:[TCP::client_port] TCP idle_timeout set to [IP::idle_timeout]" } } when HTTP_RESPONSE { (re)set the TCP idle timeout for the current connection until IP::idle_timeout $static::keepAliveTimeout if { $static::keepalivetimeoutDEBUG } { log local0.debug "[IP::client_addr]:[TCP::client_port] TCP idle_timeout set to [IP::idle_timeout]" } } :keepalivetimeout
- Colin_Walker_12Historic F5 AccountTricky, I like it. :)
- hooleylistCirrostratusNice work in figuring out what was happening.
- Kenny_Lussier_5NimbostratusHoolio,
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects