Forum Discussion

AlexS_yb's avatar
AlexS_yb
Icon for Cirrocumulus rankCirrocumulus
Aug 28, 2021

My stick session

Hi

 

The system has multiple tomcat stype containers, they provide a JSESSIONID and we append a node id to the end

so we have a JSESSION id that looks like

 

JSESSIONID=83987345.nodeX where X could 1 2 3 4 5

 

on my nginx setup i had

 

 server app1.env:XXXX slow_start=0s weight=1 max_fails=0 fail_timeout=10 route=node1;

 server app2.env:XXX slow_start=0s weight=1 max_fails=0 fail_timeout=10 route=node2;

 

  # Session Persistence based on JSESSION ID, if necessary

  sticky route $route_cookie;

 

 

# jboss mapping for nodes

map $cookie_jsessionid $route_cookie {

  ~.+\.(?P<route>\w+)$ $route;

}

 

 

I want to do this in F5 i presume with F5.

 

But ... the persistence model in F5 break my nginx setup.

 

so

 

client A -> connect talks to node1

JSESSIONID 123456789.node1

 

node1 dies

client A -> get rerouted to node2

JSESSIONID 123456789.node1...

JSESSIONID 987654321.node1

 

note 100% sure if the jsessionid changes or not. but i'm 100% sure that the nodeX stays the same

 

 

until node1 comes back client gets routed to node2

 

once node1 comes back the client is routed back to node1

 

I presume irule.

 

but how do I say go to pool member if its up otherwise go to pool (use the balancing method)

 

 

 

 

  • xuwen's avatar
    xuwen
    Icon for Cumulonimbus rankCumulonimbus

    pool_node1 member 10.1.1.10:80 monitor tcp

    pool_node2 member 20.1.1.20:80 monitor tcp

    pool_default member 10.1.1.10:80 20.1.1.20:80 monitor tcp

     

    iRuels code:

     

    when RULE_INIT {

      array set static::pool_array {

        1 pool_node1

        2 pool_node2

      }

    }

    when HTTP_REQUEST {

      if { [HTTP::cookie exists "JSESSIONID"] } {

        set node_x [findstr [HTTP::cookie "JSESSIONID"] "node" 4 1]

        log local0. "node_x is $node_x"

        if { [active_members [lindex [array get static::pool_array $node_x] 1]] == 0 } {

          pool pool_default

        } else {

          pool [lindex [array get static::pool_array $node_x] 1]

        }

      } else {

        pool pool_default

      }

    }

    • AlexS_yb's avatar
      AlexS_yb
      Icon for Cirrocumulus rankCirrocumulus

      Think I like this. but modified

      I will create singleton pools for each member and 1 pool with all members.

      then

      if I have no JSESSIONID or no NODE

      then go to the generic pool

      other wise

      test to see if pool with 1 node corresponding to the NODE1 is available

      if yes then send it

      if no then send to generic pool

       

       

  • Hello Alex.

     

    You could configure an iRule that routes traffic base on the "nodeX" value of the JSESSIONID cookie, checking first if this specific member is UP using "active_members" command.

    https://clouddocs.f5.com/api/irules/active_members.html

     

    Config details.

    • Create an iRule
    • create a generic pool with all members
    • create specific pools with only one member (let say, node1, node2, ...)

     

    iRules steps:

    1. Get the "nodeX" value.
    2. if "[active_members pool_nodeX] == 0" use generic pool
    3. if "[active_members pool_nodeX] > 0" use specific pool (pool_nodeX)

     

    Hope this helps you.

     

    Regards,

    Dario.