Forum Discussion

Ryan_Crowley_18's avatar
Ryan_Crowley_18
Icon for Nimbostratus rankNimbostratus
May 18, 2009

How to cause a failover to another server when a error string is present in a response?

Ok,

 

 

totally new to writing iRules here, so bear with me through a couple stupid questions.

 

 

My situation is that i am using ColdFusion (and JRun) as an application server. Sometimes (frequently) JRun crashes, and displays an error message, which does not have the proper header information of a 500 error, or what ever.. it sends a 200.

 

 

So what I need to do is look at each response that comes back from the server, if i detect the string "JRun closed connection." or "Server Error", then retry the request on another server in the pool.

 

 

My problem is currently that I am not sure what I'm looking for here. It seems that the event I need is HTTP_RESPONSE_DATA or HTTP_RESPONSE and looking at HTML::payload but.. I keep going through the documentation and being that I'm new to both iRules and TCL, I'm never sure of which I'm looking for an F5 thing or a TCL thing. ya know?

 

 

If someone could point me to either an example or at least in the right direction I'd greatly appreciate it!

 

5 Replies

  • Why can't you use the monitors that come within the LTM? You don't need to look at the header information to determine the problem. You could simply look for content within the page which would mark it down if it does not recieve the message it was intending.
  • Or use reverse monitors with "JRun closed connection" and "Server error" as receive strings.

    Otherwise you're correct that you'd have to look in HTTP::payload, the main issue with that is you're going to have to do an HTTP::collect on every response, which could be fairly resource-intensive and/or add a lot of latency. Testing would reveal the extent of that. If you could limit the collect to something other than the full payload that would help (ie, if you know how many bytes along in the content either of those error messages would show up).

    Something like this might work, I haven't tested:

     
      
     when HTTP_RESPONSE { 
           HTTP::collect [HTTP::header Content-Length] 
            or use number of bytes rather than content-length 
     } 
      
     when HTTP_RESPONSE_DATA { 
        if { (string tolower [HTTP::payload] contains "jrun closed connection") || (string tolower [HTTP::payload] contains "server error") } { 
          LB::down   
     } 
      
     when LB_FAILED { 
        LB::reselect 
     } 
     

    The problem even with that is even if you mark the node down in a rule, the next successful health monitor will bring it back up, so you still need to have some sort of health monitor that's looking for this.

  • As cmbhatt and Denny said, monitors would be a much better solution. You could configure a standard HTTP monitor which checks for a string that isn't found in the 200 response with an error message. Or you could check for a 200 with a normal monitor and then look for (?:JRun closed connection|Server Error) in a reverse monitor.

     

     

    I'd try to avoid buffering any amount of response content for every response just to check for an error string. I don't think the added value of hiding an error message from some clients is worth the added overhead and latency for all clients.

     

     

    Aaron
  • Yeah, as it turns out, the health monitors looking for a string that is always there when the sites are up is a better choice. Thanks for all the suggestions though; the performance hit of looking at every response was the first thing that came into mind that made it seem unpalatable, but i proceeded with the assumption that there were either efficiencies in it I was not aware of yet, or there was just a better way to do it.
  • Right, it sounds wrong to retry the http request because we found the string "server error" in the payload of the first http response. Servers should return status code in the http status code, or at least, the logic should be based on the presence or absence of HTTP response headers, not the content.

     

     

    My .02

     

    Mohamed.