Forum Discussion
iRule with JSESSIONID including the server id with jvmRoute
Dears,
unfortunately I did not find a fitting post to my problem:
We have two or more servers they creating a JSESSIONID where the id of the server is added on the end like so:
7B0DE3926CF23C27DFF9C80BE604B009.serverID0
5C38A6262816E6E3A6BBB0B3ABB42D3A.serverID1
(we are using the -DjvmRoute=... on the tomcat)
Is it possible, that every JSESSIONID with the ending serverID0 is always routing to server 0 and serverID1 to server 1?
The rootcause is, that if the routing switches for a user, they logged in 3 days before, they has to loggin again, although there is a valid security context on tomcat available on the "right" server...
- xuwenCumulonimbus
# first create 3 pool,name is pool_node0, pool_node1, pool_default # pool_node0 member 10.1.1.10:80 monitor tcp # pool_node1 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 { 0 pool_node0 1 pool_node1 } } when HTTP_REQUEST { if { [HTTP::cookie exists "JSESSIONID"] } { set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 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 } }
- xuwenCumulonimbus
PLAN B:
Firstly, create 2 pool:
pool_web member is 10.10.10.1:80 10.10.10.2:80
pool_default is standby(its member is 20.20.20.1:80 20.20.20.2:80) when pool_web all members is down
Dynamically add elements to the array according to pool member select
# create pool_web member is 10.10.10.1:80 10.10.10.2:80 # create pool_default is standby(its member is 20.20.20.1:80 20.20.20.2:80) when pool_web all members is down when RULE_INIT priority 500 { array set static::pool_array {} } when HTTP_RESPONSE priority 500 { set node_ip [IP::server_addr] set node_port [TCP::server_port] log local0. "node_ip is $node_ip, port is $node_port" if { [HTTP::cookie exists "JSESSIONID"] } { # serverID0,serverID1 set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 1] log local0. "node_x is $node_x" # dynamic add element in array ,key is ID, value is pool member set static::pool_array($node_x) "$node_ip:$node_port" log local0. "response event pool array is [array get static::pool_array]" } } when HTTP_REQUEST priority 500 { if { [HTTP::cookie exists "JSESSIONID"] } { set server_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 8 1] log local0. "server_x is $server_x" if { [active_members pool_web] == 0 } { log local0. "exists cookie, select slave pool pool_default" pool pool_default } else { # 0 10.10.10.1:80 # 1 10.10.10.2:80 if { [array get static::pool_array $server_x] != "" } { set mem_ip [getfield [lindex [array get static::pool_array $server_x] 1] ":" 1] set mem_port [getfield [lindex [array get static::pool_array $server_x] 1] ":" 2] if { [LB::status pool pool_web member $mem_ip $mem_port] eq "up" } { pool pool_web member $mem_ip $mem_port } else { pool pool_web } } else { reject log local0. "client send fake invalid cookie JSESSIONID!" } } } else { if { [active_members pool_web] == 0 } { pool pool_default log local0. "no cookie, select slave pool pool_default" } else { pool pool_web } } log local0. "request event pool array is [array get static::pool_array]" }
- xuwenCumulonimbus
plan C:
Creating the universal persistence profile
To create a universal persistence profile and reference the persistence iRule you created in the previous procedure, perform the following procedure:
- Log in to the Configuration utility.
- Navigate to Local Traffic > Profiles.
- From the Persistence menu, click Create.
- Type a name for the universal persistence profile.
- For Persistence, click Universal.
- For Configuration, select the iRule check box, then click the persistence iRule you created.
- Click Finished.
iRules code:
when HTTP_RESPONSE priority 500 { if { [HTTP::cookie exists "JSESSIONID"] } { # serverID0,serverID1, length is 9 set node_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 0 9] log local0. "node_x is $node_x" # persist add uie, key is serverIDX, timeout is 1800s persist add uie $node_x 1800 } } when HTTP_REQUEST priority 500 { if { [HTTP::cookie exists "JSESSIONID"] } { set server_x [findstr [HTTP::cookie "JSESSIONID"] "serverID" 0 9] set value [persist lookup uie $server_x] if { $value != "" } { persist uie $server_x } } }
I wrote this one a while ago (there is room for improvement with the array access):
when RULE_INIT { array set static::srvid_node { node1 172.29.32.160 node2 172.29.32.161 node3 172.29.32.162 node4 172.29.32.163 } set static::debug_map_srvid 1 } when HTTP_REQUEST { set original_request "[IP::client_addr]:[HTTP::method]:[HTTP::uri]:HTTP/[HTTP::version]" if {([HTTP::cookie exists JSESSIONID])} { set session_id [HTTP::cookie value JSESSIONID] set node_id [getfield ${session_id} . 2] set node_ip [getfield [array get static::srvid_node ${node_id}] " " 2] if {(${node_ip} ne "")} { if {(${static::debug_map_srvid} > 0)} { log local0. "info: valid header-cookie JSESSIONID found (${session_id}) in request (${original_request}); mapping to ${node_ip}" } } else { log local0. "error: broken header-cookie JSESSIONID found (${session_id}) in request (${original_request}); balancing to default pool ([LB::server pool])" pool [LB::server pool] return } } elseif {([findstr [HTTP::path] JSESSIONID 11] ne "")} { set session_id [findstr [HTTP::path] JSESSIONID 11] set node_id [getfield ${session_id} . 2] set node_ip [getfield [array get static::srvid_node ${node_id}] " " 2] if {(${node_ip} ne "") and (${static::debug_map_srvid} > 0)} { log local0. "info: valid url-cookie JSESSIONID found (${session_id}) in request (${original_request}); mapping to ${node_ip}" } else { log local0. "error: broken url-cookie JSESSIONID found (${session_id}) in request (${original_request}); balancing to default pool ([LB::server pool])" pool [LB::server pool] return } } else { if {(${static::debug_map_srvid} > 0)} { log local0. "info: no addressed node found in request (${original_request}); balancing to default pool ([LB::server pool])" } pool [LB::server pool] return } if {([LB::status pool [LB::server pool] member ${node_ip} 80] equals "down")} { log local0. "warning: addressed node (${node_ip}) in request (${original_request}) is unavailable; sending 503" HTTP::respond 503 noserver Server "test service" Connection Close Date "[clock format [clock seconds] -format {%a, %b %d %Y %H:%M:%S %Z} -gmt 1]" return } else { pool [LB::server pool] member ${node_ip}:80 return } } when HTTP_RESPONSE { if {([HTTP::cookie exists JSESSIONID]) and ($static::debug_map_srvid > 0) and ([info exists original_request])} { log local0. "info: response cookie JSESSIONID ([HTTP::cookie value JSESSIONID]) found in response for request (${original_request})" } } when LB_FAILED { # Ausloesung des Events bei Nichtverfuegbarkeit innerhalb Monitoring Timeout if {${static::debug_map_srvid} > 0} { log local0. "error: selected server not available (${node_ip}:80) for request (${original_request}); sending 503" } HTTP::respond 503 noserver Server "test service" Connection Close Date "[clock format [clock seconds] -format {%a, %b %d %Y %H:%M:%S %Z} -gmt 1]" return }
- MarcoPNimbostratus
Many tanks so far for the suggestions - will check it with my IT guy 😄
You are awsome!
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com