Generate new JSESSIONID when on different application server - java

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.

Related

How can I identify the client or caller of an EJB within the request?

I have a system where several (20 or so) web app servers (hosting a website) talk to the same 2 - 4 EJB servers (through a VIP). I'd like to know if it is possible to identify which one of those app servers generated a specific request.
For example: Website example.com works by sending HTTP requests to any of 20 app servers to handle the request. These servers are named (internally) app01 through app20. It is ensured that all requests with the same session ID will be routed to the same app server, thus enabling us to logically track all requests from a single user. Some requests will need some extra data not available directly, for which there is an EJB (2.1) application on another cluster of 3 servers, named ejb01 to ejb03. Connections to the EJB servers are made through a VIP (ejb00), which routes the requests round-robin style to the three EJB serves.
Within the logging (we use Apache Log4J) of the EJB servers, it would be really nice if I could identify which of the 20 app servers a request originated from. The alternative is checking the logs on each server separately - but I don't have a good way to grep through the logs on 20 different boxes.
My question is: is this possible within Standard EJB? I'd be willing to do something non-standard, if there was nothing else, but it's gotta be reliable and work on my system. We use Weblogic 11g, both for the web-app and the EJB servers.
I've seen suggestions to pass the identity of the caller as a parameter, but that would mean an extra parameter for each of 20+ EJB methods, and that's rather unwieldy.
Any solutions, anyone?
There is no standard solution. There was a proposal in JSR 149, but it was withdrawn. Adding an extra parameter to the remote methods is probably your best option. If you're using RMI remote, you might be able to write an ORB interceptor to add a custom context on the client side, receive it on the server side, and set a thread local around the method invocation on the server.
WebSphere Application Server has a non-standard solution called work areas, which does work for remote EJB.
I am not familiar with WebLogic, so I don't know if they have a similar solution. Searching for similar terms finds a WorkContextMap that looks similar, but I don't know if it works for remote EJB since all the examples I can find are for webservices.

Glassfish-3.0.1 mixing user sessions - SSO

We are experiencing a strange behaviour, we have an application (jsf 2.2.4 embedded) that has a login form, glassfish has sso enabled and a custom realm (LDAP). We have also several applications (some with jsf 2.2.4 embedded, others using jsf implementation of glassfish) that are linked by the application that contains the login form.
For some reason when glassfish has created 300 - 400 sessions approximately or cpu is at high rate or maybe at a random moment, and we navigate from the main application to the others and then return to the main application, at some point glassfish changes the jsessionidsso cookie, assigning a new one. The thing is that sometimes that cookie represents the session of another user, so thats where we have a session mix and can see the information of another user.
We are running Glassfish-3.0.1 on a Centos-6.5, no proxy.
We have already tried updating weld following this guide http://www.andygibson.net/blog/quickbyte/updating-weld-in-glassfish-v3/ but we are currently experiencing the same behaviour.
Can someone point us to the right direction? What could it be?
Thanks so much!
Regards,
Mateo.
We have the same problem and don't know the reason yet. Our temporary solution: we attach the user ID to every user request and we check the permissions of that particular user every time, because we unfortunately can not trust to the session id. If the session does not belong to the user ID, we reject the request and ask the user to initiate a new session. The problem affects less than 1 percent of sessions.
We suspected the load ballancer system in front of the Glassfish servers, but if someone has the same experience without load ballancer layer, the problem hides somewhere else.

Using tomcat in round robin mode

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

An issue dealing with JSP Session

I'm having an inconvenient dealing with sessions..
I have this:
www.mydomain.com
sub1.mydomain.com
sub2.mydomain.com
sub3.mydomain.com
and when I log into "www", then I change to "sub2" (for example) I
figure out it creates another session :S
why is that??
I need the same session for www, sub1, sub2, sub3, and so on.. ALL in
"mydomain.com"..
what can I do?? is it like that and I have to make a trick?? or is
there a "legal" solution for what I want??
The JSESSIONID cookie is issued by the container, and the cookie domain and path is always that of the web application's domain and context root.
It appears as if you have multiple applications in which case, the JSESSIONID issued by one application will not be recognized by another, due to a change in either the domain or the context root, even if the applications are in the same container.
There are multiple ways to deal with this:
If you are not dealing with a high-value application, and if you can guarantee that no 'rogue' applications will be deployed on the server, you can configure the server to share sessions across applications. Weblogic Server can be configured to do this.
Use a central authentication and session management provider - SSO.
Use TLS/SSL - most servers do not issue a JSESSIONID cookie when communication is over SSL, and instead use SSL itself to store state. You will have mixed results here.
Update:
Glassfish v3 allows you to set the domain for the session cookie. This is done via the session-config element in sun-web.xml. I'm not sure if this is available in v2 or lower versions of Glassfish.
Yes, it is like that because you will have separate session cookie for every different domain. Which web server do you use ? You may implement SSO related solution to share data across the domains.
Look at this tutorial: http://javadude.wordpress.com/2011/05/12/glassfish-3-1-%e2%80%93-clustering-tutorial-part2-sessions/
I summarized all steps for Glassfish 3.1 and session replication

Tomcat sessions expiring unexpectedly

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.

Categories