Forum Discussion

Adam_24063's avatar
Adam_24063
Icon for Nimbostratus rankNimbostratus
Mar 19, 2007

persist based on cookie with URI pools

Howdy, I'm trying to take our working jsessionid iRule and add a twist. We'd like for requests with a .seam URI to go to one pool, while all other requests go to a different pool (the motivation here is to equal out expensive seam requests which treverse a Tomcat backend vs. simple JavaScript/JPGs/etc). Below is the working rule we use today:


rule jsessionid {
   when HTTP_RESPONSE {
  if { [HTTP::cookie exists "JSESSIONID"] } {
    persist add uie [HTTP::cookie "JSESSIONID"] 86400
  }
}
when HTTP_REQUEST {
  if { [HTTP::cookie exists "JSESSIONID"] } {
    persist uie [HTTP::cookie "JSESSIONID"] 86400
    if { [HTTP::uri] contains ".seam" } { log local0. "IP:[IP::remote_addr] URI:[HTTP::uri] NODE:[LB::server]" }
  } else {
    set jsess [findstr [HTTP::uri] ";jsessionid=" 12 32]
    if { $jsess != "" } {
      persist uie $jsess 86400
     }
   }
}
}

Along with the attempted new rule..


rule seam_persist {
   when HTTP_RESPONSE {
  if { [HTTP::cookie exists "JSESSIONID"] } {
    persist add uie [HTTP::cookie "JSESSIONID"] 86400
  }
}
  when HTTP_REQUEST {
    if { [HTTP::uri] ends_with ".seam" } {
      pool www_seam
      log local0. "POOL:seam IP:[IP::remote_addr] URI:[HTTP::uri] NODE:[LB::server]"
    } else {
      pool www
      log local0. "POOL:www IP:[IP::remote_addr] URI:[HTTP::uri] NODE:[LB::server]"
    }
    if { [HTTP::cookie exists "JSESSIONID"] } {
      persist uie [HTTP::cookie "JSESSIONID"] 86400
    } else {
      set jsess [findstr [HTTP::uri] ";jsessionid=" 12 32]
      if { $jsess != "" } {
        persist uie $jsess 86400
      }
    }
  }
}

It should be noted the URI selection work fines, what we're running into is requests aren't being holding stickyness or persistence; this is obvious from navigating our application or logging LB::server. Thanks for the help!

3 Replies

  • First off I would highly suggest you get away from handling cookie persistence in the dynamic fashion that you are doing with Irules, the cookie hash function handles it much better, believe me, I had a very extensive JSESSIONID iRule that performed almost the exact same thing, but failed on more than one occassion when the server took a dive. So, what I would suggest is that you use a cookie hash persistence profile, set it to expire with the same timeout value as your deployment descriptors state within the web.xml, or application.xml.

     

     

    Once that is in place, take out the UIE persistence and simply rely on the URI inspection, which is working for you.

     

     

    The issue is that you are referencing multiple pools in your URI which most likely contain different application servers, with different JSESSIONID entropy, so what you need to do is create the hash profile.

     

     

    However, this still will not solve your other issue in which if you send a request to a different pool, you loose persistance, if you are using the same servers in the other pool as the original pool (how many times can I say pool?) the hash cookie profile will work, if not, there is no way to handle this because each container (e.g. Tomcat etc) has it's own unique entropy used to generate the SessionID, and when a client comes in with an unreferenceable ID, it treats it as a stale ID, and generates a new one.

     

     

    Course, you could try to setup the Hash cookie profile (referencing the JSESSIONID as the cookie) and match across pools, that may help to resolve the problem, but again, only if you are using the same servers in the same pool.

     

     

  • Thanks for the reply. We avoided the cookie function to support folks who don't accept cookies, this is why you see the ";jsession" string in URI's.

     

     

    We're only using seperate pools as a way to "count" the connections of .seam requests seperate from JPG/CSS/JS/etc files; we'd like the expensive requests more equally weighted. We're flexible on what technique to use for this, using two seperate pools with the same nodes just seemed to most obvious at the time.
  • Yes that is the standard reason, which escaped me, which is why I always use simple persistence as a backup in case the cookie fails, but doesn't always work.

     

     

    At any rate, the problem is the nodes have to be the same for the JSessionID to work, match across pools should preserve the JSessionID in the header, if you use the profile that I suggested earlier, if not, then you have the issue of trying to keep track of the SessionID.