Forum Discussion

Alan_Evans_1020's avatar
Alan_Evans_1020
Icon for Nimbostratus rankNimbostratus
Apr 08, 2009

iRule (HTTP) to select pool based on URI then continue using that pool for duration of session

I am working on a HTTP iRule where I want to create an iRule that selects a pool based on an entry URI and then have the HTTP session continue using that pool and redirect the user to a regular URI for the service.

 

 

In the setup:

 

SYSTEM

 

BIG-IP 9.4.4

 

 

POOLS

 

pool_prod (contains nodes prod1..n)

 

pool_dev (contains nodes dev1..n)

 

pool_train (contains nodes train1..n)

 

 

VIRTUAL SERVERS

 

vs_site_http - listening on port 80, just does redirects to https (DONE)

 

vs_site_https - should send traffic to pools based on entry URI (LB is terminating SSL)

 

 

INTENDED BEHAVIOR

 

SCENARIO 1

 

1. user1 enters on site.com/prod/

 

2. lb assigns the session to the prod pool

 

3. lb redirects the user to site.com/servlet/somejsp

 

4. user1's browser goes to site.com/servlet/somejsp

 

5. lb having seen user1 enter on /prod/ sends traffic to prod pool

 

 

SCENARIO 2

 

1. user2 enters on site.com/dev/

 

2. lb assigns session to the prod pool

 

3. lb redirects user to site.com/servlet/somejsp

 

4. user2's browser goes to site.com/servlet/somejsp

 

5. lb having seen user2 enter on /dev/ sends traffic to dev pool

 

 

SCENARIO 3

 

1. user3 enters on site.com/

 

2. lb treats / URI as /prod/ URI, does like scenario 1

 

 

I can persist on cookies, SSL, source or whatever. Pretty flexible, just need to keep a session tied to a pool without expecting the information to be in every requested URI, just the first.

 

 

Seems like, excuse the meta code...

 

 

HTTP_REQUEST {

 

if session not already seen {

 

select the beginning of URI from class or switch on it

 

set a cookie or create a persistence table entry

 

send a redirect

 

}

 

}

 

 

It looks like 'persist add' might be all I need, but the wiki page is a little terse and I am still looking for other docs. Is persistence smart enough to keep a connection in a pool and assigned to a specific node?

 

 

Can anyone help me out?

3 Replies

  • Hmm... Guess I didn't need the smiley on the post. Sorry, don't spend much time in forums.
  • 'Persist add' is a generic way to manually insert a persistence record. It doesn't actually include the persistence method.

    I think using a cookie per pool would be a good method for this scenario. However, I'm not sure I understand the full scenario. Would a client ever start with a request which is sent to one pool and then during the same browser session make a request which goes to another pool? If so, would you want to remove any previously set cookies, so the client would be sent to the most recently selected pool for requests which don't have a corresponding URI to pool mapping in the class?

    I'd think the logic would be something like this:

     
     when HTTP_REQUEST { 
      
        If request is to a path which has a corresponding path to pool mapping 
           Select this pool 
           Use cookie insert persistence for this pool (persist cookie insert "pool_A_cookie") 
           Set a variable to track that we're using this pool 
        Else request is not to a path which has a corresponding path to pool mapping, check for pool cookie 
           If any pool cookie exists 
              Select this pool 
              Use cookie insert persistence for this pool (persist cookie insert "pool_X_cookie") 
              Set a variable to track that we're using this pool 
           Else no pool cookie, so take some default action like select default pool, redirect client or send HTTP response? 
     } 
     when LB_FAILED { 
      
        If pool is down, do something like select default pool, redirect or send HTTP response? 
        Else if pool is up, reselect a different pool member? 
      
     } 
     when HTTP_RESPONSE { 
      
        Expire all the other pool cookies based on the variable which tracks the currently used pool 
     } 
     

    Aaron
  • A few tweaks still to be done but this is the basis of what I am using.

     
     when HTTP_REQUEST { 
       set lb_persist [LB::persist] 
       set lb_server [LB::server addr] 
       set lb_key [LB::persist key] 
       set http_uri [HTTP::uri] 
       log local0. "persist: [LB::persist] server: $lb_server uri: $http_uri" 
       if { [LB::server addr] eq "" }{ 
         if { [HTTP::path] starts_with "/dev" } { 
           pool pool_dev 
           eval [LB::select] 
           persist cookie 
           HTTP::redirect https://[HTTP::host]/?[HTTP::query] 
         } elseif { [HTTP::path] starts_with "/train" } { 
           pool pool_train 
           eval [LB::select] 
           persist cookie 
           HTTP::redirect https://[HTTP::host]/?[HTTP::query] 
         } elseif { [HTTP::path] starts_with "/prod" } { 
           pool pool_prod 
           eval [LB::select] 
           persist cookie 
           HTTP::redirect https://[HTTP::host]/?[HTTP::query] 
         } 
       } 
     }