-
Notifications
You must be signed in to change notification settings - Fork 348
Home
A tomcat high-availability solution that additionally stores sessions in a memcached compatible key-value store for session failover, while reading them from local memory for optimal performance (for sticky sessions). For non-sticky sessions the memcached compatible backend is used as session store (keeping a copy of the session in a secondary memcached node). "memcached compatible" here refers to the memcached protocol, therefore the backend can be any (if you like persistent) solution "speaking" memcached (e.g. memcachedb, membase etc.).
- Supports Tomcat 6, 7, 8, 9
- Handles sticky or non-sticky sessions
- No Single Point of Failure
- Handles tomcat failover
- Handles memcached failover
- Comes with pluggable session serialization
- Allows asynchronous session storage for faster response times
- Sessions are only sent to memcached if they're actually modified
- JMX management & monitoring
Imagine you have a web application with sticky sessions running on several tomcats and want to have some kind of session failover. You want to have a scalable solution for that – just add more servers to handle an increasing number of sessions. This can be handled by sessions that are stored for backup in memcached nodes: If a tomcat dies all other tomcats will take over the work of the lazy/dead one and fetch the sessions from the appropriate memcached node(s) and serve this session from thereon.
Wait. You're using non-sticky sessions? Since version 1.4.0 also non-sticky sessions are supported, with optional session locking for concurrent requests and without a single-point-of-failure (sessions are stored in a secondary memcached for backup).
(needs to be updated for non-sticky sessions)
The memcached session manager installed in a tomcat holds all sessions locally in its own JVM, just like the StandardManager does. (This is the case for sticky sessions - for non-sticky sessions, the session is primarily stored in memcached, and only pulled into the session manager for the time of a request. When the request is finished the session is removed from the session manager to prevent stale session state).
Additionally, after a request was finished, the session (only if existing) is sent to a memcached node for backup.
When the next request for this session has to be served, the session is locally available and can be used, after this second request is finished the session is updated in the memcached node.
Now imagine the tomcat dies.
The next request will be routed to another tomcat. This tomcat (in more detail the memcached session manager) is asked for a session he does not know about. He will now lookup the session in the memcached node (based on an id that was appended to the sessionId when the session was created). He will fetch the session from memcached and store the session locally in its own JVM - he is responsible for that session from now on. After the tomcat served this request of course he also updates the session in the memcached node. You see tomcat failover is handled completely.
And that was only the first part of the story.
Also memcached node failover is implemented: if a memcached node is not available anymore the session will be moved to anoder node - also the sessionId will be modified and a new JSESSIONID cookie will be sent to the browser. As you are using sticky sessions make sure that the loadbalancer does use only the "plain" sessionId, without the suffix.
The memcached session manager knows a list of memcached nodes (e.g. as n1.localhost:11211 n2.localhost:11212
) that he references by the specified id (n1/n2). This id is encoded in the sessionId, so the sessionId might be 602F7397FBE4D9932E59A9D0E52FE178-n1
.
Here's a complete list of changes.
You want to see it in action? There's a sample webapp on github that comes with two tomcats and a sample web application built with wicket. The tomcats are configured to store sessions in memcached using kryo as serialization strategy. Just check out the project, mvn install the sample webapp and start memcached and the configured tomcats. Start playing!