3

Every time I copy OpenGrok/dist/source.war to /var/tomcat/webapps/, the tomcat generates blank error pages with 404 Not Found errors to my users, during a couple of seconds immediately after such copying.

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Tue, 02 Apr 2013 19:00:14 GMT
Connection: close

This is not acceptable. Am I not deploying correctly, by manually copying a .war file into a tomcat directory, or is it an OpenGrok bug of some sort? How do I ensure there's not a single visitor that'd be getting an undue 404 during the deployment process?

cnst
  • 25,870
  • 6
  • 90
  • 122
  • If you need a 100% uptime you may want to look into a loadbalancer and at least 2 tomcat nodes. Then you can update one while the other handles the requests, and after the first is updated correctly you can switch to it and update the second one. – Leonard Brünings Apr 02 '13 at 19:33
  • @LeonardBrünings, you have to be kidding me! I'm obviously not looking for 100% uptime, but I didn't know that tomcat is a amateur-hour solution that requires a disgraced multi-second downtime with normal use. I'd be very happy to ditch tomcat7, if this is indeed the only way around this; recommendations of decent alternatives are very welcome (I only use tomcat to run OpenGrok). – cnst Apr 02 '13 at 19:53
  • do you have unpackWars set to true? How large is your application, do you perform expensive startup actions? – Leonard Brünings Apr 02 '13 at 19:58
  • @LeonardBrünings, I'm using the defaults; the `.war` files do get unpacked automatically, so, most likely unpackWars is indeed set to true. OpenGrok is not that big -- my `.war` is about 4MB, and it's on a dedicated server. I'm not aware of any specific expensive startup actions (but then I didn't actually write OpenGrok). My OpenGrok instance does have a couple of medium-sized Lucene index files, totalling 1.1GB, but those aren't supposed to be loaded during the startup (else, it wouldn't be taking only a couple of seconds anyways). – cnst Apr 02 '13 at 20:09
  • Then try setting unpackWars to false in your tomcat config https://tomcat.apache.org/tomcat-7.0-doc/config/context.html#Standard_Implementation this should at least reduce your downtime. Furthermore I would suggest looking at the logs to determine the startup behavior of your app. – Leonard Brünings Apr 02 '13 at 20:29
  • @LeonardBrünings, from your words, that doesn't sound like a solution; I want no downtime at all when some minor change is made to a .war; are other Java servlet servers likewise affected? – cnst Apr 02 '13 at 20:36
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/27432/discussion-between-leonard-brunings-and-cnst) – Leonard Brünings Apr 02 '13 at 20:44

1 Answers1

1

Tomcat 7 has a feature called parallel deployments. Using this feature it is possible to have multiple instances of your app running under the same context path.

This blog post explains it nicely: http://www.javacodegeeks.com/2011/06/zero-downtime-deployment-and-rollback.html

To sum it up you need to manually version your wars when you add them to your appBase.

cp foo##001.war apache-tomcat-7/webapps/
cp foo##002.war apache-tomcat-7/webapps/

You may want to set undeployOldVersions and autoDeploy to true so that tomcat automatically deploys the app and removes the old version if it is no longer necessary. Check https://tomcat.apache.org/tomcat-7.0-doc/config/host.html for further info on tomcat's config.

The Version after the ## must be string comparable, so you can use e.g. a build number from your CI System but you may have to zero pad it.

There are a few things to look out for:

  • External resources need to be shareable, if you are using a database but your new versions needs a new schema you'll run into problems. Or if you open a TCP listener on a specific port it is also not shareable.
  • Caches, if your application uses internal caches they should be write through and expire quickly
  • The app must be undeployable
Leonard Brünings
  • 12,408
  • 1
  • 46
  • 66
  • opengrok does open a listening TCP socket, for configuration updates. so, your answer is non-conclusive in regards to how it applies to opengrok. – cnst Apr 02 '13 at 21:29