[JAVA] The guy who replicates sessions with tomcat

What should I do with session information when autoscaling a Java web application using Tomcat? So I looked it up.

Cluster tomcat

Faithful to the basics.

A method of setting up a cluster in Tomcat and performing session replication. You just use multicast to form cluster membership, right? This time I was trying to use the AWS environment, so I got stuck here. Multicast is restricted within the VPC.

I'm wondering if Oracle Cloud and IBM Bluemix are built Java-friendly around here, but what about?

Use Amazon DynamoDB Session Manager for Apache Tomcat

Then, why not use the library provided by AWS? : cherries:

https://github.com/amazon-archives/aws-dynamodb-session-tomcat

This seems to be an extension of the persistent manager, which is one of the session managers provided by Tomcat as standard.

Persistent Manager provides the function to save session information in external storage, and by using it to change the session storage location from memory to DynamoDB, it seems to be a stateless application and enable autoscale. Is it?

Unfortunately, it has been archived and is no longer updated. As expected, I wanted to avoid adopting it from now on, so I decided to use it because the README asked me to use "memcached-session-manager" instead.

Use memcached-session-manager

https://github.com/magro/memcached-session-manager

Make settings while reading the SetupAndConfiguration wiki page in the README, and finally the definition of Context is as follows. I did.

META-INF/context.xml (excerpt)


	<Manager
		className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
		memcachedNodes="redis://redis" sticky="false"
		sessionBackupAsync="false"
		lockingMode="auto"
		requestUriIgnorePattern=".*/uptime_check.html$" />

Changes from Example

Change lockingMode to auto

It seems that this attribute is to prevent sessions from being changed at the same time due to Ajax, tab browsing, etc. and updates being lost.

You can specify the URL that has the possibility with a regular expression, but since it was difficult to specify exactly where it was with the target application this time, I set it to "auto".

It is said that this does not lock in the case of a request that is "read only", but specifically, the session was not accessed at all (`HttpSession # getAttribute ()` and `HttpSession # setAttribute" It seems to be the case () was not done).

Change requestUriIgnorePattern

If the URL of the request matches the regular expression specified by this attribute, it seems that the process of saving the session in the in-memory DB can be skipped.

For the page (uptime_check.html) where the load balancer performs health check, session information is not generated, so I set it as a URL to skip so as not to perform extra processing.

Also, access to the static file as shown in Example was set at first because the session is not related, but this time the target application caused unexpected movement, so I decided to change it.

The target application was designed to pass ServletFilter even for static files, but in this library, whenever `HttpServletRequest # getSession ()` is called in a request that matches requestUriIgnorePattern, it is new. The implementation is to generate a session, which causes the session ID to switch each time a static file is accessed, and the behavior of the application has changed.

setting sessionBackupTimeout

A timeout error now occurs after a small load. For the time being, I extended it to about 1.5 seconds and the problem was solved, but I doubt that it is okay. : thinking:

30-Oct-2018 07:04:51.146 WARNING [http-nio-8080-exec-1] de.javakaffee.web.msm.BackupSessionTask.handleException Could not store session 3EE38D05C62D287516AD504BFCBD572D in memcached.
Note that this session was relocated to this node because the original node was not available.
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:205)
at de.javakaffee.web.msm.BackupSessionTask.storeSessionInMemcached(BackupSessionTask.java:235)
at de.javakaffee.web.msm.BackupSessionTask.doBackupSession(BackupSessionTask.java:198)
at de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:119)
at de.javakaffee.web.msm.BackupSessionTask.call(BackupSessionTask.java:50)
at de.javakaffee.web.msm.BackupSessionService$SynchronousExecutorService.submit(BackupSessionService.java:345)
at de.javakaffee.web.msm.BackupSessionService.backupSession(BackupSessionService.java:204)
at de.javakaffee.web.msm.MemcachedSessionService.backupSession(MemcachedSessionService.java:1098)
at de.javakaffee.web.msm.RequestTrackingHostValve.backupSession(RequestTrackingHostValve.java:232)
at de.javakaffee.web.msm.RequestTrackingHostValve.invoke(RequestTrackingHostValve.java:161)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:800)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:800)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)

Session ID conflict

When generating a session ID, Tomcat searches the memory and regenerates if the session ID conflicts.

This library seems to erase the session information from the memory and save it in the in-memory DB, so there is a possibility that the session ID will not be unique. I was worried.

… The author doesn't collide so much, so I care too much. Are you saying (GitHub Issues)

Recommended Posts

The guy who replicates sessions with tomcat
The guy who tries-with-resources with kotlin
The guy who tries-with-resources with kotlin
Try using the Stream API in Java
The guy who replicates sessions with tomcat
To you who were told "Don't use Stream API" in the field
A crappy guy who makes layout adjustments sober and efficient with the development of libGDX