Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Manage distributed sessions

To avoid a single point of failure, use a distributed architecture for managing sessions

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
For a good description of what sessions are and what the problem with having sessions across multiple servlet servers is, refer to Thomas E. Davis and Craig Walker's "Take Control of the Servlet Environment, Part 2: Alternatives to Servlet Session Management" (JavaWorld, December 21, 2000). Basically, the problem is that if you have more than one servlet server, session information exists only in one servlet engine's JVM and is not communicated to the other servlet servers. If a servlet server fails or shuts down for maintenance, any information saved in a session is lost. Also, if an environment has multiple servlet servers, a user with a session must always be redirected to the same servlet server in order to reference any data in that session. Davis and Walker suggest using a relational database that all servlet servers can access to save the session information. However, that solution still has a single point of failure: the server hosting the database. If the database went down, all session information would become unavailable to the servlet servers. Also, saving serialized objects into the database is a functionality that is difficult to implement in all databases.

Another possibility for multiserver session management utilizes the JavaSpaces API (for documentation, see Resources) to maintain records of the session objects. However, if the machine hosting the JavaSpace were to go down because of crashing or maintenance, all session information would be lost. So again, we are left with a single point of failure.

To accomplish the distributed session server with n-nodes, we must address three main problems:

  1. How to set up a repository to store session information
  2. How to synchronize distributed repositories
  3. How to let a servlet server retrieve the session information in such a way that if one repository suddenly goes offline, it tries to retrieve the object from the next repository


Introduction to the Mnemosyne

The repository we will use to store the session information is an implementation of the Mnemosyne interface (named after the Greek goddess of memory and mother of the muses). An object that implements Mnemosyne is responsible for managing all objects in the repository. Any other object that wants to write, retrieve, or remove objects in the repository must call a method of the Mnemosyne.

To be saved to a Mnemosyne, an object must implement the Memory interface, which defines the equalsMemory()operation for determining whether two memory objects are equivalent. That allows the Mnemosyneto figure out what object should be returned on a read or a take request. The Memory interface also extends Serializable so that you can use RMI to transmit the object across the network.

A Mnemosyne uses three other interfaces to represent its state:

  1. A CommonContext interface will store all information for the Mnemosyne. Each Mnemosynewill have one instance of a CommonContextobject to allow for synchronization between methods when reading, writing, and taking Memoryobjects. For writing and taking, the CommonContextdefines both "silent" and "loud" methods. The silent methods are used when objects need to be added without any event notifications. For example, when a Mnemosynereceives a WriteRemoteEvent (a notification that an object has been written to a remote Mnemosyne), it will want to write another object to the CommonContext. However, it doesn't need to notify the other remote Mnemosynes; the original Mnemosynehas notified them. So the write is done "silently" by calling the CommonContext's silentWrite()method. The "loud" methods give details of the event to any interested listeners that are called when an object is first put into the context.
  2. A Transaction interface allows for distributed transactions when reading, writing, or taking Memoryobjects. That means multistep operations can occur on the Mnemosyne.
  3. A TransactionContext interface manages a distributed transaction. That makes it possible to abort or commit transactions.


Keeping Mnemosynes synchronized is accomplished with two methods defined by the Mnemosyne: synchronize()and notify(). synchronize()is intended to get a local Mnemosyne"in sync" with a Vector of other Mnemosynes. (Those Mnemosynes may be local or remote, but for the sake of clarity, we will assume they are remote.) A sample implementation of the synchronize()method (from the MnemosyneImplclass) is displayed below. (See Resources for the complete sample code to this article.)

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources