session migration/replication in tomcat - java

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.

Related

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

Tomcat / jBOSS sessions - where are they usually stored?

Preface: I'm not a java developer.
I have a question about Tomcat / jBOSS and other java application servers. Where are sessions (session data) stored? In PHP, sessions are usually stored in the database which means you can easily share session data in a load balanced environment. In Tomcat and other application servers, session seem to be stored in memory by default which would not apply in a load balanced env. While it is true that PHP stores sessions in files by default, it takes a few lines to hook it up to a DB. Is the same true of applications servers?
Basically, what's the pros for storying sessions in memory? Is this still standard practice for application servers? Thanks all!
I have a question about Tomcat / jBOSS and other java application servers. Where are sessions (session data) stored?
By default, I'd say in memory. Details are actually... implementation details which are application server specific.
In PHP, sessions are usually stored in the database which means you can easily share session data in a load balanced environment. In Tomcat and other application servers, session seem to be stored in memory by default which would not apply in a load balanced env.
Well, not exactly. What this means is that a client request has to be sent to the same node in a clustered environment (this is referred to as "session stickiness") and this is not an issue from a load balancing point of view. But this is an issue from a failover point of view: in case of failure of a node in a cluster, session state managed by the node can be lost. To solve this, almost all application server providers implement session failover (using various mechanism such as in-memory replication, JDBC-based persistence, etc). But, again, implementation details are application server specific. See for example how Tomcat or WebLogic deal with that. The Under the Hood of J2EE Clustering article on The Server Side is a very interesting reading too.
While it is true that PHP stores sessions in files by default, it takes a few lines to hook it up to a DB. Is the same true of applications servers?
As I said, not all application servers will offer JDBC-based persistence. Having that said, and to answer your question, configuration is in general simple when they do. But using a database is really not the preferred solution (actually, I avoid it at all price).
Basically, what's the pros for storying sessions in memory? Is this still standard practice for application servers?
Simply: performance! Serializing data, calling a database, writing to disk, all this has a cost. In-memory replication obviously allows to avoid some overhead. But it has some limitation too. For example, it doesn't allow WAN HTTP Session State Replication with WebLogic. But well, only few people need this :)
With the provided Session Manager, the session is always in memory but it has a manager to persist the session to JDBC store,
http://tomcat.apache.org/tomcat-5.5-doc/config/manager.html
Unlike in PHP, the session is still accessed from memory and it's only persisted to DB when the memory limit is reached or at server shutdown. So your load-balancer must have sticky routing for this to work.
The benefit of in-memory session is performance because db access doesn't occur for every transaction.
You can write your own session manager to simulate the PHP behavior.
The JavaEE spec does not dictate this, it is up to the individual implementations to decide. For example, the usual way to handle load balancing in Tomcat is to use replicated sessions, where the session data is multicast between the nodes. Storing session data in the database is a huge performance killer, and while Tomcat may support it, I really wouldn't recommend it.

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.

What's a good FOSS java servlet session replication solution

I work on a very high volume public website running on Tomcat 5.5. Currently we require stickiness to a particular server in order to maintain session. I'd like to start replicating session, but have had trouble finding a good FOSS solution. I've written my own Manager (using memcached as the store) but am having trouble dealing with race conditions if more than one server is handling the requests for the same user.
Is there a solution out there I should be looking at? I'm looking for not just something that works as a fallback if stickiness fails, but that would work if user requests are regularly spread to multiple servers.
This is a tough issue. In my opinion, Servlet sessions in Tomcat doesn't work at all if you have multiple servers and geo-distributed.
Our solution is to make our server totally stateless. All sessions are stored in database only. We use geo-localized MySQL with memory engine and the performance is much better than the old methods using Tomcat session replication.
Even though the chance of race condition is much less, it still occurs occasionally. We added record versioning in DB so we can detect race conditions and retry.

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