Forum Discussion
Dan_Hughes_1946
Nimbostratus
Jan 06, 2010loadbalanced redirection
Howdy,
Wondering if anyone can suggest a solution to a little problem I have. I want traffic coming into an LTM to be redirected to one of two URLs - based on a round robin loadbanace. So :
client sends request to www.domain.com
LTM returns HTTP redirect to either firsthost.domain.com or secondhost.domain.com based on a round robin loadbalance..
I can see lots of ways of returning a single redirect in a given set of circumstances, and I see of course simple ways to proxy/forward to a pool of servers. But I can't see an obvious method of load balancing to multiple redirects.
Any help appreciated!
Dan
14 Replies
- Colin_Walker_12Historic F5 AccountIf you just want even distribution of load to two redirects then you'd just need to do something like:
when CLIENT_ACCEPTED { set count 0 } when HTTP_REQUEST { switch $count { 0 { HTTP::redirect "firsthost.domain.com" set count 1 } 1 { HTTP::redirect "secondhost.domain.com" set count 0 } } }
Colin - The_Bhattman
Nimbostratus
Hi Dan,
I suppose you can try the following untested example:when HTTP_REQUEST { set turnbit [expr [STATS::get "roundrobin" turnbit] %2] switch $turnbit { 0 { log local0. "$turnbit" HTTP::redirect "http://firsthost.domain.com" STATS::incr "roundrobin" turnbit } 1 { log local0. "$turnbit" HTTP::redirect "http://secondhost.domain.com" STATS::incr "roundrobin" turnbit } } }
You have to assign a STATS profile to the VIP. In this example I called the STATS profile "roundrobin" with a field called turnbit.
What this does is that it stores a number and then it is incremented one after it's been evaluated by the expression using N mod 2.
Basically one person is directed to the first domain and another after him will be directed to second , 3rd will go back to the first domain and rotate in a round robin fashion. Of course this has been tested at all but I think it might come very close to what you could be looking for.
I hope this helps
Bhattman - hoolio
Cirrostratus
I think it would actually be more evenly distributed with a global counter or a session table entry.
As there will be more TCP connections with a single HTTP request, resetting the counter on the start of every connection would result in many more requests going to the first redirect location. If you didn't want to use a global counter or session table entry, you could use an idea from Spark where you create a pool with two dummy pool members, force a load balancing decision with LB::select and then choose the redirect location based on which dummy pool member was selected.
If any one of these options sounds good, let us know and we can provide an example.
Aaron - Dan_Hughes_1946
Nimbostratus
Guys,
Two things..
1) I'm from a Cisco background, only really getting into the F5s.. I have to say I'm really impressed at the quality of the responses I've got to this post. Really - fantastic guys, I really appreciate it.
2) Wow iRules are powerful. I'm going to spend a little time trying those options (as much from a learning what they're doing perspective).
I feel like a convert who reaslises he was in the 'wrong' religion all these years ;-)
Thanks
Dan - Dan_Hughes_1946
Nimbostratus
Hi Hoolio,
Thanks for the response. I think in this particular situation we shouldn't get too much of a problem, as the connection coming into the LTM is an initial connect from a URL in the application. Once it gets redirected, the real action happens, so a user (probably) only sends one connection to the load balancer.
Thanks
Dan - Dan_Hughes_1946
Nimbostratus
OK one more question on this. Lets say I wanted to have a health monitor on the rewrite destinations. Is it possible to make the use of each redirect URL dependent on the state of a monitored node?
Thanks again... - hoolio
Cirrostratus
I think in this particular situation we shouldn't get too much of a problem, as the connection coming into the LTM is an initial connect from a URL in the application. Once it gets redirected, the real action happens, so a user (probably) only sends one connection to the load balancer.
If the clients are generally going to establish a TCP connection, send a single HTTP request and the close the connection, you wouldn't want to reset the redirect number on every new TCP connection. Doing so would mean that most clients would get redirected only to the first URL. If you use a global counter of some sort (global variable, stats profile field or session table entry) then there should be even distribution of redirects to the first and second URLs.
Here is an example which uses a global variable declared in RULE_INIT to track the redirects.Example of round robin redirection when RULE_INIT { Initialize the redirect counter to 0 set ::redirect_counter 0 } when HTTP_REQUEST { Check the counter value switch $::redirect_counter { 0 { Value was 0, redirect to first URL with cache control headers set to prevent caching of response HTTP::respond 302 Location "http://firsthost.domain.com" Cache-Control No-Cache Pragma No-Cache set ::redirect_counter 1 } 1 { Value was 1, redirect to second URL with cache control headers set to prevent caching of response HTTP::respond 302 Location "http://secondhost.domain.com" Cache-Control No-Cache Pragma No-Cache set ::redirect_counter 0 } } }
Or if you configure the IP address(es) of the two domains in a pool with round robin load balancing, you could configure an HTTP(S) monitor to check the response of each server and use an iRule like this to send the redirects. You wouldwhen HTTP_REQUEST { For a load balancing selection from the VIPs default pool This assumes you've set the pool's load balancing algorithm to round robin switch [LB::select] { "1.1.1.1" { Send client a 302 redirect with the hostname which corresponds to the 1.1.1.1 server IP HTTP::respond 302 Location "http://firsthost.domain.com" Cache-Control No-Cache Pragma No-Cache } "2.2.2.2" { Send client a 302 redirect with the hostname which corresponds to the 2.2.2.2 server IP HTTP::respond 302 Location "http://secondhost.domain.com" Cache-Control No-Cache Pragma No-Cache } default { Take some default action if both servers are marked down? } } }
Aaron - Dan_Hughes_1946
Nimbostratus
Hi Aaron,
Thanks for that. Can I just check my understanding of the logic of option 2 here (I want to be sure I have my hear around this ;-) ..
What we're doing is setting up a pool with two members, 1.1.1.1 and 2.2.2.2. This ensures that they we can set a health monitor to each, and this is the pool assigned to the virtual server resources.
Then, when the connections come in, we are sending to the pool, but changing rewriting the response to a 302 with the appropriate location.
However if a pool member is down, then of course traffic won't be load balanced to it, so we'll only perform the response re-write on the pool member that we are sending traffic to...
Excusing terminology - am I about right there?
Thanks for all your help..
Dan - Dan_Hughes_1946
Nimbostratus
Great. Thanks all of you! Glad to be following the logic too!
Rgds
Dan - htran
Nimbostratus
Sorry to jump in the middle. Can I have a quick question:
We have a similar situation. The application was written poorly that the Web servers need to be able to interact directly with the workstations. I want to take the LTM out of the picture but still want to leveraging the Load Balance and health check functionality. I am thinking of configure VIP and pool. When request come in to the VIP, we will use the same IRule here to re-write the URL to direct the workstation to one of the member server. From then on, the workstation establishes connection with the server for the application. Can I use this IRule for my purpose?
Thank you in advanced.
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