Forum Discussion
Re-balance requests from a single client
Hello,
We have an internal device hitting our public site with a large number of requests per second, and due to persistent connections (and the rate at which the requests are coming in from the device), it's rendering the server it hits basically useless to customer traffic. Because it's a licensed device, our hands are tied as to altering the configuration on that end, so we'd like to use the load balancer to balance the requests from the device.
I've compiled an iRule that I think should work, but I'm pretty new to writing them, so I'd love anyone's input as to the following questions:
Will it work as written? Is it logical? Is there a more efficient or effective iRule to perform this function?
Thanks in advance for your help and advice!
9 Replies
Hi!
Welcome to the world of iRules!
A few tips:
- The LB::reselect can't be used in the HTTP_REQUEST.
- Also, tables has an inbuilt expiration you can use.
/Patrik
Try this one:
when RULE_INIT { set static::lifetime 60 set static::requestlimit 10 } when LB_SELECTED { if { [HTTP::header "User-Agent"] contains "Mozilla" } { Add a table entry with a lifetime in seconds of the value of $lifetime. table add [IP::client_addr] 1 indefinite $static::lifetime if { [table incr [IP::client_addr]] > $static::requestlimit } { If the user has surpassed the request limit the pool member is reselected log local0. "This server was selected: [LB::server]" LB::reselect log local0. "Selected [LB::server]" } } }/Patrik
- AllrecipesDCO_1
Nimbostratus
Hi Patrik,
Thanks for your reply! I'll edit the static::lifetime portion down to 2 and test this out.
- AllrecipesDCO_1
Nimbostratus
Hi Patrik,
I looked over your suggestion again and I have a concern/question about using the LB_SELECTED tag. Will this rule only come into affect when a connection from the specified user-agent is initially opened?
Specifically, the issue we're seeing is that there is only one connection from the device, so to my thinking, the LB is only selected once, but a very large number of requests.
Does LB::reselect only work within LB_SELECTED, and if so, is there a similar function that would work under HTTP_REQUEST?
Thanks again! Jody
Hi Jody!
I see what you mean, and you have a point, and I did not know the answer. So I did an experiment. Set the maximum connections in firefox to 1 and then added the following rule on my VIP:
when CLIENT_ACCEPTED { log local0. "New connection. Client port [TCP::client_port]" } when LB_SELECTED { log local0. "LB Selected. Client port [TCP::client_port]" }This is the log
Mar 14 09:09:16 LB1 info tmm2[12112]: Rule /Partition/iruletest : New connection. Client port 18482 Mar 14 09:09:17 LB1 info tmm2[12112]: Rule /Partition/iruletest : LB Selected. Client port 18482 Mar 14 09:09:17 LB1 info tmm2[12112]: Rule /Partition/iruletest : LB Selected. Client port 18482Looks like it's triggered everytime.
IF it does not work, we could try to reselect the member via the pool command in the HTTP_REQUEST event, but it will be messier. 🙂
/Patrik
Hi again!
Have you managed to solve your issue yet?
I did some further tests today for another thing and it turns out that what I saw must have been a fluke.
The LB_SELECTED event is only activated once (per pool selection), and this causes a problem for you since the LB::reselect command only seems to be valid in the LB_SELECTED event.
I have an idea for a solution using tables but I'd rather know if you've solved it before tampering with it later tonight.
/Patrik
I think I figured it out. I wrote and iRule and tried it on a virtual server having a default pool with two members. The load balancing method was predictive.
The result seems to be what you want. There was no interruptions to the requests and the server was changed as planned.
when RULE_INIT { set static::lifetime 60 set static::requestlimit 5 set static::debug 1 } when CLIENT_ACCEPTED { log local0. "New connection" } when HTTP_REQUEST { if { [HTTP::header "User-Agent"] contains "Mozilla" } { Add a table entry with a lifetime in seconds of the value of $lifetime. table add [IP::client_addr] 1 indefinite $static::lifetime Check if the limit has been reached if { [table incr [IP::client_addr]] > $static::requestlimit } { Delete the table entry to restart the timeout table delete [IP::client_addr] if { $static::debug } { log local0. "Before select [LB::server addr]" } Disconnect the server session LB::detach Force a new load balancing decision based on the current load eval [LB::select] if { $static::debug } { log local0. "After select [LB::server addr]" } } else { if { $static::debug } { log local0. "Connections still ok" } } } }Added some debug options for testing it, but you can remove them (and the whole CLIENT_ACCEPTED event.
To test it I wrote a powershell script that sends a request every 3 seconds and echoes the result. Since it's only using one session (can be verified by the fact that CLIENT_ACCEPTED logging only is triggered once) it could be used to simulate the calls made by your service.
Create a web client object $wc = New-Object System.Net.WebClient while(0 -lt 1){ Add headers $wc.Headers.Add("User-Agent", "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0;)") "Sending a request" $result = $wc.DownloadString("https://www.mysite.com") Echo request result $result Wait for 3 seconds before sending the next one sleep 3 }Hope it works for you!
/Patrik
- Kevin_Stewart
Employee
do you know/can you explain why LB::reselect can't be used within HTTP_REQUEST, but LB::detach and LB::select can be?
For lack of a better answer, this has to do with event timing. The HTTP_REQUEST event triggers when the VIP consumes the request headers, but has not yet made a load balancing decision. You can preemptively cause a load balancing selection with LB::select (and perhaps detach that with LB::detach), but you can't reselect something that hasn't been selected yet.
Hi!
Just out of curiousity, did it work as expected?
/Patrik
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* 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