multiple webapps in tomcat -- what is the optimal architecture?
- by rvdb
I am maintaining a growing base of mainly Cocoon-2.1-based web applications [http://cocoon.apache.org/2.1/], deployed in a Tomcat servlet container [http://tomcat.apache.org/], and proxied with an Apache http server [http://httpd.apache.org/docs/2.2/]. I am conceptually struggling with the best way to deploy multiple web applications in Tomcat. Since I'm not a Java programmer and we don't have any sysadmin staff I have to figure out myself what is the most sensible way to do this. My setup has evolved through 2 scenarios and I'm considering a third for maximal separation of the distinct webapps.
[1] 1 Tomcat instance, 1 Cocoon instance, multiple webapps
-tomcat
|_ webapps
|_ webapp1
|_ webapp2
|_ webapp[n]
|_ WEB-INF (with Cocoon libs)
This was my first approach: just drop all web applications inside a single Cocoon webapps folder inside a single Tomcat container. This seemed to run fine, I did not encounter any memory issues.
However, this poses a maintainability drawback, as some Cocoon components are subject to updates, which often affect the webapp coding. Hence, updating Cocoon becomes unwieldy: since all webapps share the same pool of Cocoon components, updating one of them would require the code in all web applications to be updated simultaneously.
In order to isolate the web applications, I moved to the second scenario.
[2] 1 Tomcat instance, each webapp in its dedicated Cocoon environment
-tomcat
|_ webapps
|_ webapp1
| |_ WEB-INF (with Cocoon libs)
|_ webapp1
| |_ WEB-INF (with Cocoon libs)
|_ webapp[n]
|_ WEB-INF (with Cocoon libs)
This approach separates all webapps into their own Cocoon environment, run inside a single Tomcat container. In theory, this works fine: all webapps can be updated independently.
However, this soon results in PermGenSpace errors. It seemed that I could manage the problem by increasing memory allocation for Tomcat, but I realise this isn't a structural solution, and that overloading a single Tomcat in this way is prone to future memory errors.
This set me thinking about the third scenario.
[3] multiple Tomcat instances, each with a single webapp in its dedicated Cocoon environment
-tomcat
|_ webapps
|_ webapp1
|_ WEB-INF (with Cocoon libs)
-tomcat
|_ webapps
|_ webapp2
|_ WEB-INF (with Cocoon libs)
-tomcat
|_ webapps
|_ webapp[n]
|_ WEB-INF (with Cocoon libs)
I haven't tried this approach, but am thinking of the $CATALINA_BASE variable. A single Tomcat distribution can be multiply instanciated with different $CATALINA_BASE environments, each pointing to a Cocoon instance with its own webapp. I wonder whether such an approach could avoid the structural memory-related problems of approach [2], or will the same issues apply?
On the other hand, this approach would complicate management of the Apache http frontend, as it will require the AJP connectors of the different Tomcat instances to be listening at different ports. Hence, Apache's worker configuration has to be updated and reloaded whenever a new webapp (in its own Tomcat instance) is added. And there seems no way to reload worker.properties without restarting the entire Apache http server.
Is there perhaps another / more dynamic way of 'modularizing' multiple Tomcat-served webapps, or can one of these scenarios be refined?
Any thoughts, suggestions, advice much appreciated.
Ron