I have an application deployed with JBoss on two machines in a cluster. When a user logs into one application server, I've validated that the session is replicated to the other cluster (logging in with the same cookies to the other server confirms this).
JBoss handles this replication automatically with Infinispan and JGroups for caching and messaging respectively. My issue is: How can I get a handle of each replicated session in the second server?
The normal way nowadays to manage HttpSession instances is by implementing the HttpSessionListener interface which calls a sessionCreated(HttpSession s) method whenever a new session is added. This works fine for the first server, but this does not work in the second server because: the session in server 1 is serialized, copied over, then de-serialized in the second server, which bypasses the constructor and therefore does not allow the session to be registered to the HttpSessionListener listener.
Is there another possibility to get a handle of a session as it is replicated? Could I perhaps listen for de-serialization events (is that even possible) or do something else?
Related
I've got a system with multiple jboss (4.2.3) servers behind multiple apache servers.
In the situation where one of the jboss servers goes down we still get users with sessions for those servers coming in, however they "bounce" around the servers due to the application server ID in the JSESSIONID, causing apache to send the request to random servers for each request, resulting in session timeout errors.
My initial thought was to create an interceptor in the application to invalidate the session if we detect that the session is actually for a different server (i.e. session.invalidate())
But that doesn't cause a new JSESSIONID to be generated (even with the fix described here https://issues.jboss.org/browse/JBAS-4436)
My next idea was to create a valve to do the same job but on the Request instead of the HttpServletRequest, however I can't find the library to add ValveBase to jboss 4.2.3 (and I'm not even certain that valves are supported by 4.2.3)
Is there either:
a) Anything I've missed in getting one of my 2 ideas above to work
or
b) Any better ideas I haven't thought of for solving the problem ? (I would like to cluster the sessions but can't at the moment due to infrastructure problems)
Thanks.
Use Session Stickyness in Apache so it won't switch to other application server until it dies.
I am working on Spring MVC application. Usually face a problem that when server get down the client session get expired.
So, I want to make session alive. When server goes up then client not need to login again.
Can we save cookie id or session id in database to make client reconnect.
could it be what you are looking for?
how-can-i-make-the-spring-security-stores-the-http-session-in-database-so-i-can
here is the link to the blog-article:
Tomcat 7 JDBC Session Persistence
If you are using spring security, you can have your own implementation of SecurityContextRepository (By default this is HttpSessionSecurityContextRepository) to persist the session content in database. In this way when user presents his cookie the security framework filter (SecurityContextPersistentFilter) will look at your database for the session. Hence, even when server is down the context is still available in database and is loaded during next user request after server restart.
If session persistence is not an option, you may have to deploy a cluster of servers with session replication strategy.
The purpose of remember me is altogether different. It's not to have session across server restarts, but for across restarts in client (browser). Even with remember-me you can not get it across server restarts, unless you use PersistentRememberMeService (to database)
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.
thank you you guys for looking at my post.
Due to grey areas in licensing issues, I have two instances of tomcat running. I'm using Apache proxy to seamlessly communicate between the two.
App1 lives in tomcatA.
App2 lives in tomcatB.
Both requires user authentication and uses sessions for storing data. App1 is the only one visible to outside world and all the requests that comes in to App2 are generated by JavaScripts from App1. Unfortunately, App1 has a session and sends that specific JSESSIONID to all the requests from App2. Since there isn't a session with that specific id in App2, it returns with errors.
Is there a way for me to initialize a session with specific id?
Is there a way for me to modify all the requests so that it puts the valid session id into the headers.
Edit: I need App2 to realize that requests coming through, from App1, with a particular session id maps to a session that App2 created.
Even if both application lived in the same Tomcat, sessions would be different as they are issued on a per-app basis. Personally, I am not entirely convinced by this design.
If your question is how to propagate authentication to another app, use a single sign-on application like Josso or a CAS; to share session data, you can use a centralized cache accessible from both applications and accessible through JSON.
And yes, session data is bad.
Update: can't you simply implement a handshake protocol like: app2/register/{app1 session id} - at this point you both hold both session ID's and you can correlate each other. This can be done also with a session listener.
You could just use a different session cookie name (or path, if possible) for your tomcatB. tomcatB would thus consider the JSESSIONID cookie as any other cookie, and not as a session cookie.
See http://tomcat.apache.org/tomcat-7.0-doc/config/context.html.
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