Zero downtime deployment to Tomcat 7 with Maven

This is just one way of deploying to Tomcat, not the only one


Similar to the "sister guide" (Developing with Tomcat and Eclipse), there's more than one way to skin the deployment cat. With Maven, good options are the Tomcat plugin and the Cargo plugin. Modern PaaS platforms also typically have their own cluster deployment tools. However, this guide is specifically for Tomcat 7 using its parallel deployment feature. - Kalle Korhonen / tynamo.org

Tomcat 7 added a superb but rarely used feature, called parallel deployment. With enough memory on the system, you could approach poor man's high availability with parallel deployment but where it really shines is continuous integration and continuous deployments to your alpha/QA systems. It completely sucks if your development team/CI system deploys a new version to an alpha server 60 or more times a day and you need to reload the web application every time (or worse yet, restart the whole server) while at the same time, your QA is desperately trying to use the same system to verify features and test user experience. With parallel deployment, existing users can keep using the same version of the web application until their session expires while others can be simultaneously using newer versions.

However, parallel deployment and tools for it are surprisingly rough on the edges. I haven't found any Maven plugins that would automatically take advantage of the feature so I hacked one together, using Ant so those disliking Maven can also enjoy the feature (smile).

Little convoluted perhaps readable and straightforwarded. The important thing to note is that Tomcat's parallel deployment feature relies on special naming convention of the war file, with double hash (#) character separating the version from the context/war file name. Above, I'm using the BUILD_NUMBER variable as generated by (Jenkins) CI system but you are of course free to use any other version identifier, however Tomcat only understands alphabetical ordering of version identifiers. Another thing to note is that currently the previous versions are not unloaded by default but just passivated. This causes the memory to fairly quickly run out which is why I'm simply manually deleting the previous war files that causes Tomcat to undeploy and remove their exploded webapp folders. For continuous delivery, you most likely want to set Host attribute undeployOldVersions for removing previous instances, i.e. have something like this in your Tomcat's server.xml configuration file:

Finally one more note about the parallel deployment is that if loading the new version of a webapp fails, it'll never become active, so you always have a version of the webapp in a runnable state.

Powered by Atlassian Confluence