Forum Discussion
Limit HTTP Requests per second on virtual server
Hello -
I need to implement an iRule that dynamicly monitors HTTP Requests per second on a virtual server - and in the event that we reach the pre-defined limit - serve a custom HTTP response (that includes an iFile). I have tried using some of the previously posted "throttling" rules - but none of them seem to be working for my situation.
Currently - I am trying to get the rule below working - but when i check the syntax in the iRules editor, I keep getting: "Response is not well-formed XML". Can anyone offer some assistance with this?
Thanks!
-David
when RULE_INIT {
set static::win_size 1000
set static::qps_hwm 10
set static::no_bid_file "/Common/RTB_no_bid_response"
set static::window_count 10
set static::debug 1
array set ::time_windows {}
set ::req_counter 0
set ::sample_rate 100
set ::last_time [clock microseconds]
}
when HTTP_REQUEST {
set ::req_counter [incr ::req_counter]
if { ::req_counter == $static::win_size } {
set timestamp [clock microseconds]
set differnce [expr {$timestamp - $::last_time}]
set current_qps [expr {$difference / $static::win_size}]
if {[info exists ::time_windows($static::window_count)]} {
for {set i 0} {$i < $static::window_count} {incr i} {
set tmp [lindex [array get ::time_windows [expr {$i + 1}]] 1]
set ::time_windows($i) $tmp
}
set ::time_windows($static::window_count) $current_qps
} else {
set ::time_windows([array size ::time_windows]) $current_qps
}
set total 0
foreach index [array names ::time_windows] {
set total [expr {$total + ::time_windows($index)}]
}
set avg_qps [expr {double($total) / [array size ::time_windows]}]
if { $avg_qps < $static::qps_hwm } {
set ::sample_rate 100
} else {
set ::sample_rate [expr {100 * [expr {double($static::qps_hwm) / double($avg_qps)}]}]
}
set ::req_counter 0
set ::last_time $timestamp
if { $static::debug == 1 } {
log -noname local0. "Current avg qps: ${avg_qps}"
log -noname local0. "Current sample rate: ${::sample_rate}"
}
}
set random_number [expr {rand() * 100}]
if { $random_number >= $::sample_rate } {
HTTP::respond 200 content [ifile get $static::no_bid_file] Cache-Control "no-cache,no-store,must-revalidate" Pragma "no-cache" Expires "Fri, 01 Jan 1990 00:00:00 GMT"
return
}
}
3 Replies
- nitass
Employee
[clock microseconds]i understand microseconds is not supported.
Is microsecond precision available in an iRule?
https://devcentral.f5.com/community/group/aft/1178832/asg/50
if { ::req_counter == $static::win_size } {is $ missing (i.e. $::req_counter)?
set total [expr {$total + ::time_windows($index)}]is $ missing (i.e. $::time_windows($index))? - David_Murphy_20
Nimbostratus
Thank you for this information. It turns out we needed to make these changes, along with a few other tweaks. The code that finally worked is below.
Thanks -
David - David_Murphy_20
Nimbostratus
when RULE_INIT { set static::win_size 1000 set static::qps_hwm 10 set static::no_bid_file "/Common/RTB_no_bid_response" set static::window_count 10 set static::debug 1 array set ::time_windows {} set ::req_counter 0 set ::sample_rate 100 set ::last_time [clock clicks -milliseconds] } when HTTP_REQUEST { set ::req_counter [incr ::req_counter] if { $::req_counter == $static::win_size } { set timestamp [clock clicks -milliseconds] set difference [expr {$timestamp - $::last_time}] set current_qps [expr {double($static::win_size) / double($difference)}] if {[info exists ::time_windows($static::window_count)]} { for {set i 0} {$i < $static::window_count} {incr i} { set tmp [lindex [array get ::time_windows [expr {$i + 1}]] 1] set ::time_windows($i) $tmp } set ::time_windows($static::window_count) $current_qps } else { set ::time_windows([array size ::time_windows]) $current_qps } set total 0 foreach index [array names ::time_windows] { set total [expr {$total + $::time_windows($index)}] } set avg_qps [expr {double($total) / [array size ::time_windows]}] set avg_qps [expr {$avg_qps * 1000}] if { $avg_qps < $static::qps_hwm } { set ::sample_rate 100 } else { set ::sample_rate [expr {100 * [expr {double($static::qps_hwm) / double($avg_qps)}]}] } set ::req_counter 0 set ::last_time $timestamp if { $static::debug == 1 } { log -noname local0. "Current avg qps: ${avg_qps}" log -noname local0. "Current sample rate: ${::sample_rate}" } } set random_number [expr {rand() * 100}] if { $random_number >= $::sample_rate } { HTTP::respond 200 content [ifile get $static::no_bid_file] Cache-Control "no-cache,no-store,must-revalidate" Pragma "no-cache" Expires "Fri, 01 Jan 1990 00:00:00 GMT" return } }
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