Parallel Deployment with Tomcat 7
Tomcat 7 introduces the ability to perform parallel deployment. This means that multiple versions of a war file can exist on single Tomcat server at the same time. More importantly, those multiple versions of the war file can be used simultaneously by different users.
The idea is that this allows a new version of a war file to be deployed to a Tomcat server, without requiring any downtime. This (in theory) offers a simpler process than the more conventional approach involving multiple Tomcat servers and load balancers.
This blog post demonstrates this feature and also notes some limitations.
A Simple Example
For the purposes of this example, we will use a simple page which refreshes every second (thus continually fetching from the Tomcat server) and displays a session id and a timestamp.
If you want to try this yourself, the code is as follows …
I then created a war file called
test##001.war containing this file (plus a
WEB-INF and the bootstrap CSS I’m using) and deployed it to my Tomcat server.
This then enabled me to view this page in my browser …
Note that I am using Safari, Firefox and Chrome here to allow me to demonstrate the parallel deployment goodness as this post progresses. For now, it is enough to note that I have opened my test app in Safari and Firefox (and left Chrome unused for now).
The observant will have spotted that despite calling the war file
have been able to access it simply using the url
/test. This is because the
## and whatever follows is the versioning string … more about this later.
Version 2 of my Test App
I next created a second version of my test app, which is identical to the first
version, but displays the name “Example #2” instead of “Example #1”. I saved
this with the name
test##002.war and deployed it to my Tomcat server …
As you can see, by “deploy” I simply mean that I copy it to the Tomcat server webapps directory. You can also see that both versions are now available on the server.
If I now use my Chrome browser to access my test app, I get the following …
This is the clever part … since the Safari and Firefox browsers had a session running (for version 1) before I deployed version 2, they continue to access that version. However, because the Chrome version accessed the page after I deployed version 2, it gets served version 2 of the app.
This is the essence of the parallel deployment feature of Tomcat 7. When you access an app, Tomcat will serve up the latest version it has. Once you have established a session, Tomcat will continue to serve the version of the app you accessed when you set up the session.
It is also worth commenting further on the version identifier (the part after the ## in the war file name). The version strings are compared using a string comparison not a numeric one. This has the advantage that you have more flexibility in your versioning labels, but does come with the “gotcha” that if you need to zero pad an numbers you use (otherwise version “12” would be seen as an earlier version than version “2”).
Moving Through the Versions
In a real application, sessions would be naturally killed during a journey (e.g. at basket checkout) and users naturally move to new versions. To demonstrate it here, I’ll simply clear the cookie cache …
That’s the Firefox session I’ve killed (the middle browser) so when the display refreshes, it now moves to version 2 …
To take this a step further, if I deploy a third version of this app I can end up with all three running in parallel …
I can then kill off the Safari session (causing it to move straight from version 1 to version 3) …
Finally, killing off the Chrome session results in all three picking up version 3 …
As you can see from the above, a new session will always get the last version of the app – it cannot pick up an earlier version.
Implementing Parallel Deployment
As demonstrated in the above example, to be able to use parallel deployment in Tomcat 7 is simply a matter of adding a version string to your war files. Assuming you have an automated build process, this should not be a significant change.
Rolling Back a Deploy
One advantage of this approach is that you can roll back a deploy by deleting the new version of the war file. Tomcat will then automatically pick up the previous version (i.e. the one with the highest version string).
It is worth considering what you do with older versions. You could delete them once there are no sessions attached. Alternatively, you can leave them deployed (since they won’t be accessed), or adopt a policy of keeping the last N versions of a war file.
Limitations and Drawbacks
Although parallel deployment offers advantages in simplifying updating war files, there are also limitations which need to be considered. Here are some which spring to mind:
- You may not wish to have users simultaneously on different versions of your app, for example …
- If your update is to address something critical (e.g. a change in terms and conditions) you may prefer to force the update so it rolls out immediately
- In test environments it is usually important to be sure what version of the app is being tested
- If the data model changes, then you will probably need to make sure the app layer and the data layer are in sync, so you can’t run two versions of the app
- Similarly, if you are interacting with a messaging bus, if the message format changes you won’t be able to have two versions of the app