JBrisbin.com

Tomcat Session Manager backed by Riak

27
Dec

Tomcat Session Manager backed by Riak

I thought I would take a few minutes and put a little meat on the bones regarding the Tomcat session manager I recently uploaded to GitHub that's backed by the Riak Key/Value datastore.

I've been playing around with Tomcat session managers for the last year or so. When I started getting involved in private cloud architectures, one of the major obstacles I ran into was that the serious session manager that would provide a sticky-session-less configuration for Tomcat or SpringSource tcServer instances was a commercial offering. Sticky sessions are the bane of a private cloud's existence because they demand certain servers be available in specific configurations. The default clustering configuration for handling failover is sorely lacking in functionality, robustness, and scalability.

I've tried to back session managers by various methods, most notably with the somewhat temperamental one backed by RabbitMQ. No plug-in session manager will be as performant as the default, in-memory version. And, as it turns out when you start logging requests to the HttpSession, there is a lot of access of the session object throughout the request's lifecycle. This slows down the page generation time quite a bit. There are probably some optimizations that could be made (like caching certain bits of data from the session throughout the request lifecycle) in the interest of better performance. But the basic functionality is complete and it does what it's supposed to--namely to store objects from the user's session into Riak for access by any server or webapp that is configured to use that Riak server. This means you could configure multiple web applications in as many Tomcat instances as you want (behind a front-end like HAProxy or Apache mod_proxy) without using sticky sessions and the user's data will be available to that server whether the user was ever previously served a page from that instance before or not.

YMMV and Caveat Emptor, of course

The session manager is backed by the latest snapshot of the Spring Data Key/Value for Riak support I've been working on. Since that support is also dependent on Spring, you'll need to install a relatively large list of dependencies into your servlet container to use this session manager. This might be a problem for you, depending on your environment. Having an full Spring framework distribution in your servlet container is not entirely a bad idea, however. That would allow you to not have to deploy the Spring dependencies inside your web application, which will reduce WAR file size considerably. Your Mileage May Vary, of course, but I've found that having Spring in the servlet container's classpath is more a convenience than a liability.

Installation

To install the session manager for Riak into your Tomcat or tcServer servlet container, it's probably easiest to simply download the binary tar file on my GitHub page, which contains all the dependencies you need. The jar files are all in a subdirectory called "lib/" within the tar file.

If you want to install all these lib jars alongside your existing Tomcat lib jars, then do something like the following (replace CATALINA_HOME with the appropriate value for your environment):

cd /tmp
mkdir riak-session-manager
cd riak-session-manager
tar -zxvf ~/downloads/riak-sessions-0.2.tar.gz
cp -R lib $CATALINA_HOME/spring

This copies the contents of the jar file to a directory in your Tomcat home directory called "spring/". To add this directory to your container's classpath, edit the "conf/catalina.properties" file. Find the line that defines the locations for the "common.loader". Add the following to that line:

,${catalina.base}/spring,${catalina.base}/spring/*.jar

You'll also likely want to put a log4j.xml or log4j.properties file inside this directory as well. The Riak support in SDKV produces a lot of debug level log output.

Configuration

To start using this session manager once all the JAR files have been installed into your container's classpath, just add a Manager configuration to the META-INF/context.xml file inside your WAR file or web application directory. It should look something like this:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true">
  <Manager className="com.jbrisbin.vpc.riak.session.RiakManager" 
           defaultUri="http://localhost:8098/riak/{bucket}/{key}"
           mapReduceUri="http://localhost:8098/mapred"
           maxInactiveInterval="1800"/>
</Context>

The rest should be transparent to your web application. You should be able to simply store objects inside your session like you normally would. setAttribute calls will be serialized using a slightly modified version of standard Java serialization.

This session manager is no panacea for sticky-session-less configurations. The commercially-supported versions based on things like TerraCotta and GemFire are more performant and more flexible. But they're also not free either, which puts this session manager down into everyone's price range.

As usual, everything's Apache licensed. Contributions, feedback, and patches are greatly encouraged. The source is on GitHub and, for the technologically-curious, is written in Groovy and uses Gradle for the build.

blog comments powered by Disqus