Cloud architectures are different. They are designed to scale up and down quickly to make the most efficient use of the resources and minimize the cost. User experience is no less important in the cloud as well. User sessions should be seamless and often times dictate application architects to build applications with sticky sessions. Yet, these sessions can make your cloud architecture "lumpy" and concentrate active sessions on a single machine which may take time to eventually pull out of service. To build a truly flexible cloud architecture, it is much better to employ a session manager to maintain the user experience and still achieve the flexibility that is so attractive of cloud deployments.
After exhausting existing tools on the market today Jon Brisbin, Java guru at NPC International, the world's largest Pizza Hut franchise, has dealt with this in his own way with his company's cloud infrastructure. Recently he posted an article on how to keep track of the available services in a cloud deployment using a custom Listener that he open sourced on Github. Today, Brisbin posts another article on Tomcatexpert.com describing a new session manager he wrote that further completes this architecture.
In the article, Brisbin describes his requirements:
I dug into the code of the available session managers and found they simply would not do what I was asking them to do. My expectations were (and are) quite high. I was looking for something that was, simultaneously:
- Lightweight (sorry Terracotta)
- No single point of failure
- Asynchronous (for speed and efficiency)
- Easy to configure
- Zero (or nearly so) maintenance
I don't have to give the standard session managers a second thought when deploying a web application onto Tomcat. I wanted the same out of any other session manager. I also didn't want user sessions "copied" throughout the network all the time. I use lots of little Tomcat instances that have small heap sizes. If there was any way around it, I didn't want to keep entire copies of every active session in every server. But if I wanted the session loaded on demand, I'd need something screamingly fast. I use a cluster of RabbitMQ servers internally, so it only made sense to leverage that great asynchronous message broker to solve this problem.
Ideally, a user session would always be available in-memory. This is the fastest possible way to serve the user request. But it's inherently limiting. What if a new server comes online? Or, why keep precious resources locked up caching user sessions if that application server never sees that user?
Faced with these requirements, Brisbin went on to build his own session manager that suits his needs perfectly using RabbitMQ and Java. In describing generally how it works:
When a Tomcat server is asked to load a user session, it passes that ID into the CloudStore, which checks the internal list of session IDs. If it finds that ID listed there, it knows it has an active session and checks the internal Map to see if that session is actually local to the application server. If it's not, it publishes a "load" message to the appropriate queue. The thread is then blocked for a configurable amount of time until it's either got the loaded session or it times out and assumes the session is no longer valid (maybe because the server that had it in-memory crashed).
As a somewhat-related aside: the Tomcat server doesn't know what's on the other end of that queue. It could be another Tomcat server that has that session in its internal Map. It could also be a dedicated session replicator written in Ruby and backed by a Redis (or other NoSQL) store. Going the other direction: code running in standalone mode, like a system utility, could load the session object that was created when a user logged into your initial web application, exposing a single user object to any Java code running anywhere in your cloud. Pretty cool, huh? ;)
When the server responsible for that session gets this load message, it serializes the session it has in-memory and sends those bytes back to the sender. The sender's listener gets this "update" message and checks to see if any loaders are waiting on this session. If it finds one, it gives the deserialized session to the loader, who, in turn, passes the session back to Tomcat, who continues to serve the page.
The code for the new session manager can be found under the Apache 2.0 license on Github:
The complete article introducing this session manager (and teaser for what's next) can be found here: