Forum Discussion

torisan_93696's avatar
torisan_93696
Icon for Nimbostratus rankNimbostratus
Apr 10, 2007

Feasibility : Session Persistence based on URI parameters

Hi,

 

 

being new to F5 devices and iRules I have the following use case + question(s):

 

 

Use Case: We want to load balance requests (simple RR) but have session stickyness (persistence) based on certain parameters (a session is identified by three parameters). Using cookies or a designated session-id parameter is not an option (unfortunately). All this is with a BIG-IP 9.4.0 Build 517.5.

 

 

Idea: use an iRule to access the values of the URI parameters and then persist the node assignment based on a hash calculated off those three parameters. Persisting needs to be done once only, after that the the sticky assignment should be known to the balancer.

 

The basic idea for this to work would be something like that:

 

 

EVENT arrives {

 

get URI parameters

 

calculate hash from parameter values

 

check whether for this hash there a persistent node assignment already

 

IF yes {

 

let load balancer proceed based in the persistent assignment already there

 

} ELSE {

 

assign to a node

 

}

 

}

 

 

Question 1: Could it generally work like this?

 

 

Question 2: There are hash and universal persistence strategies in the divice which are not really much documented - can anyone tell me how to fill these with life for my purpose?

 

 

Questions 3:

 

- If ever it could work like this, which events would I have to use in the iRule? I assume HTTP_REQUEST, but LB_SELECTED sound also interesting - Will I be able to access HTTP specific variables in the LB scope? Thinking about my use case it could even be worthwhile to do things HTTP_RESPPONSE, since the first time node assigment would have happened already then, I could get the information on the server respondig and persist the assignment that has taken place. But I am not sure whether this is still "legal" to be done so late ...?

 

- I saw that there is a persist function which seems to be there to let the load balancer know a persistent assignment programmatically, right? Is there a way to access persisted node assignments?

 

 

 

Well,

 

if anyone would take the time to give me some first clues, if would appreciate it a lot,

 

Toralf Richter

 

  • Short answer, no problem at all -- you would use universal persistence, or perhaps just do it in an iRule (I need to go back and look). I will try to get you an example later today, but I wanted to let you know that this sort of thing is not going to be an issue at all.

     

     

    The general way it works is that the BIG-IP makes the load balancing decision however you tell it (round robin or better yet something like fastest or least connections) and then remembers that decision for future requests (i.e. persistence). You just need to write some code that pulls the persistence value from the URL.
  • Hi,

     

     

    thanks for replying. In the meantime I have come with something like the following:

     

     

    1. did an iRule with persist uie "my session key"

     

    2. setup persistence profile referencing this iRule and assigned this persistence profile a primary profile to my virtual server.

     

     

    So, please don't waste to much of you time ...

     

    However, do you happen to know how the scoping and durability of variables is handled?

     

    I can access a variable assigned with set xyz "value" in all events in an iRule - the events occur in a certain sequence probably (down the protocol stack on request, up the stack on response I guess, but the precise sequence is not clear), so if I assign a variable in HTTP_REQUEST, it is already filled in LB_SELECTED (which is OK for me). The same seems to hold for ::xyz - I believe the "::" notation is something like global in TCL, right?

     

     

     

    --- Code for the iRule I used ---

     

    when HTTP_REQUEST {

     

     

    Sticky Sessions for WF Connect based on URI parameters on URIs starting with the /extern infix

     

    if { [HTTP::uri] starts_with "/extern" } {

     

     

    set username ""

     

    set password ""

     

    set account ""

     

    this access to parameters will work also in pre 9.2 big ip systems

     

    log local0. "HTTP::query: [HTTP::query]"

     

    set namevals [split [HTTP::query] "&"]

     

    for {set i 0} {$i < [llength $namevals]} {incr i} {

     

    set params [split [lindex $namevals $i] "="]

     

    set pnum [expr $i+1]

     

    if { [lindex $params 0] == "account" } {

     

    set account [lindex $params 1]

     

    }

     

    if { [lindex $params 0] == "username" } {

     

    set username [lindex $params 1]

     

    }

     

    if { [lindex $params 0] == "password" } {

     

    set password [lindex $params 1]

     

    }

     

    }

     

    set ::persistenceKey "$account-$username-$password"

     

     

    this will only work in 9.2 and later version of big ip

     

    set persistenceKey [md5 "[URI::query [HTTP::uri] "account"]-[URI::query [HTTP::uri] "username"]-[URI::query [HTTP::uri] "password"]"]

     

    persist uie $persistenceKey

     

    log local0. "wf connect request (/extern) using session persistence key: $persistenceKey"

     

    }

     

    }

     

     

    Just to check - output result of node assigment to log

     

    when LB_SELECTED {

     

    log local0. "wf connect request (/extern) directed to [LB::server addr] for persistenceKey $persistenceKey"

     

    }

     

     

     

    Maybe it helps someone else as well.

     

    Toralf
  • If you have any troubles let me know. As far as scoping goes, normal "local" variables are available throughout the entire connection. So if you set something in CLIENT_ACCEPTED then you can read it in LB_SELECTED and/or HTTP_REQUEST, CLIENT_CLOSED, etc.

     

     

    Global variables are of the form $::varname and are shared among all connections so be careful with those.