On a basic LAMP stack, at least with our RHEL5/6 servers, we are able to apply rolling code-updates to our document management system across load-balanced web servers without killing users' connections (and possibly document downloads) by using apachectl graceful
and apachectl graceful-stop
. We're migrating to a Tomcat web server based application, and we'd like to have that sort of capability with our new system, but I cannot find any sort of equivalent functionality with tomcat6. Does such a capability exist with tomcat6?
Short Answer
If you have load balanced tomcat instances and your load balancer supports sticky sessions and live configuration, then the you can achieve the kind of rolling and transparent upgrades that you are talking about (to some degree) by rotating out the tomcat instances 1 by 1.
Long(er) Answer
With respect to the other answers correct description of tomcat as an application server vs httpd and the associated issues there are actually a number of ways to get what you want, which is an end-user transparent restart.
Given that tomcat frequently takes 30 seconds or more depending on how monstrous and bloated your application is to deploy from cold, it is usually useful to be able to do it transparently.
An additional bonus of this method I will explain is that it is reassuring to be able to check the new application in production before putting it live to your customers.
So... apache's graceful restart advises its children to exit after their current request has completed, and replaces them with new spawned processes/threads that have re-read the new configuration file. Hence long running connections can finish downloading while new requests get the new content. There are effectively 2 versions of the application running during the graceful restart transition managed by apache, the old and the new.
Unfortunately, with tomcat if autodeploy=true is set, any change to the configuration files or war contents causes a rather ungraceful redeployment of the Context and I would guess the Catalina web container waits for some specified time, before killing all the outstanding threads and requests. It's not very transparent, and you end up serving horrible 500 errors until the app is back on its feet :-(
Hence to allow the transparent end-user experience you are going to need to have 2 versions of your app running at the same time for a short period, one for the old connections and one for the new. (There are a number of caveats to these approaches which I will cover below...)
The simplest way, is to have a front-end load balancer such as apache, haproxy, or Cisco CSM with 2 or more tomcat instances - where the load balancer supports sticky sessions and hot load balancer configuration deployment.
eg tomcat1, tomcat2 and balancer
Notice that it is the change node preference level rather than, drop node will allow the load balancer to gracefully manage the transition of the connections to the new web app.
Obviously if you only have 1 server, and hence only 1 tomcat, you can come up with something similar, but this requires some clever naming for your webapp. I have never had to deploy into production on 1 tomcat, but I would do it with 2 versions of my web app with different war names and doc paths installed on the same tomcat6 like so;
And make the change transparent by using apache mod_proxy or haproxy to migrate the connections between the 2 apps gracefully.
ie I would have apache httpd AND tomcat6 installed together on the same box, with httpd mod_proxy pointing like so;
Caveat, if you have to upgrade your data base schemas, then unless you want to start doing some crazy naming and linking sh*t with your databases like database_0_1 then, you are going to have to suck up some downtime.
If your users have really long sessions, then tomcat6 supports session clustering using a variety of backends
There is no such feature for Tomcat.
Remember that Tomcat is an application server and not a web server and it needs to load things upon start and perhaps shut down things nicely upon shutdown.