Forum Discussion

Serge_M__252_ll's avatar
Serge_M__252_ll
Icon for Nimbostratus rankNimbostratus
Jan 18, 2016

Http::retry after timeout (again)

Hi,

this is a reiteration of this question

in short the Problem is: i need to retry a Server connection if it takes longer than x to process (eg Server connection died mid request, congestions, to much cats...). The idea so far was to use "after" in the http request, and the do a http::retry or a lb::reselect. But neither works HTTP::retry only works in HTTP_RESPONSE which i never reach, since my request are processed to slowly(or cats) and LB::reselect does not retry the request. I tried inband monitors, but they dont seem to work the way i expected

any suggestions?

best regards Serge

P.S. The Solution so far

rule myrule {
   when RULE_INIT {
   set static::response_timeout  5
}

when HTTP_REQUEST {
   log local0. "Received request, beginning response monitor interval. [clock seconds]"
   set monitor_id [\
      after $static::response_timeout {
         does not work in this context
         HTTP::retry [HTTP::request]
         log local0. "Timeout $static::response_timeout milliseconds elapsed without server response. [clock seconds]"
      }\
   ]
}

when HTTP_RESPONSE {
   this is never reached
   log local0. "Received server response."
   if {[info exists monitor_id]} {
      log local0. "Canceling after script with id $monitor_id"
      after cancel $monitor_id
   }
}
}

2 Replies

  • iRules are event driven. As such you will need to key this off an event that is being hit. You might try modifying the code used to detect and prevent Slowloris attacks, detailed here: https://support.f5.com/kb/en-us/solutions/public/10000/200/sol10260.html

     

    We use a timer to reset the connection one second after initialization:

     

    when CLIENT_ACCEPTED { set rtimer 0 after 1000 { if { not $rtimer} { drop } } }

     

    when HTTP_REQUEST { set rtimer 1 }

     

  • Hi Serge,

    I do strongly believe, that you have to request your backend systems entirely through SIDEBAND connections, so that you're able to transperently reselect/retry an successfully established - but then somehow stalled server side connection.

    The idea behind this approach is, that SIDEBAND connections do provide independend timeouts for the connection establishment (comparable to the LB_FAILED detection) and the received payload (the added functionality you're looking for).

    Note1: Using SIDEBANDs to retrieve the content would unfortenately have a strong impact on your performance... 😞

    Note2: You may also investigate if your application / web server already supports a configurable maximum response timeout, so that it would send a "503 - Server Busy" response to your your F5 after the given timeout is reached. The 503 response could then be catched during the HTTP_RESPONSE followed by a

    [LB::down]
    and
    [HTTP::retry]
    .

    Cheers, Kai