Using tomcat in round robin mode - java

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

Related

Does session timeout get affected if session sharing is achieved between two java web application

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.

session migration/replication in tomcat

I have N number off application servers all behind a hardware load balancer.Now i want to make these app server session aware?
If i create a session on one appserver other app server will not be aware of it.After googling i found 2 approaches
1)Generate a random String .Put this randomString in cookies and store these in Db table with creation time.Very time when request comes in check this db table.But this opration is heavy
2)Use tomcat session migration?Now am sure if this works correctly .Does this work correctly?
Am using TOMCAT as my web server (Cant use other)
How can i configure tomcat for session migration/replication?Any tutorial?
I am not aware about the session affinity when working behind a hardware load balancer ,However for the scenario that you have mentioned as per your googling results for the 1st part you can use Memcache instead of cookie+database to reduce the operation response time . A simpler approach when using Memcache can be using "memcached-session-manager" .The setup and configuration is easy as mentioned at at http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration .
Session replication is a pretty broad topic. Have you tried the Tomcat built-in replication yet?
http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html
If that's not good enough for you, you can look for commercial tools like Terracotta Web Sessions. Or you could develop your own session cache around for example memcached.

How to generate custom JSESSIONID, based on some hash of user's data in order to replicate session

Is it possible to override Tomcat's embedded generator of JSESSIONID, to be able to create custom values of this cookie, based on user's login?
Why do I need this: I have a load balancer with "sticky sessions", configured to route requests with the same JSESSIONID to the same server, and I want to prevent situation, when same user can start two different sessions on different servers.
P.S: all this is about Amazon EC2
There is a better way to do this: See the tomcat manual on session replication in cluster
You can do so by defining your own customized session manager,
http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html
However, it probably doesn't work for your use-case. You don't know username before user logs in but the session needs to be created for the login.
I think pushing session to the backend is the best approach. You can use the JDBCStore session manager distributed with Tomcat. You can also find implementation for memecached.
If the purpose of multiple servers is for redundancy, you can also use clustering but that doesn't help you if your goal is to scale for load.

Session replication across JVMs in WebSphere

We have an infrastructure set up where in the webservers are clustered and the application servers are not. The webservers route the request to the application servers based on round-robin policy.
In this scenario, the session data available in one application server is not available in the other application server. Is there anyway by which the session data from first application server can be made available in the second application ? The two application servers are physically separate boxes in different cells.
One approach could be to use the database - is there any other means of accomplishing this session replication ?
In WebSphere there are essentially two ways to replicate session data:
Persisting to a database
Memory-To-Memory transfers
Which one is appropriate for your needs is highly dependent on your application scenario:
How important is the persistence of your session data, when all your application servers go down?
How many session objects do you have at any one time simultaneously?
In a DB you can store many sessions without much problems, the other option is always a question of how much memory is available.
I would go with the database, if you already got one set up, which all application servers use anyway.
Here is the link to the WebSphere Information Center with the necessary details.
One obvious solution is to enable clustering of your application servers. I assume from the way you worded your question you have rejected this option. Another option is to change the routing used by the web servers to use session affinity (requests for the same session go to the same app server).
Other that that, I'd second the answer by dertoni.
maybe you can look at 'terracota'. its an caching framework, which can cache sessions and runs on a seperate server
There are two options for clustering within WebSphere, session replication or database. If you have large session objects you are best off using database because it allows you to offload stale sessions to disk. If they are then represented then they can be extracted from the database, if you use session replication then those sessions need to stay in memory on not just your target server but also the other servers in the replication group. With large sessions this can lead to an out of memory condition.
With database session handling it is also very customisable and doesn't performance noticeably in the environments that I have used it.
don't forget oracle coherence.

Is there a way to specify a different session store with Tomcat?

Tomcat (version 5 here) stores session information in memory. When clustering this information is periodically broadcast to other servers in the cluster to keep things in sync. You can use a database store to make sessions persistant but this information is only written periodically as well and is only really used for failure-recovery rather than actually replacing the in-memory sessions.
If you don't want to use sticky sessions (our configuration doesn't allow it unfortunately) this raises the problem of the sessions getting out of sync.
In other languages, web frameworks tend to allow you to use a database as the primary session store. Whilst this introduces a potential scaling issue it does make session management very straightforward. I'm wondering if there's a way to get tomcat to use a database for sessions in this way (technically this would also remove the need for any clustering configuration in the tomcat server.xml).
There definitely is a way. Though I'd strongly vote for sticky sessions - saves so much load for your servers/database (unless something fails)...
http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html has information about SessionManager configuration and setup for Tomcat. Depending on your exact requirements you might have to implement your own session manager, but this starting point should provide some help.
Take a look at Terracotta, I think it can address your scaling issues without a major application redesign.
I've always been a fan of the Rails sessions technique: store the sessions (zipped+encrypted+signed) in the user's cookie. That way you can do load balancing to your hearts content, and not have to worry about sticky sessions, or hitting the database for your session data, etc. I'm just not sure you could implement that easily in a java app without some sort of rewriting of your session-access code. Anyway just a thought.
Another alternative would be the memcached-session-manager, a memcached based session failover and session replication solution for tomcat 6.x / 7.x. It supports both sticky sessions and non-sticky sessions.
I created this project to get the best of performance and reliability and to be able to scale out by just adding more tomcat and memcached nodes.

Categories