Separate the Static from the Dynamic with Tomcat and Apache
Hosting multiple Java Web-enabled applications with Apache/SSL in combination with Tomcat is potentially highly detailed. Separating the dynamic from the static content requires URL rewriting and aliases. This article discusses one viable configuration.
I describe the basics of how to host multiple Java Web applications using a pure Apache project approach. In other words, I explain how to apply Apache, mod_ssl, some rewrite rules and the Tomcat Servlet container to gain control of a consistent and viable production environment. In real life, I am a more-than-a-little-busy developer, and one of my more-recent tasks was to define and implement a structure to host a complex database-intensive Web-enabled searchable publication mechanism through the life cycle. I condense the experience gained and explain the most relevant details here.
The basics of placing an Apache Web server in front of multiple Tomcat servers is explained in an article by Daniel McCarthy on the Linux Journal Web site (see Resources). I take this article somewhat further by adding the ability to provide secure communication via SSL and show how to optimize performance by separating dynamic content, such as JSP pages, from static content, such as HTML and images. Further security issues also are nodded at briefly.
The following preparations are for those who want to generate a working instance of the infrastructure mentioned. This infrastructure involves a locally configured Apache server running with two Tomcat instances, all being referenced from a Web browser via different loopback (127.0.0.x) addresses. This article is still worth reading without following through with the recipe.
I assume that the following have been installed: Apache 1.3x Web server, mod_ssl, mod_jk and two instances of a Tomcat 5.5.x server, one running the ajp1.3 connector on the standard port of 8009 and the shutdown port of 8005, and the other on port 8019 and 8015. I have chosen a plain-old stable and reliable Apache 1.3.x server over an Apache 2.x version on the principle that you shouldn't fix what isn't broken. At the Institutes for which I have been responsible, during the past few years they have run Apache 1.3.x without issue, the system administrators have built up their knowledge, and the systems are maintained and patched to the highest levels and snuggly sit in the maturity section of the Web server's life cycle. The same applies for the choice of mod_jk over mod_jk2. In fact, mod_jk2 development has been discontinued due to the complexity of configuration.
If you have a Debian-based Linux distribution, to install the Apache server without compiling, try the following:
sudo apt-get install apache sudo apt-get install libapache-mod-jk sudo apt-get install libapache-mod-ssl
You should now have a running Apache instance with the configuration files sitting under /etc/apache.
For the Tomcat servers, you have two choices. The first is to use one instance of the binary and then two instances of the configuration, and then run a startup script that applies the unique instance of the binary with different configurations. The second choice is to use two copies of the Tomcat server and modify the server.xml file. The advantage of the first approach is the avoidance of replication of executable code. However, this is nearly always a false economy. The second approach has advantages for complex environments where you want to host different versions of Tomcat servers. The second approach is more relevant for Application Service Providers that have multiple customers. A division exists between code that is written for Java 1.5 that runs natively in Tomcat 5.5 (without installing the 1.4 compatibility package) and Java 1.4 that runs in Tomcat 5. Furthermore, the Servlet implementation is more up to date the newer the Tomcat version. Due to the current velocity of change, software that is hosted for more than a year can be considered legacy, so there always will be a demand for the use of older but still reliable servers.
Next, we want to test only on the loopback addresses with no packets reaching the network. This can be achieved by modifying the /etc/hosts file to something similar to:
127.0.0.10 bronze_a 127.0.0.11 silver 127.0.0.12 gold
Therefore, every time you type https://bronze_a, no DNS lookups are necessary. The packets from the browser never will reach the Internet and will stay local to 127.0.0.10.
In the main Apache configuration file, httpd.conf, you will find an include line that tells Apache to look under the conf.d directory for further configuration. For example:
Every time a package is installed that requires configuration changes for Apache, you will find an extra configuration file within the conf.d directory. In fact, if you want (for a nice aside), try to install Drupal and read the Drupal.conf file that is dumped.
I want to keep our work separate from the rest of the world's. No doubt, we will generate mistakes during playtime. Add a second line to include a directory for our virtual hosting files:
Then, make the directories /etc/apache/ssl and /etc/apache/vhosts. Later, we will place our certificates and server keys in the SSL directory, one set per virtual host.
Next, check the httpd.conf file to see whether the SSL engine is turned on. I want to turn the engine off until enabled per virtual host. So, the line SSLEngine On should change to SSLEngine Off.
Now we have an Apache 1.3.x server that is ready for action.
If you have not set up your Tomcat servers yet, you need to modify the following lines under the tomcat_root/conf/server.xml file for the second instance. Change the port numbers to 8015 for the shutdown command and port 8019 for the AJP/1.3 connector:
<Server port="8005" shutdown="SHUTDOWN"> <Connector port="8080" <Connector port="8009" enableLookups="false" protocol="AJP/1.3" />
For the sake of security, change the shutdown attribute from the value SHUTDOWN to some randomly long string. Otherwise, perhaps on the worst day under a badly defended system, a cracker can Telnet in and type SHUTDOWN, and then your server is down. Also, I would comment out the 8080 connector. There is no need to expose Tomcat directly to the Internet.
Only one task is left—to create two Web applications. Under the webapps directory of the first Tomcat instance, create a bronze_a directory, and then under that directory, create a WEB-INF directory. Place the following web.xml file in WEB_INF:
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>BRONZE_A</display-name> <description> BRONZE_A Dynamic </description> <welcome-file-list> <welcome-file> index.jsp </welcome-file> </welcome-file-list> </web-app>
Notice the mention of web-app_2_4.xsd. This web.xml file will not work under Tomcat 5, which uses the 2.3 standard. Under the webapps/bronze_a directory, place the following index.jsp file. This is our poor yet relevant example of dynamic content:
<%String mess="Hello World from Bronze_a"; %> <%=mess%> <br><%=request.getRequestURI()%>
Follow the same procedure for the second instance, but replace the string bronze_a with silver under the webapps/silver directory of the second Tomcat instance.
|Dynamic DNS—an Object Lesson in Problem Solving||May 21, 2013|
|Using Salt Stack and Vagrant for Drupal Development||May 20, 2013|
|Making Linux and Android Get Along (It's Not as Hard as It Sounds)||May 16, 2013|
|Drupal Is a Framework: Why Everyone Needs to Understand This||May 15, 2013|
|Home, My Backup Data Center||May 13, 2013|
|Non-Linux FOSS: Seashore||May 10, 2013|
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- RSS Feeds
- A Topic for Discussion - Open Source Feature-Richness?
- Validate an E-Mail Address with PHP, the Right Way
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Readers' Choice Awards
- The Secret Password Is...
- All the articles you talked
1 hour 52 min ago
- All the articles you talked
1 hour 55 min ago
- All the articles you talked
1 hour 56 min ago
6 hours 21 min ago
- Keeping track of IP address
8 hours 12 min ago
- Roll your own dynamic dns
13 hours 25 min ago
- Please correct the URL for Salt Stack's web site
16 hours 37 min ago
- Android is Linux -- why no better inter-operation
18 hours 52 min ago
- Connecting Android device to desktop Linux via USB
19 hours 21 min ago
- Find new cell phone and tablet pc
20 hours 19 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi
It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?