Forum Discussion
iRule that will limit connections
1) limit the web servers to 50 connections each.
2) any connection after 50 will be redirected to another site.
3) Clients are using cookies for persistence.
4) Once a client gets a cookie we need to keep persistence.
rule session_limit {
my qustion is - i
1)Is the max_active_clients- of 50, is that for the pool or each member?
2) How do we guarantee that we always send users to a server that has the capacity? We notice - that when we have a few connections available on a server. We will still get redirected – for example - one servers will have 40 connections- the other about 10. So we will get redirted - in this case to yahoo. Is there a way to set the limit on the per node basis? It looks like we are setting the limit on the per vip basis.
Below is what we have:
rule session_limit {
when RULE_INIT {
array set ::active_sessions { }
set ::total_active_clients 0
set ::max_active_clients 50
}
when HTTP_REQUEST {
if { [HTTP::cookie exist "BIGipServerhalifax"] } {
pool halifax
incr ::total_active_clients
log "Total Clients $::total_active_clients"
log "Active Sessions $::active_sessions { } "
} else { if { $::total_active_clients < $::max_active_clients } {
if { [HTTP::uri] contains "linkID=halifax" } {
pool halifax
incr ::total_active_clients
} else { HTTP::redirect "http://pleasehold.evenue.net/bigip/nocookies.html" }
} else { HTTP::redirect "http://www.yahoo.com/"
return
}
}
}
when CLIENT_CLOSED {
incr ::total_active_clients -1
}
}
5 Replies
- Deb_Allen_18Historic F5 AccountHey Bob --
The rule you've created will actually enforce a connection limit at the rule/virtual server level, not for each pool member. You could set connection limits on each node as required, and use "observed" or "least connections" lb method to ensure that all servers are utilized up to the max of the VS limit without the skewing you're seeing.
And unless I'm reading your code wrong, it looks like you may want to reverse the comparison of total to max? Looks like you're redirecting only if total < max?
And finally, in case the rule might be applied to more than 1 VS, you should be aware that since the rule uses global array values for the counter, that array value would be shared across multiple instances of the same rule.
HTH
/deb - bob_rao_7722Historic F5 AccountIs the connections based on active connections or total connections?
When we look at the node - we see 0 active connections, and we see 200 plus "tot" connections. It is enforcing the connection limit on "tot".
We set a limit on the node level for 25 connections each, and we have a 50 connection limit on the VS level with the iRule.
Once we hit the max on the "tot" connections, we can not initiate new connection to the VIP, we are redirected to yahoo.
So what we are trying to do- is set a limit to 50 active sessions - 25 active sessions on each server.
What should I edit to accomplish this?
thanks
Bob - Deb_Allen_18Historic F5 AccountMake sure I have the logic straight first:
if cookie exists load balance to default pool w/persistence (session already exists, so don't increment counter) if no cookie exists if uristring exists redirect to "nocookies" page if connection limit not yet reached load balance to default pool increment counter else if connection limit already reached redirect to "server busy" page
By re-ordering your original conditions a bit, eliminating one unused array, and incrementing a bit differently, we get:rule session_limit { when RULE_INIT { set ::total_active_clients 0 set ::max_active_clients 50 } when HTTP_REQUEST { ; If persistence cookie already exists, ; allow persistent connection without incrementing counter if { [HTTP::cookie exists "BIGipServerhalifax"] } { pool halifax return ; If no cookie, check for URI link parameter ; & redirect if present } else { if { [HTTP::uri] contains "linkID=halifax" } { HTTP::redirect "http://pleasehold.evenue.net/bigip/nocookies.html" return } ; Still no cookie ; Check limit vs. active ; Allow in if there's room, and incr counter for this new cnx if { $::total_active_clients < $::max_active_clients } { incr ::total_active_clients pool halifax return ; otherwise redirect } else { HTTP::redirect "http://www.yahoo.com/" return } } } when CLIENT_CLOSED { incr ::total_active_clients -1 } }
This will enforce a connection limit of 50 total concurrent users on the VS. If you use "least connections" load balancing, you will get the most even distribution of connections across the server pool. I'm not sure how nicely node connection limits will play with the rule limits, so I'm going to recommend you leave off the node limits until you have the rule logic working the way you want, and then I'll leave the question of node limits open for your experimentation.
HTH
/d - David_Horton_20
Nimbostratus
Hi
I am trying to implement a very similar setup, I was finding that the client_close was triggering for both active clients and those being redirected, so I put a HTTP::close and a TCP::close after the redirect with an increment of the current active users thus triggering the client close and decrementing it again, this seemed to solve that issue.
My current problem is that client browser triggers the client_close after a period of inactivity (it seems to happen at different times for different browsers) at this point the number of active users gets decremented allowing a new user in, but the session cookie for the first user is still present so they can still gain access also, thus bursting the caps.
Any pointers anyone could give me with this would be gratefully received. See my irule below.
Thanks
David
when RULE_INIT {
set ::total_active_clients 0
set ::max_active_clients 1
log local0. "rule session_limit initialized: total/max: $::total_active_clients/$::max_active_clients"
}
when CLIENT_ACCEPTED {
log local0. "Client accepted"
log local0. "active clients $::total_active_clients"
}
when HTTP_REQUEST {
log local0. "current active clients $::total_active_clients"
; test cookie presence
if {[HTTP::cookie exists "ClientID"]} {
log local0. "active user with cookie making http request"
set need_cookie 0
set client_id [HTTP::cookie "ClientID"]
; if cookie not present & connection limit not reached, set up client_id
} else {
if {$::total_active_clients < $::max_active_clients} {
log local0. "http request from new client access granted. cookie set."
set need_cookie 1
set client_id [format "%08d" [expr { int(100000000 * rand()) }]]
log local0. "current active clients $::total_active_clients"
log local0. "new active client"
incr ::total_active_clients
log local0. "current active clients $::total_active_clients"
; otherwise redirect
} else {
log local0. "http request from non active connection denied"
HTTP::redirect "http://www.google.com"
incr ::total_active_clients
log local0. "attempting to close connection"
catch HTTP::close
catch TCP::close
return
}
}
}
when HTTP_RESPONSE {
; insert cookie if needed
if {$need_cookie == 1} {
HTTP::cookie insert name "ClientID" value $client_id
}
}
when CLIENT_CLOSED {
; decrement current connection counter for this client_id
log local0. "current active clients $::total_active_clients"
log local0. "client closed"
log local0. [IP::remote_addr]
if {$::total_active_clients > 0} {
log local0. "decremeting active clients"
incr ::total_active_clients -1
}
log local0. "current active clients
$::total_active_clients"
} - Leslie_South_55
Nimbostratus
I am testing your rule, and sometimes I get the followingSep 11 10:09:12 tmm tmm[1055]: 01220001:3: TCL error: Rule rule_http-session-limit - Operation not supported. Multiple redirect/respond invocations not allowed (line 23) invoked from within "HTTP::redirect "http://www.google.com""
sort of confusing, as line 23 is this log statementlog local0. "current active clients $::total_active_clients"
Thoughts?
-L
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