Forum Discussion

Laurent_P_'s avatar
Laurent_P_
Icon for Employee rankEmployee
Aug 06, 2007

Performance impact of HTTP::respond

Hi,

 

 

We have a customer requesting ability to limite the rate of HTTP request. The iRule which has been developed answers with HTTP::respond 501 when the maximum rate is reached.

 

Testing under load produce a huge performance loss.

 

Did anybody observed the same ?

 

Any alternative for this iRule command ?

 

 

Thanks a lot for any help.

 

Regards.

7 Replies

  • Hi Laurent,

     

     

    Could you post the rule? What kind of connection rates are you seeing the rule response quickly for? What number of client/connection counts is the rule tracking? At what connection level does the rule start to introduce latency? Is TMM CPU usage climbing high?

     

     

    Aaron

     

  • Here it is :

     

    when RULE_INIT {

     

    set ::maxRate 100 ;nombre de requetes HTTP max par utilisateur

     

    set ::windowSecs 10 ;fenetre de limitation de requetes

     

    init array if non-existent

     

    array set ::postHistory { }

     

    wipe array if already existent

     

    array unset ::postHistory

     

    }

     

    when HTTP_REQUEST {

     

    if { [HTTP::method] eq "GET" } {

     

    if {[HTTP::cookie exists JSESSIONID]} {

     

    Extraction du critere de niveau 7 - en l occurence le cookie JSESSIONID

     

    set myUserID [HTTP::cookie "JSESSIONID"]

     

    log local0. "premiere requete du user $myUserID"

     

    Initialisation du nombre de requetes pour l utilisateur

     

    set myMaxRate ""

     

    utilisation du max rate defini plus haut

     

    if { $myMaxRate eq "" }{

     

    set myMaxRate $::maxRate

     

    log local0. "max rate set to $::maxRate"

     

    }

     

    }

     

    else {

     

    set myUserID "no_user_id"

     

    log local0. "premiere requete du user $myUserID"

     

    Initialisation du nombre de requetes pour l utilisateur

     

    set myMaxRate ""

     

    utilisation du max rate defini plus haut

     

    if { $myMaxRate eq "" }{

     

    set myMaxRate $::maxRate

     

    log local0. "max rate set to $::maxRate"

     

    }

     

    }

     

    set currentTime [clock seconds]

     

    calcul de la fenetre de temps

     

    set windowStart [expr {$currentTime - $::windowSecs}]

     

    log local0. "cutoff time set"

     

    incremente le nombre de requete pour cet utilisateur

     

    set postCount 1

     

    foreach { requestID requestTime } [array get ::postHistory ${myUserID}*] {

     

    compte les requetes dont le start time > $windowStart, supprime le reste

     

    if { $requestTime > $windowStart } {

     

    incr postCount 1

     

    log local0. "User $myUserID - incremente - Current rate: $postCount - Max rate: $myMaxRate"

     

    } else {

     

    unset ::postHistory($requestID)

     

    log local0. "User $myUserID - decremente - Current rate: $postCount - Max rate: $myMaxRate"

     

    }

     

    }

     

    if { $postCount < $myMaxRate } {

     

    autorise les requetes et ajoute une entr?e au tableauy w/myUserID.rand + currentTime

     

    set requestID "${myUserID}.[expr { int(10000000 * rand()) }]"

     

    set ::postHistory($requestID) $currentTime

     

    } else {

     

    Rejete la requete en envoyant un 501 server error

     

    log local0. "Service Unavailable - User $myUserID - Current rate: $postCount - Max rate: $myMaxRate"

     

    HTTP::respond 501

     

    return

     

    }

     

    }

     

    }
  • This is iRule intend to allow a sliding windows of 10 second wthin wich a user or a robot can issue a max of 100 request per second.

     

    This is done to prevent server resources from being blown away by 'non-human' rate of requests.
  • What version of code are you running? There is a performance issue with the clock command prior to 9.2.
  • Nina_Forsyth_67's avatar
    Nina_Forsyth_67
    Historic F5 Account
    The issue with the iRule is this line:

     

     

    set requestID "${myUserID}.[expr { int(10000000 * rand()) }]"

     

     

    I am not sure if anyone has a better way to do it but the math is pretty costly to CPU time.
  • The rand() function was used to uniquely identify each user request.

     

     

    The clock() command is used to have a kind of sliding window of time in order to determine the 'human behaviour'.

     

     

    Any alternatives to these commands ?