23 mars 2016
→To best understand, you should know what Varnish is (a caching reverse-proxy), its basics (VCL, hash, etc.) and have a simple understanding of Tomcat.
→The software versions used in this post are: OS Debian 7 |Tomcat >= 8.0.15 |Apache 2.2 |Varnish 3.0.x |vmod curl – It should work without much adaptation on other distros.
At Oxalide, we aim to provide the best possible uptime to our customers while encouraging them to adopt an agile workflow where they push new versions of their apps often and seemlessly.
Because most of our clients are using PHP (or Ruby), we usually help them to setup Capistrano: it’s efficient and there are a lot of plugins for different frameworks (capifony for instance). Varnish is also quite often in our list of requirements, because of its sheer capacity to absorb trafic and deliver content.
When UGC came to us with their Java app, they had a set of strong requirements in response to which we had to innovate. With Alteis, their developpers, we set up a way to easily deploy apps in their Tomcat cluster while using Varnish in front of the whole infrastructure. On an infrastructure like UGC’s, Varnish is mandatory if we want to keep the number of servers used reasonable. It also allows us to (greatly) lessen the load when there is a lot of trafic (typically, on rainy days for cinemas!).
I will try to demonstrate how you can setup Varnish in front of a Tomcat cluster using Blue/Green deployment (known as Parallel Deployment in Tomcat parlance).
The goal here is to provide the following functionalities:
Because we don’t want to reinvent the wheel, the best is to use tools and methods that already exist. With this in mind, Tomcat already provides a lot of the functionnalities we need:
Let’s talk a little about parallel deployment. It allows you to deploy multiple apps under the same URL. You can use it to upgrade an app: just deploy the new version under the same URL and new users are going to use the new version while users with sessions on the old version will stay on the old version. When all users are on the new version, you can delete the old one.
! The problem
The problem you now have is that you want to use Varnish and by default Varnish identifies objects to cache by their URL. As app 001 and 002 have exactly the same URLs, their cache will be mixed up and the result will be desastrous: Varnish will serve a mix of app 001 and 002 to users.
To solve this problem, we will isolate the cache of both versions of the app and identify which version is used by a given user.
Set-up of a Tomcat cluster and cluster-wide deployment
As long as you can use multicast in your environment (which is NOT the case in some popular public cloud offers), this is pretty straightforward. In your tomcat’s server.xml, you can define it either in the « Engine » node (which will make the whole Tomcat member of the cluster), or in a « Host » node (which will make only this virtual host member of a cluster). I advise you to choose the later because you can then configure the FarmDeployer which allows you to deploy a webapp in your whole cluster.
[ ... ]
Let’s decompose this:
+ With this config, you now have a functionning Tomcat cluster where you can deploy apps by simply dropping them in a directory. Sessions will be shared between the servers which will enable you to setup a non-sticky load-balancer in front of your servers. It also means that if one of the Tomcats goes down, no user looses its session.
! You want all your Tomcat servers to be up and running while you are deploying an app. If a Tomcat server joins the cluster after the deployment, it won’t receive the messages ordering it to deploy the app, leaving it empty.
Tomcat’s parallel deployment
Each app must come as a WAR with the following naming convention: name##version.war. For instance, you can deploy both foo##001.war and foo##002.war under http://localhost:8080/foo.The trafic is then routed to one app or the other according to sessions. Let’s take an exemple:
You have updated your app without any downtime and completely seemlessly.
This method can be applied on a cluster without any problem.
At this stage, we have a functionning Tomcat cluster on which we can deploy several versions of the same application in parallel. The deployment is done by simply copying the war file in a directory on a single member of the cluster. In part 2, we will see how to integrate Varnish in this setup.
Article rédigé par : Théo Chamley – Consultant Architecte DevOps chez Oxalide