In my first article on taking advantage of RabbitMQ's asynchronous messaging to implement a cloud-friendly session manager, I covered the method behind the madness and introduced you to some of the functions a session manager has to perform in the course of doing its job. In this, the second of two articles covering this topic, I'll describe how loading and updating session objects is handled and, in the interest of fairness, give some disclaimers and acknowledge the trade-offs made to get here.
Whenever code wants to interact with a user session, whether that be to load it into its own memory or to replicate attributes on that session, it sends these messages to a queue whose name contains the session ID. The pattern used to create the queue name is configurable so you can partition user sessions by application, or even by something more fine-grained (without resorting to using multiple, non-clustered RabbitMQ servers).
The session store first checks its internal Map to see if the requested session happens to be local to this store. If it is, the store simply hands that session back to the manager. If it's not, then the store sends a "load" message to the session's queue. It doesn't just fire off a message, though. It turns out that a user's session can be requested from the store many times during the course of a request. If one were to send a load message every time this happens, then we would see a serious performance degradation. To get around this, before a load message is sent, the store checks to see if it's already trying to load this session. If it is, it simply waits until that process is finished and uses the session being loaded in that other thread.
The existing solutions for Tomcat session clustering are viable for moderate clusters and straightforward failover in traditional deployments. Several are well developed with a mature code-base, such as Apache's own multicast clustering. But there's no getting around the fact that today's cloud architectures place new and different expectations on Tomcat that didn't exist several years ago when those solutions were being written. In cloud architectures, where horizontal scalability is king, a dozen or more Tomcat instances is not unusual.
In my hybrid, private cloud, first described in my earlier post on keeping track of the availability and states of services across the cloud, I wanted to fully leverage all my running Tomcat instances on every user request. I didn't want to use sticky sessions as I wanted each request (including AJAX requests on a page) to be routed to a different application server. This is how virtual machines work at a fundamental level. Increased throughput is obtained by parallelizing as much of the work as possible and utilizing more of the available resources. I wanted the same thing for my dynamic pages. Not finding a solution in the wild, I resolved to roll my own session manager. The result is the "vcloud" (or virtual cloud) session manager. I've Apache-licensed the source code and put it on GitHub--mostly to try and elicit free help to make it better. You can find the source code here: http://github.com/jbrisbin/vcloud/tree/master/session-manager/
I sometimes pine for the days when I just had one server to worry about. I wax nostalgic, remembering how easy my life was when I didn't have servers and virtual machines growing out of my ears. It's almost the same feeling I get thinking about the days when I only had one child and you could just pop them in a carseat and take off. Now I've got kids driving themselves and their siblings to several activities a day and I can hardly keep track of whether I'm coming or going. I feel the same way about my data center.
If you have existing ASF Tomcat servers running on the same machine as tc Server, you will not be able to configure AMS to manage the application deployment, nor server configuration. AMS cannot manage ASF Tomcat to the same degree as it can for tc Server.
Often times a developer or operations professional needs access to monitor a Tomcat instance for purposes of capacity planning, troubleshooting, and performance tuning. There are many tools available already for Tomcat, some of them open source, and others paid for. Some tools are simple and others are complex management suites.
There are comprehensive monitoring suites available that monitor and manage Tomcat, and do it well; however, there is always a benefit to being able to create your own custom Tomcat/application management tools. The first advantage is that you get exactly what you want out of your utility. In my example, I wanted to have a way to browse a Tomcat server’s Java Management Extensions’ MBeans with a hierarchical, bash-like navigation. This allows me to quickly find and diagnose problems with my Tomcat server or custom applications running within Tomcat, and is more precise than trending those MBeans over time using a more comprehensive monitoring suite. I liken it to purchasing a ready-made suit, or having one custom tailored to your exact specification. It just feels better sometimes, and other times it is not practical.
Many utilities will not provide the specific feature that you need. There are usually a host of open source or commercial utilities for anything that one goal any developer or operations professional may want to achieve; however, often times that utility will not integrate well into their existing infrastructure, or not play well with automated processes that are pre-existing in the enterprise. In such cases, a custom utility can come in handy. Writing your own tools from scratch is a quick solution to a specific problem, and cuts out a lot of the fat. For simple tools, the complexity risk argument just isn't there, and in the time it takes to write a simple custom application.
There are three schools of thought on how to achieve the same task of managing a large production Tomcat infrastructure: distributed command-line solutions, custom tools using Java Management Extensions (JMX), and full-blown commercial software suites designed for managing Tomcat specifically. All of the methods and utilities for managing Tomcat have their own respective tradeoffs of elegance, simplicity, manageability, and cost.
The Tomcat Manager application is an excellent utility for managing Tomcat server. It has built-in support for deploying and un-deploying applications, reloading applications, gathering statistics about the JVM and Web application, as well as starting and stopping applications. IT even includes a Web-based JMX proxy where a user can modify and query MBeans through the manager application.
Where it falls short is that it primarily only supports functions for performing management operations at the servlet container level and above. It doesn’t allow a user to restart, start or stop the JVM that the Tomcat instance runs on from this Web interface and doesn’t have a built-in method for managing groups of Tomcat servers.
The simplest method is using ssh-keys and shell/Python/Ruby/Groovy scripts, which requires little effort to implement, but lacks in elegance. There are a number of service wrappers that support automatic restarts on failure, schedule restarts and taking thread dumps on failure, but they don’t come with a good interface through being managed remotely by a Java standard such as JMX.
Many institutions implement homegrown or scripted solutions for managing large Tomcat infrastructures. When dealing with anything beyond 10 Tomcat servers, it becomes tedious to log into each host and start and stop each Tomcat instance.
Many solutions exist for running a distributed command against a large group of Tomcat clusters. Some organizations set up SSH keys on all hosts and use a scripted or CGI Web interface to send a single command to a large group of servers; however, when dealing with thousands of hosts, installing the keys can become a tedious task, and without a configuration management utility, such as Puppet or Cfengine this can consume a large amount of time to perform.