Recently, one of our Managed Services customers in the e-commerce sector undertook a new project which required scaling up their existing Tomcat infrastructure.
Because we provide fully managed middleware support for their application deployment, and have an in-depth knowledge of their systems and business processes, we were able to bring in our consultancy team to design and deliver a roadmap for an AWS cloud migration.
When I was talking with their in-house team about some of the issues, one of the developers asked about creating multiple Tomcat instances. It struck me as a useful topic to explore, and gave me the idea to write a short walk-through for anyone who might be looking at deploying multiple Tomcat instances.
Installing a single Tomcat instance is a simple and straightforward practise, but things become a little more complex if you want to isolate different Tomcat applications on several dedicated instances.
In theory, you can just keep duplicating the Tomcat files, but the more instances you have, the more the effort required to maintain several parallel installations increases.
So, let’s see how to do it in a more efficient way!
The software I used in this scenario was:
- Apache Tomcat (8.5.16)
Let’s start from a standard Tomcat installation, and take the Tomcat binaries (or the sources) from the Tomcat website: https://tomcat.apache.org/download-80.cgi
Also we need a JDK, I’m using Tomcat 8.5, so any jdk version from and including 7 is fine. If you're using a different version, then just check that it's supported by your installation here: http://tomcat.apache.org/whichversion.html
When you copy Tomcat and jdk to your server, and decompress the packages, you should see something like this:
[tomcat@centos1 tomcat]$ pwd /opt/tomcat [tomcat@centos1 tomcat]$ ls -ltr total 188152 drwxr-xr-x. 5 tomcat 1001 112 Jul 21 15:28 apache-tomcat-8.5.16 drwxr-xr-x. 8 tomcat 1001 255 Dec 13 2016 jdk1.8.0_121
Now, the apache-tomcat-8.5.16 folder contains a fully working Tomcat server.
We will keep this folder as a location for our binaries (CATALINA_HOME) while we will create a folder for each tomcat instance we need (CATALINA_BASE), and inside each instance folder we will need to create the following directories:
If everything is correct, you should have a structure like the one below:
[root@centos1 instances]# pwd /opt/tomcat/instances [root@centos1 instances]# tree . ├── tomcat1 │ ├── bin │ ├── conf │ │ └── Catalina │ │ └── localhost │ ├── logs │ ├── temp │ ├── webapps │ └── work └── tomcat2 ├── bin ├── conf │ └── Catalina │ └── localhost ├── logs ├── temp ├── webapps └── work 18 directories, 0 files
Now, copy the content of the conf folder and the webapps folder from CATALINA_HOME to your instances folders:
cp -pr /opt/tomcat/apache-tomcat-8.5.16/conf /opt/tomcat/instances/tomcat1/ cp -pr /opt/tomcat/apache-tomcat-8.5.16/webapps /opt/tomcat/instances/tomcat1/ cp -pr /opt/tomcat/apache-tomcat-8.5.16/conf /opt/tomcat/instances/tomcat2/ cp -pr /opt/tomcat/apache-tomcat-8.5.16/webapps /opt/tomcat/instances/tomcat2/
And also copy the $CATALINA_HOME/bin/catalina.sh, $CATALINA_HOME/bin/shutdown.sh and $CATALINA_HOME/bin/startup.sh to the bin folder of your CATALINA_BASE folders:
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/catalina.sh /opt/tomcat/instances/tomcat1/bin cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/startup.sh /opt/tomcat/instances/tomcat1/bin cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/shutdown.sh /opt/tomcat/instances/tomcat1/bin cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/catalina.sh /opt/tomcat/instances/tomcat2/bin cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/startup.sh /opt/tomcat/instances/tomcat2/bin cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/shutdown.sh /opt/tomcat/instances/tomcat2/bin
To finish the set-up, all you now need to do is create a new file (setenv.sh) inside the bin folder of each CATALINA_BASE folder, using the following content:
JAVA_HOME=/opt/tomcat/jdk1.8.0_121 CATALINA_HOME=/opt/tomcat/apache-tomcat-8.5.16 CATALINA_BASE=/opt/tomcat/instances/tomcat1
Remember to change the CATALINA_BASE accordingly!
Technically, the structure is now complete, but if we try to start two instances together, we will find an error with the second, because we didn't change the listening port of the second instance!
Let’s edit the $CATALINA_BASE/conf/server.xml and change the port value of each active connector you have in your configuration, and the shutdown port. In this case this is the diff between the server.xml files of two different instances:
[root@centos1 conf]# diff server.xml ../../tomcat1/conf/server.xml 22c22 < <Server port="8006" shutdown="SHUTDOWN"> --- > <Server port="8005" shutdown="SHUTDOWN"> 69c69 < <Connector port="8081" protocol="HTTP/1.1" --- > <Connector port="8080" protocol="HTTP/1.1" 71c71 < redirectPort="8444" /> --- > redirectPort="8443" /> 116c116 < <Connector port="8010" protocol="AJP/1.3" redirectPort="8444" /> --- > <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
With this set up, we'd be able to spawn several instances each dedicated to a single or a group of applications. Now, updating one, some or all the instances becomes easier to manage, and is just a matter of updating the setenv.sh file to use the proper CATALINA_HOME for the binaries and libraries.
Of course, this is a simple scenario. In the real-world project, the next step would be to integrate the set-up with an automation tool such as Ansible, Chef or Puppet to provide reduce release times, manage workloads, and provide optimal control over infrastructure administration.
And, the great thing from a support perspective is that when a customer we work so closely with on business-as-usual activities is looking ahead to a new project, our knowledge of their business processes and systems means that we can work with our delivery team on their behalf.