Forum Discussion

Chris_Phillips's avatar
Icon for Nimbostratus rankNimbostratus
Feb 05, 2011

assignment to pool and uie persist to member




I've a slightly odd scenario I'm trying to work out as slickly as possible with LTM's (before we've received them, so dev is hard...). We have a web app (apache fronting tomcat) of which we are going to be running up to 5 different versions of code (i.e. 5 pools), and we need a way to be able to reach a chosen pool but always using the same FQDN, as the web apps will always serve out dynamic content with the same fqdn in it's code etc... Now I think I can do something like say on the first connection, when some, currently undefined, condition is not met to send directly back a simple pool choice page from the LTM itself, but I'm unclear on the persistence that's possible when dynamically allocating pools.



I think I will want to use universal persistance, using XFF it's it there (most clients come via akamai) and if not, source IP (local users), but I'm not certain how simple this solution can be. If in my iRule the user (after clicking on a link in my pool choice page) comes in with a uri like /pool/a and I use that to set their pool to pool-web-a, and then strip that out of the uri before passing to the pool, what else will i need to ensure that all connections come through from that client to the same back end server, as it's not just the member of a pool, but the pool itself which needs to be persisted (unless in reality in the persistence code the pool doesn't actually figure in the code logic)



I think I would want to use persist uie, but maybe I should be using an inserted cookie instead? Is there any scenario where we could provide a solution allowing multiple browser instances on the same client to be persisted to different backends? I guess using different browsers (FX / Chrome) would permit different sets of cookies, but if I used UIE then they would all be persisted at the client level, right? Or is the point of UIE that I could actually also use the user-agent or similar to personalise the persistence data further?








6 Replies

  • Hi Chris,



    You could modify this iRule to select the pool based on a query string parameter and set a session cookie to ensure clients get back to the same pool:





  • Here's a quick example that lines up with the original URI based method...

     when HTTP_REQUEST {
     The first part of the URI should be a pool.
     for this example, my pools are named "p_1" and "p_2",
     so the URI of '/p_1/foo/bar.html will point to pool p_1,
     then the cookie persistence will take care of subsequent requests.
     NO default pool is set on the Virtual Server, and
     use a cookie insert persistence profile on the VS.
     Using variables for clarity.
    set uri [HTTP::uri]
    if { $uri ne "" } {
     Set the pool name, strip off slashes.
    set p [string map {"/" ""}  [URI::path $uri 1 1]]
    if {$p starts_with "p_"} {
    log local0. "orig URI: $uri"
    set newuri [string map "/$p/ /" $uri]
    log local0. "New uri is: $newuri"
     Set the new URI.
    HTTP::uri $newuri
    persist cookie
    pool $p
    log local0. "Selecting pool: $p, uri is [HTTP::uri]"
    } else {
    log local0. "Nothing to do, no pool in URI."


  • By the way, I feel like this approach may be brittle if you really put it through its paces so be sure and validate that either the URI or parameter-based methods will work for you. Also, note that in my example there's no contingency for an initial request (read: no persistence cookie) that doesn't have a pool name in the first part of the URI, so be sure and add that logic if you decide to poke at this method in your testing.



  • Thanks for these, not sure how I didn't see that first link. I'm a bit confused about that link though, as it does not use any formal persistence. Whilst I can see that the existence of the cookie is still there, and I guess is just more "visible" than a more muted "persist cookie" and letting it do it under the covers, I don't think I'd want to have to be going through iRules once a connection is under way. I'm looking to use this in a number of scenarios, at one end 5 identical pools which our test analysts would always need to pick a pool manually somehow, and at the other a production service where we'd want very close control over which source IP's (maybe..) can specify a pool so the great unwashed couldn't exploit it.



    I think a query string makes more sense than a uri change, as then I don't need to change the uri at all, and I can certainly see a combination of those two and some basic tests I've already written, but I'd really appreciate some clarity about how much meddling there would be once we are being load balanced. The less the better. I guess I can just use the cookie. In your example their Matt, you say to use an insert cookie persist on the VS, yet there's a persist in the rule. Do these work together, or override one another? I can certainly see how simple your example is there to get the hell out of the way and let normal persistence do it's thing when the uri is "normal" though, that's certainly good to see.



    I'm also somehow going to need a solution, maybe this one, to deal with appliances (games consoles and set top boxes) as well as web users. Hopefully I can use a uri / query modification as their starting point, but we'll see. Might need to do something on the back end instead using data groups... Anyone know if an xbox 360 posts consistently unique additional http headers per device? No? Ho hum...





  • In this specific case, the cookie insert in the rule and the profile on the VS work together. I did it this way to enforce the persistence record to be created when the pool name was figured out in the iRule logic.



    Question: are the multiple versions supported for different production devices, or for your organization's testing of the respective versions? I ask because this will really drive the approach moving forward.



  • Well hopefully it's for both. In the first instance we need 5 siloed (sp?) versions of a VOD service, fronted by a single 3900, as the builds come from our developers to functional testing on a private internal network. Then we have a load testing environment, with 2 versions fronted by a pair of 8900's, which is likely to be partially web exposed, and then finally a production environment, with 2 versions again with8900s, which will need some mechanism to ensure a newly deployed environment is operational before we flip a default pool to make it live for a gazillion users. I'd like to keep as much code as common as humanly possible, but without risking anything in the production environment. There is a security principle if all global users could add a paramter onto the query string, but I'd probably deem that to be trivial compared to all sorts of other risks that are much juicier. That said, I'm sure some public IP range block could be used.