Forum Discussion

marsmann_58298's avatar
marsmann_58298
Icon for Nimbostratus rankNimbostratus
Oct 15, 2007

Check/Get page load response after HTTP header checks ok

Hi all,

 

 

I am brand spankin' new to the F5's. I come from a former Cisco CSS environment so this is a big change for me. I would appreciate some help on the following simple request. I want to have the F5 do:

 

 

* User requests site/app via VIP address

 

* F5 receives request, checks webserver farm/pool

 

* Establishes connection with web server

 

* Gets a 200 ok (or relevant header code)

 

* Establishes session, applies cookies/stickies

 

* Serves page to client

 

 

Here's where I need help

 

 

* After it receives a 200 ok and starts serving up the page IF the page takes more than "x" seconds or higher (slow response on page load) mark the server as "down" and reconnect to a new server in the farm/pool.

 

 

Can this be done? I've been reading into EAV and monitors and so far what I have found is that an IRule will be the best way to do this. I just need some guidance or a good starting point unless someone here already knows exactly how to do this. Thanks in advance.
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    There is no reliable way to do this currently using iRules.

     

     

    Every iRule action requires a trigger, and the lack of a response doesn't trigger anything.

     

     

    From what I understand, we will be adding a timeout trigger in an upcoming release to address this requirement.

     

     

    HTH

     

    /deb
  • thanks for the response.

     

     

    I was playing around with something like:

     

     

    when HTTP_RESPONSE {

     

    if {[HTTP::status] == 200}{

     

    HTTP::collect [HTTP::header Content-Length]

     

    }

     

    }

     

    when HTTP_RESPONSE_DATA {

     

    HTTP::respond 200 content [HTTP::payload]

     

    }

     

    ...........etc.

     

     

    Or,

     

     

    when HTTP_REQUEST { if {[HTTP::uri] starts_with "whatever" } {

     

    IP::idle_timeout 3600 }}

     

     

    I figure with the first one there would be some data collected that could be manipulated with a trigger/payload response code.

     

     

    No? I'm way off here??

     

     

     

     

     

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Well, if you want start over & resend the request to a new server after the payload is received, you could keep track of the total time since the 200 OK was seen & react accordingly. It seems like you'd just be creating more latency, though, not improving the response time, if your servers begin to respond slowly.

    You would have to collect to trigger the response data event, then you could compare the times & decide on an action.

    You can use LB::down to set the pool member status to DOWN, but it will kill all current connections (not just the one tirggering the logic) and once a monitor receives a timely response, it will be marked up again.

    There is really no guarantee you'll get a better server the next time, but you can improve your chances by using Fastest or some other metric-based LB mode.

    Something like this will do all of the above:
    
    when RULE_INIT {
      set ::tMax 30
    }
    when HTTP_REQUEST {
      set req HTTP::request
    }
    when HTTP_RESPONSE {
      if {[HTTP::status] == 200}{
        set t0 [clock seconds]
        HTTP::collect [HTTP::header Content-Length]
      }
    }
    when HTTP_RESPONSE_DATA {
      if {[clock seconds] > [expr {$t0 + $::tMax}]}{
        LB::detach
        LB::down
        LB::reselect
        HTTP::retry $req
      } else {
        HTTP::release
      }
    }
    HTH

    /deb
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    (Oops!

     

    Re-worded first sentence to actually make sense... sorry!)
  • Excellent. Thank you for your time and assistance. I think I see your point about the new potential latency with dropping and re-establishing connections. I'm not sure if that will be better or worse than the current configuration. I guess I will try it out and see.

     

     

    I'm going to take your script, plug it into a secondary testing VIP (which points back to the same pool) and test that way. Problem is I can reproduce the "hang" that I'm told users experience.

     

     

    I'll update this post with my findings.
  • hmmm... so I get this error when trying to apply/create the new iRule:

     

     

    01070151:3: Rule [sharepoint-payload-resp-chk] error:

     

    line 14: [use curly braces to avoid double substitution] [[$t0]]

     

    line 17: [command is not valid in current event context (HTTP_RESPONSE_DATA)] [LB::reselect]

     

     

    I tried several variations and can’t get line 14 to be valid.

     

     

    The other one appears to not be valid under the HTTP_RESPONSE_DATA. If LB::reselect won’t work under my response section I guess this won’t work unless I write in another call function that goes from HTTP_RESPONSE_DATA to when_LB_FAILED or something… where in there I can do an LB::reselect.

     

     

    Thoughts?

     

     

  • ok. figured out the errors and created the rule. I also removed the LB::reselect entry under HTTP_RESPONSE_DATA section and just defined my pool to reselect on a "down" server so in theory (I'm thinking) this should handle the reselection for me if my iRule flags a host as "down".

     

     

    however, when using the rule I get this in the logs:

     

     

    TCL error: Rule sharepoint-payload-resp-chk HTTP_RESPONSE_DATA –

     

    cant read tMax: no such variable while executing expr $t0 $tMax

     

     

    weird. triple checked the syntax under RULE_INIT and that seems ok but somehow it's not reading the variable as defined within the expression.

     

     

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Oh, I'm sorry, that should be a global variable.

     

     

    Change "tMax" to "::tMax" everywhere, and it should work.

     

     

    /deb