Forum Discussion
Gregory_Gerard_
Nimbostratus
Jun 18, 2005How do I detect if a pool is down in an iRule?
Use Case:
pool is down
Current behavior:
I have an http profile setup that sends back an impersonal redirect to the client.
Desired behavior:
I'd like to have the URI passed to the host that got the redirection.
Why?
I have an SSL VS https://blah.example.com
An iRule looks at the first portion of the URI and decides which pool to send to in a big switch statement:
iRule fragment:
elseif {[HTTP::uri] starts_with "/customer1" } {
pool pool-customer1
}
https://blah.example.com/customer1/rest/of/uri?and=stuff
gets routed to a different pool than
https://blah.example.com/customer2/rest/of/uri?and=stuff
If the pool is down, I'd like to be able to redirect to a system down page and send the original URI so I can log it in our application and periodically retry their original request with a JavaScript timer.
Right now, the redirect is fixed because the profile is shared amongst all customers. Must I create a profile per customer to get this behavior or can I gauge the health of a pool and do a better redirect myself?
8 Replies
- unRuleY_95363Historic F5 AccountThe way to do this is to write a handler for the LB_FAILED event.
You can then query the pool and take action according to which pool was selected.
Eg:when LB_FAILED { switch [LB::server pool] { pool-customer1 { HTTP::redirect http:://foo/customer1 } pool-customer2 { HTTP::redirect http:://bar/notavail } default { HTTP::redirect http:://sitedown/ } } }
You can also use "HTTP::respond" instead of "HTTP::redirect" and then you can completely customize the response. - Al_Carandang_11
Nimbostratus
I am trying the follwowing rulerule sorry_test { when LB_FAILED { log local0.err "ERR: Load Balancing failed for [virtual name] Pool: [LB::server] Client: [IP::remote_addr] HTTP::redirect "http://sorry.domain.com/sorry.html" } }
Now when I make a request to the virtual immediately after shutting down the webserver I get an empty reply from the server and I get the following entry in /var/log/ltm:Mar 5 16:47:02 tmm tmm[1028]: Rule sorry_test : ERR: Load Balancing failed for testvip Pool: test_pool Client: 10.1.1.1 Mar 5 16:47:02 tmm tmm[1028]: 011f0007:3: http_process_state_header_xfer - Invalid action EV_SINK_HEADER during ST_HTTP_XFER_HEADERS
So it appears to have triggered the LB_FAILED event but the HTTP:redirect did not get executed.
Then a few seconds later when the monitor marks the pool member down, I get the correct redirect the response to my HTTP request and I get the following in /var/log/ltmMar 5 16:47:03 testbip mcpd[1119]: 01070638:3: Pool member 10.2.2.2:80 monitor status down. Mar 5 16:47:04 tmm tmm[1028]: Rule sorry_test : ERR: Load Balancing failed for testvip Pool: test_pool Client: 10.1.1.1 Mar 5 16:47:04 tmm tmm[1028]: 011f0007:3: http_process_state_header_xfer - Invalid action EV_SINK_HEADER during ST_HTTP_XFER_HEADERS
In this case, the LB_FAILED event was triggered and the HTTP::redirect was executed.
So my questions are:
1. Why does the HTTP::redirect not get executed in the first instance?
2. What does the EV_SINK_HEADER error message mean?
-Al- Walter_Kacynski
Cirrostratus
I think you want to use LB::down and then perform the redirect. I haven't tested this.
- Colin_Walker_12Historic F5 AccountNot that you don't have valid questions, because they're good ones, but wouldn't it be easier to just check to see if the pool is down prior to sending the request to it? If all you're looking to do is redirect when no members in the pool are available, something like this would work:
when HTTP_REQUEST { if { [active_members your_pool] < 1 } { HTTP::redirect "http://somedomain.com/somepage.html" } else { pool your_pool } }
I know it doesn't answer your questions (which I'd love to do, when I get a minute to look into them), but I would think it would give you the desired behavior, no?
Colin - Al_Carandang_11
Nimbostratus
Thanks for the suggestion.
Actually I do have that in my production iRule. I just was looking for a way to handle the period where a server crashes or is otherwise unresponsive between the time a request is dispatched to it and before the health check marks a server as down.
There are still other active pool members in this scenario so if it would be possible to have the request redirected to another server, that would be even better. I already tried something like..when HTTP_REQUEST { set request [HTTP::request] } when LB_FAILED { HTTP::retry $request }
But I haven't gotten it to work yet.
-Al - Wes_98712
Nimbostratus
Have you looked at inspecting the return response from the server?
Something as follows may help out:when HTTP_RESPONSE { if { [HTTP::status] ends_with "404" } { LB::reselect pool }
Course you could also setup a datagroup with the HTTP codes that you want to base your reselect decision on, what I mean is, anything other than 200 or a select few, you could also do something similar to:when HTTP_RESPONSE { if { [HTTP::status] > "300" } { LB::reselect pool }
I haven't tested any of this stuff, but with a little trial and error I don't see why it wouldn't work. Best of all you are inspecting the response code from the server and not relying on the interval ECV to mark the node unavailable if it fails (which you should still do, but this comes into place in between those health checks and wait times before the LB marks the node down).
Let me know how it goes.
-wn
} - Wes_98712
Nimbostratus
This issue is you want to determine if the server is down before the LTM does, that is a bit tricky. I'm wondering if you combined the LB failed logic with the pool reselect, instead of redirect, I think the redirect has to be executed based on a positive return value for whatever condition you are checking for, then again they both might and we'll be back in square one. - Wes_98712
Nimbostratus
Also kind of wondering if those errors you mentioned before are related to the fact that the HTTP profile inspects the HTTP packet header information, since there isn't one it flips out. Not sure if that makes sense or not.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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
