What should I do with session information when autoscaling a Java web application using Tomcat? So I looked it up.
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?
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.
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$" />
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).
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.
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)
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