Forum Discussion
Wade_Miller_113
Nimbostratus
Dec 11, 2007Need persistance assistance
So I have a non-standard tcp protocol that I need to load balance with the following conditions.
1) multiple clients with the same "channel identifier" in the first part of the tcp payload need to persist to the same server.
2) if there are no active sessions for the "channel identifier" then load balance and populate a key in the session table.
3) If the "channel identifier" exists in the session table then persist the new session to the same nodes as the rest of the matching sessions.
4) once the the "channel identifier" is associated with a node, only that node can handle requests for that "channel identifier."
5) once a day, all session/persistance info for this vip/pool must be flushed. This can be done by fairly low session timeout value and stopping all nodes for a period greater than this timeout value.
The below irule seems to work ok in limited testing, but there are a couple scenerios that could cause it to fail.
What if a node fails and the 300-400 clients that were connected to the failed node all reconnect at the same time?
Since there could then be multiple requests at the same time and a few hundred milliseconds before the first connection populates the session table, could this result in load balancing multiple clients with the same "channel identifier" to different nodes?
Is there some sort of serialization or locking in the session table that could/would prevent this?
What can I do to make this work without rewriting the application?
Thanks/Wade
------------------------------------------------------
when CLIENT_ACCEPTED {
TCP::collect 44
}
when CLIENT_DATA {
set ConStr [TCP::payload 44]
set SessionID [substr [getfield $ConStr "@" 2] 0 " CHID" ]
log local0.info $SessionID
set PersistTo [session lookup uie $SessionID]
log local0.info $PersistTo
if { $PersistTo equals "" } {
pool [LB::server pool]
log local0.info "No session ID, load balancing the connection."
} else {
pool [LB::server pool] member $PersistTo
log local0.info "$SessionID sent to $PersistTo"
}
}
when SERVER_CONNECTED {
if { $PersistTo equals "" } {
session add uie $SessionID [IP::server_addr]:[serverside {TCP::remote_port}]
log local0.info "Added $SessionID to [IP::server_addr]:[serverside {TCP::remote_port}]"
} else {
log local0.info "$SessionID already exists to $PersistTo"
}
}
- Wade_Miller_113
Nimbostratus
BTT - spark_86682Historic F5 Account
The below irule seems to work ok in limited testing, but there are a couple scenerios that could cause it to fail.
What if a node fails and the 300-400 clients that were connected to the failed node all reconnect at the same time?
What can I do to make this work without rewriting the application?
when CLIENT_ACCEPTED { TCP::collect 44 } when CLIENT_DATA { set ConStr [TCP::payload 44] set SessionID [substr [getfield $ConStr "@" 2] 0 " CHID" ] log local0.info $SessionID if { $SessionID equals "" } { No SessionID, just load balance as usual log local0.info "No session ID, load balancing the connection." pool YOUR_DEFAULT_POOL_NAME } else { All clients with this SessionID go to this server timeout is 120 seconds persist uie $SessionID 120 } }
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects