Discussions

Web tier: servlets, JSP, Web frameworks: distributed sessions in a multiple-JVM environment

  1. In many application server environments, for reasons of load balancing and failover, there is more than one JVM process sitting behind a web server. A web server plugin usually, but not always, handles the job of deciding which Java "engine" will handle a given request (sometimes a dedicated process does this instead).

    Because HttpSessions usually exist in the context of a single Java process, many application servers either allow you to (iPlanet) or force you to (WebLogic) run in "sticky" or "pinned" mode, meaning a given browser session will only be load balanced for its first request; subsequent servlet requests within the same session will always be routed to the same Java engine, to ensure the same HttpSession is available.

    The proposed final draft of the servlet 2.3 specification indicates that a container may provide a facility for distributing the HttpSession, at the vendor's discretion, but it's certainly not a requirement.

    I believe iPlanet lets you do this, if you want, by having one of its engines maintain the distributed session information. You can designate one or more backups, with each backup also maintaining this set of sessions. Performance naturally gets worse with each additional backup. However, I have heard some people say that they've had better performance ignoring this feature and just using the simpler "sticky" session solution.

    WebLogic does offer a session "in-memory replication" feature, but it seems to me to be more for failover purposes... from my reading of the documentation, it seems you don't have a choice on the sticky issue... you have to use it; an HttpSession on one Java engine is not available in the others. The copies of the sessions seem to exist only to protect against losing session iformation when a JVM dies.

    Websphere looks like it's taken an in-between position: you can use the sticky behavior, or configure something they call "Session Persistence", where sessions are available from all engines, but this is achieved by storing them in a database. Some Websphere performance presentations I have seen claim this is a quite slow.

    On the freebie side, Apache Tomcat has a notion of multiple Java engines ("Tomcat Workers"). However, the HttpSession isn't distributed and I don't see any provision for doing anything other than using the sticky option.

    I wonder if a bolt-on, all-Java implementation of a distributed session would be useful. iPlanet wouldn't be improved by it, and someone might argue "just use stateful session beans" in the other EJB containers, but I still wonder if it would be a fun exercise and useful for Tomcat users (no EJBs there) and others. Something where you tell the system about the other JVMs via a properties file (things like host and port numbers), and the developer just uses a setAttribute()-type method call to write. Probably dog-slow with all the network traffic and serialization/deserialization in a large environment; I don't know.

    One problem I see is in the cases where the vendor forces a sticky behavior (WebLogic? Tomcat?). Even if you had a distributed session service, it wouldn't matter if some load balancing logic is forcing subsequent requests to the same Java engine for the duration of an HttpSession. Well, I suppose this wouldn't happen if you are never using HttpSession.getSession() in the first place, but a replacement instead.

    Are people pretty happy with the sticky session idea? Can anyone comment if it seems to perform much better than iPlanet's distributed session alternative? Or IBM's Session Persistence via the database? Would it be at all useful to add such a facility? I suspect it would be slow in pure Java (which I'd want to use, to be portable), and this slowness would negate anything you'd gain by "not going sticky." But it would be fun to play with. Any thoughts on this, or knowledge of anything already available?
  2. Marc,

       You raise some excellent points about sticky sessions and the potential performance issues associated with them.

       Take a look at this article for a discussion about how Resin implements load balancing. It supports sticky sessions, distributed sessions and network sessions.

       http://www.caucho.com/articles/balance.xtp

       Your points about sticky sessions are valid. Especially, in cases where the backend has a lot of data that is associated with a particular session that it has to sort through. By having that session be sticky, that particular JVM can be overloaded by an active user requesting a lot of data. I've been burned by this in a previous project. In a sense, is it fair to say that sticky sessions dont offer true load-balancing?

    Disclaimer: I have posted references to Resin and Orion server in some of my responses at TheServerSide. I have no affiliations to neither product nor their parent companies. Just find them to be useful implementations.
  3. Hi Raj,
    Thanks for the kind words and pointer the the article.
    However, I get "Can't contact servlet runner at localhost:6802" at the moment; I'll try again later.

    I keep reading about Resin at this site. Apparently,
    people like it.
  4. Hi Marc, Thanks for this beautiful content describing multi jvm Env.scenarios , Same problem I face, In Multi JVM (sticky session) Env. Multiple request are getting distributed between mutiple JVMs (Java Processes) at backend through load balancer. But as you said sometimes load balancer will distribute many subsequent request to one Java Process only , Because of that many sessions are getting created at one java process (JVM) and all connections gets consumed in very short time for that JVM,Due to that other incoming requests distributed to the same JVM through load balancer are not getting connections for execution. Let me knom if there is any solution for this or this needs to bear with that.