Connecting Apache Web Server to Tomcat and writing re-direct rules

Introduction

In this article, we learn how to connect the Apache web server to the Tomcat server, and how to write re-direct rules. The key benefit of this is that it allows us to write re-direct rules in Apache to serve up static files directly, rather than having to go through Tomcat, which is less efficient and adds needless load.

This article assumes that you have already installed a Tomcat server somewhere. It doesn't go through how to install the Apache web server on a system, other than to point out a simple way to install it on Ubuntu systems.

Setting up the Apache web server on Ubuntu

This will vary from system to system. If you have Ubuntu, you can download it and install it like this, from the command line:

$ sudo apt-get install apache2

This will install Apache 2 to your environment. In a typical Ubuntu installation, the web root is in /var/www, and the configuration files are in /etc/apache2.

Enable the AJP Connector on Tomcat

You'll need to enable the AJP Connector in Tomcat, so that the Apache web server can redirect requests meant for JRS from Apache to Tomcat. You did by editing Tomcat's server.xml file, and making sure that the connector below is active and not commented out.

<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

You'll need to restart the Tomcat server for this change to take effect.

Installing and configuring mod_jk on Ubuntu

Mod_jk is an Apache web server module that allows the web server to interface with the Tomcat application server. Installing it and configuring it are the keys to getting the web server and the application server working together.

$ sudo apt-get install libapache2-mod-jk

Execute this command to activate the new configuration:

/etc/init.d/apache2 restart

Edit or create the /etc/apache2/workers.properties file:

# Define 1 real worker using ajp13
worker.list=worker1
# Set properties for worker1 (ajp13)
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009

Now reference this file in the /etc/apache2/apache2.conf by adding these lines:

JkWorkersFile /etc/apache2/workers.properties
# Where to put jk shared memory
# Update this path to match your local state directory or logs directory
JkShmFile /var/log/apache2/mod_jk.shm
# Where to put jk logs
# Update this path to match your logs directory location (put mod_jk.log next to access_log)
JkLogFile /var/log/apache2/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the timestamp log format
JkLogStampFormat
"[ %a %b %d %H:%M:%S %Y ] "

Troubleshooting

When restarting the Apache web server, it's possible that you may get a JkWorkersFile only allowed once error message after making that last modification to apache.conf; that's because the workers file has been defined elsewhere.

If that happens, you can check the mods-available directory for the jk.conf file, which will contain an entry to the JkWorkersFile directive. The directive will specify where workers.properties file is located, and you can edit it to either add your own worker configuration to it, or, what is more likely, to use a worker that's already defined there that takes care of the AJP connector.

In that case, all you have to do if undo the changes you made to the apache2.conf file, and reference the worker in the 000-default file. That step is covered in the next section.

Configure which URLs to manage with Apache

At this point, you'll need to configure Apache to tell it which URLs to process and hand off to Tomcat, and which URLs you want Apache itself to process. For both cases, you'll need to modify /etc/apache2/sites-enabled/000-default. You can add entries right below the "DocumentRoot" line, within the VirtualHost settings. Add the following line under the DocumentRoot entry. This makes it so that you can request JRS via the Apache web server.

JkMount /jasperserver-pro* worker1

Save the file, and restart the apache service (/etc/init.d/apache2 restart). If you now go to http://localhost/jasperserver-pro, you should see the normal JasperReports Server login screen. What you have accomplished so far is to put the Apache web server in front of Tomcat.

Add the JkUnMount directive

So far so good, but we still need a better of dealing with static files. The modification so far passes every single JRS request from Apache to Tomcat, including requests for static files. We want Apache to serve up static files and not have Tomcat do it.

Apache is much better suited for serving up static files than Tomcat, and by taking this approach we lighten Tomcat's load. Tomcat can now concentrate on serving up dynamic application content.

The steps for putting this in place are:

  • Copying over the static files from the web application to the Apache web server root
  • Add "JkUnMount" entries that intercept these incoming requests
  • Restart the Apache web server.

The example I did deals with the "scripts" folder containing JavaScript files. I followed these steps:

  • I created the /var/www/jasperserver-pro folder
  • I copied over scripts folder from the JRS web application to the above directory.
  • I added the "JkUnMount" entry below, right under the JkMount entry I had added before:

JkUnMount /jasperserver-pro/scripts* worker1

You can repeat this process as many items as you want; all you need to do is create additional "JkUnMount" entries to the /etc/apache2/sites-enabled/000-default file. After you're done, you'll need to re-start Apache by running this command:

/etc/init.d/apache2 restart

How to verify that it's working

A simple way of verifying that the configuration is working is to request one of the files that Apache should serve up and then verify the logs - it should show up in Apache's logs, and not in the Tomcat logs.

For example, request this file with the browser:

http://localhost/jasperserver-pro/scripts/resource.base.js

We had previously added a "JkUnMount" entry for the scripts folder, and we had also copied the scripts folder to Apache's web root (/var/www). So when we look at the logs, this request should show up in Apache's log files (somewhere like /var/logs/apache2/access.log, as defined in the apache2.conf file).

You can also verify the Tomcat logs, and you will see that the file request wasn't processed by Tomcat.

 

Feedback