I am trying to understand the tomcat's (version 8.0.21) session persistence after I execute kill -9 . When I start my tomcat ( using startup.sh), I observe (randomly) http sessions of my web app ( which were created before the kill command execution) still being maintained.
I understand this session persistence across restart, if I execute shutdown.sh to stop the tomcat and then bring the tomcat up again. My understanding of kill -9 is some what similar to 'power-off'. So my question is :
Whether the standard manager implementation gets invoked just after kill -9, which tries to persist session before termination.
Or I just get the previous session because my tomcat may have serialized the few session, (somewhere into its temp directory) while it was up earlier (before execution of kill -9).
The Tomcat session manager documentation has lots to say on the topic. Here's a few relevant gems:
Tomcat provides two standard implementations of Manager for use — the default one stores active sessions, while the optional one stores active sessions that have been swapped out (in addition to saving sessions across a restart of Tomcat) in a storage location...
...
Whenever Apache Tomcat is shut down normally and restarted, or when an application reload is triggered, the standard Manager implementation will attempt to serialize all currently active sessions...
Emphasis mine - I think it's important to note that active sessions get serialized when you reload applications. If you've reloaded the application recently, and then do a kill -9 (which, as correctly noted in the comments, gives Tomcat no warning and no time to clean anything up, and thus should only be done as a last resort), then you will indeed see sessions persisting across the restart.
It is also possible that you may have the persistent storage manager configured:
In addition to the usual operations of creating and deleting sessions, a PersistentManager has the capability to swap active (but idle) sessions out to a persistent storage mechanism, as well as to save all sessions across a normal restart of Tomcat.
Though I will say that unless you did this configuration, or this install of Tomcat was preconfigured for you, this would not be the case.
Related
People usually use SessionManager to keep the session variable for each web agent. But these values will be lost if the server is crashed or redeployed.
I can think of some way such as save session to an external memcached, database or file, but I'm not sure which way is suitable to face with security problem and perform the best performance.
How can I keep sessions alive after restarting the service?
My tomcat application randomly invalidates the session information and the user if forced to log back in again. This only happens when the webapp is deployed with other specific web applications. When it is run by itself with no other app running, it works fine. There is a conflict somewhere, but I am unable to find it.
The webapp in question uses both the Spring and Hibernate frameworks. The other webapps do as well. Here is an example of what happens.
When I first log on, everything is fine.
JSESSIONID Matches
The JSESSONID matches in both the cookie and the management console. However, when using the application, it randomly terminates the session.
Session gone in Tomcat Console
When I another web request, the login page is shown and a new JSESSIONID has been generated.
From the research I have done, the JSESSIONID is generated whenever a JSP file is called and there is no current session. I don't understand why the session is being invalidated, but only when it is run alongside other applications. I have checked the memory usage, and I didn't notice a correlation between a memory drop and the sessions being invalidated. I guess that means that Tomcat isn't clearing sessions to free up memory.
Any help is much appreciated
Check that session.setMaxInactiveInterval() is not programmatically configured in the other web applications. This would elicit the behavior you describe.
This method is slightly different from the session timeout value that you would find in your web.xml files. (Here's a good rundown.)
the following steps may help you:
Are you sure that you did not override the default session time out value, Please check out your session time-out at runtime.
from tomcat manager page (~/manager/html/list) see the status of your web application sessions and press on the value of your app sessions column.
If i share session(HTTPSession) of one java web application deployed and running on a dedicated machine in tomcat with other java web application deployed and running on a separate machine in tomcat, will the session time out get affected?
i mean if i jump from one app to another in a different browser window with the same session, will the first app timeout and vice versa?
Every session is managed by the underlying container, so two containers will not communicate to see if session should be timed out or not.
So say your tomcat may timeout your session as per the configuration even if same session is being used in another container and is still active.
Also it is not a recommended approach to share session between JVM's as not all containers will allow you to do that. I think WSAD allows you to do that, but instead of sharing session, I would suggest you to share objects instead.
I want to run my tomcat-instances in a configuration where requests are served to several tomcat-instance via round robin. I don't want to use any internal cluster manager.
As far as I see if every request is served by different tomcats, an unknown sessionId would arrive at a tomcat, so it would be forced to create an new session and overwrite the old sessionId. So for every request a new session would be created. This seems to be a lot of overhead.
Is my view on that things right? Is there a way to disable tomcats sessions management?
Regards,
Michael
Basically you have two choices:
1) Replicate your sessions so they become reachable by any Tomcat node. Solutions: Tomcat Cluster, memcached-session-manager, possibly others.
2) Use a load balancer and implement sticky sessions. First requests will be routed randomly on a round robin basis, but subsequent requests will stick to the same server. Solutions: mod_proxy, hardware traffic managers.
The disadvantage of the first option is that session replication is costly, not very reliable and often requires Serializable-only data to be put in session.
The disadvantage of the second approach is that if you shut down your Tomcat for maintenance, the users will be forced to log in again.
You are incorrectly assuming that "for every request a new session would be created". The new session will be created only if not created before on that same server, or if it was created but already expired.
We usually used Tomcat behind an Apache web server with mod_jk for load balancing the requests across the Tomcat instances.
With sticky sessions a user will only get a session upon the first request and will afterwards always be directed to the Tomcat from where his session originates. So there is no need to replicate sessions across all Tomcats and the requests will be distributed across the Tomcats, too.
Of course, this does not ensure some kind of round-robin which you asked for.
A session will only be created once your code requests the session so if your application doesn't require the session then just simply dont access it. Checkout the section on getSession() in HttpServletRequest
http://download.oracle.com/javaee/5/api/javax/servlet/http/HttpServletRequest.html#getSession(boolean)
I'm not sure if there is a way to replicate the session across different tomcat instances however if you require some user state without session then you can use cookies instead.
EDIT: If you do need to replicate the session you could probably start by reading this tomcat document.
http://tomcat.apache.org/tomcat-5.5-doc/cluster-howto.html
We are running tomcat application server that handle over 100 concurrent sessions.
In the last 2 months the most active users noticed that sometimes they are getting kicked off from the system.
As I understood from the log tomcat sessions are getting expired without any reason.
I see no problems from the web application side.
Is there any problem from the tomcat side?
Tomcat 6.0.18.
If there has been no code change triggering this, I would look at memory usage. This might be the effect of Tomcat running out of memory and invalidating sessions to recover.
If at all possible monitor garbage collections, and/or put surveillance on with jconsole Java Flight Recorder or jvisualvm.
A possible cause is that you put in the session an object that does NOT implement the Serializable interface. Tomcat occasionally writes some of the sessions on the disk. If a session contains non-serializable objects it will simply be removed from the container (because of the NotSerializableException). If this is happening you should see the Exception in the tomcat log file.
I would increase the monitoring of the server in general and the sessions specifically.
A good monitoring application is lambda probe - it allows you to view the current sessions and their data. I would also add a HttpSessionListener to log session creation and destruction.
Edit
Is is possible that you add some non serializble objects to the session and Tomcat fails to passivate them to the disk?
Edit 2
Lambda probe seems to be dead, and there a much better fork of the project over at http://code.google.com/p/psi-probe/
there is a timeout, that you can configure in your web.xml:
<web-app>
...
<session-config>
<session-timeout>-1</session-timeout>
</session-config>
</web-app>
use -1 for no timeout
Increase your logging of sessions, which may shed some light onto your problem.
The Tomcat config page's Logging in Tomcat includes an example of increasing logging of sessions.
We just ran into this with tomcat 6_0_18 and ibm 1.5 jvm
turns out it was an ibm jvm issue with atomic operations.
There is a fix in tomcats greater than 6_0_19 to handle it.
It also doesn't occur in sun 1.5 jvm
here are some more details
tomcat bugzilla case
I have seen similar problems when the following prerequisites exist:
multiple instances of the tomcat app are installed across multiple JVMs
load balancing (between the web server and the Tomcat JVMs) is not configured correctly.
Tomcat's session replication feature is not enabled
Due to the incorrect load balancing config, the web server may randomly decide to break session affinity and send an incoming request to a Tomcat JVM that has never seen the session before. The Tomcat JVM will issue a new session and the user will lose all of their previouS session data and effectively start over.
You can search Tomcat's bug database, but it would be better to have another look at your web application first. The chances that there is something wrong with Tomcat are very low.
Try to investigate what causes session invalidation. Are you using filters? Do you have cross-context requests? Try adding logging information for every request to find out, when exactly the session is lost.
I had a similar symptom (but more consistent). Users would sign in ok, go to the dashboard ok, then loose the session.
I realized I had done a Java 16 to 18 upgrade and had not recompiled everything. Cleaned (mvn clean) and recompiled the code for ALL my .jars/.war.
Problem solved, for me.
I hope this helps someone.
Eventhough I do not know the cause of the problem, one possible fix (which I had done at my previous project) would be to run the application on a tomcat cluster and have session failover. Sessions can be by default sticky and when one node goes down, the healthy nodes pick up the sessions and all this is transparent to the end user.