I'd like to setup tomcat clustering with redis without sticky sessions.
I believe this is not supported by the library and hence would like :
- to have confirmation
- to check if it's doable to implement such support (i.e. via PR) - I don't think so using the tomcat Store approach but perhaps I'm wrong (I hope so !).
I use the following context.xml :
<!--
Each processExpiresFrequency of tomcat backgroundThreadExecution,
the manager will check if the session need to be swapped from in-memory
to the store (redis) - which will be the case after 10s of idle.
-->
<Manager className="org.apache.catalina.session.PersistentManager"
processExpiresFrequency="1"
maxIdleSwap="10"
minIdleSwap="10">
<Store className="com.gopivotal.manager.redis.RedisStore"
host="${redis.sessions.host}"
port="${redis.sessions.port}"
database="${redis.sessions.database}"/>
</Manager>
Setup explanations:
I needed to setup maxIdleSwap and minIdleSwap to for in-memory sessions to be swapped to redis.
Otherwise, PersistenceManagerBase#findSession will try to get the session from memory (ManagerBase#sessions hashmap) and if it finds it, it doesn't get the session from Redis.
Problems found
But even having this setup, I cannot support non sticky scenario :
tomcat swaps out sessions from in-memory to Store (redis) in a background thread (the swapOut method will be called every processExpiresFrequency * backgroundProcessorDelay
- aka every 10sec in my scenario and swaps out sessions idled for more than maxIdleSwap secs).
Even setting if I setup this to a lower value, I can run in the following scenario :
a - browser request1 handled by Tomcat instance1 and updating session
b - browser request2 handled by Tomcat instance2 and updating session
c - browser request3 handled by Tomcat instance1 and updating session
if execution time between a and c is less than the swapOut time, then request c will use and old session state (state from a instead of state from b).
The only way to support a non sticky scenario would be to call PersistentManagerBase#swapOut(Session) method but this one is protected.
Thanks,
Adrian
P.S. : on a related topic, if a request is running for more than processExpiresFrequency*backgroundProcessorDelay + minIdleSwap then the session is swapped out
while it's used.
This prevents us to use a small value for minIdleSwap otherwise, session could be null in the middle of a request execution.