Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently deploy multiple instances of same WAR ( different contexts, same container )

I have one WAR ( app.war ) and one container ( Tomcat, Jetty, Glassfish, whatever ). My goal is to deploy, on demand, hundreds of instances of this same web application on the container.

http://foo/app1 --> app.war
http://foo/app2 --> app.war
http://foo/app3 --> app.war 
...
http://foo/appN --> app.war

Some obvious ways of achieving this:

  • In Tomcat, create one context.xml file for each app ( named appN.xml ), all pointing to the same WAR. Other containers have similar methods
    • Problem with this approach: It will explode the WAR N times, taking up a lot of disk space
  • Use symbolic links to create webapp/{app1,app2,appN} folders pointing to an exploded version of app.war. This prevents the disk space explosion, but the JVM is still loading many duplicate JARs to memory
  • Use some shared lib folder to contain most jars ( and a combination of the previous two options ).

I wonder if there is a better method to do this. Ideally, creating a new instance should not take up ANY more disk space ( other than marginal configuration files ) and only take up memory related to thread execution stacks and other runtime allocations.

Any ideas?

like image 975
Aldo Bucchi Avatar asked Apr 16 '12 23:04

Aldo Bucchi


3 Answers

Jetty added support for what you looking for a while back with what are called overlays.

http://wiki.eclipse.org/Jetty/Tutorial/Configuring_the_Jetty_Overlay_Deployer

Copying a bit from the wiki page:

  • You can keep the WAR file immutable, even signed, so that it is clear which version you have deployed.
  • All modifications you make to customise/configure the web application are separate WARs, and thus are easily identifiable for review and migration to new versions.
  • You can create a parameterised template overlay that contains common customisations and configuration that apply to many instances of the web application (for example, for multi-tenant deployment).
  • Because the layered deployment clearly identifies the common and instance specific components, Jetty is able to share classloaders and static resource caches for the template, greatly reducing the memory footprint of multiple instances.
like image 148
jesse mcconnell Avatar answered Oct 09 '22 11:10

jesse mcconnell


Apologies for being a little bit off-topic, but in my view, your scenario shouts "multi-tenancy" application, so that you've got a single application which will service multiple "tenants" (customers).

With regard to multi-tenancy setups, the following considerations would have to be considered:

  • Customers cannot access each other's data (if they the data is stored in the same database, same schema and using "discriminator" fields to separate the data). This could be achieved by using Spring Security with Access Control Lists
  • Hibernate has built-in support for multitenancy apps from version 4.0.
  • These two SO questions may be useful as well
    • Multiple Entity Manager issue in Spring when using more than one datasource (for using different data sources (different databases or just different schemas on the same database per customer).
    • Multi tenancy support in Java EE 6

Benefits of multitenancy:

  • Shared code means that a bug fixed for one customer is fixed for all (this can be a disadvantage as well if different customers have different views on what constitutes a bug and what constitutes a feature).
  • Clustered deployment can share the load between customers (however, need to ensure that peak capacity is available for all customerS).

Downsides:

  • Code is going to be a bit more complex as queries need to ensure that the "discrimination" between customers works without accidentially exposing customers to each others data.
like image 26
beny23 Avatar answered Oct 09 '22 12:10

beny23


You could configure Apache on the front end (mod_proxy/mod_proxy_ajp) to point named virtual hosts to a single WAR deployed on Tomcat. Your application should be designed/written in a way to service all request -- per website name specific configuration could be stored in a database or as a configuration file within your application -- your app would just need to probe the user's requesting domain name to ensure the correct settings are applied (once per session). Generally speaking, you should be able to solve this with one application. Great developers are LAZY.

like image 1
Jason Grant Taylor Avatar answered Oct 09 '22 11:10

Jason Grant Taylor