Connect Apache Tomcat and Apache HTTP using mod_jk

In this tutorial we will explain how to configure an Apache HTTP server in front of the Apache Tomcat server.  Why would one need such a configuration:

  • Clustering. By using Apache HTTP as a front end you can let Apache HTTP act as a front door to your content to multiple Apache Tomcat instances.
  • Security. An additional security level is added to the applications running on Apache Tomcat. When used in a clustered environment, this configuration can simplify the security management for multiple Apache Tomcat instances.
  • Performance. It is efficient to server the static content using the Apache HTTP server and the dynamic content using the Apache Tomcat server.

The solution involves the usage of the Apache HTTP mod_jk connector. This way the Apache HTTP can forward certain requests to one or more Apache Tomcat server instances or workers.

The following installation was tested on an Ubuntu Server 12.04, using Apache Tomcat 6 and Apache HTTP 2.22. Both application servers are running on the same machine. You can find below the deployment diagram.

Deployment Diagram

Deployment Diagram

Configuration needed for the Apache Tomcat server

Edit the configuration file for the server:

sudo nano /etc/tomcat6/server.xml

We need to enabled the AJP Connector of the server. Make sure the following line is uncommented:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

Optionally you can configure the Apache Tomcat to be available only for localhost requests. Set the address property of the connector tag to the value “127.0.0.1”, for the HTTP and AJP connectors.

<Connector port="8080" protocol="HTTP/1.1" address="127.0.0.1" redirectPort="8443" />
...
<Connector port="8009" protocol="AJP/1.3" address="127.0.0.1" redirectPort="8443" />

We need to restart the Apache Tomcat server

service tomcat6 restart

Configuration needed for the Apache HTTP server

Install mod_jk for the Apache HTTP server on Ubuntu server using this command:

sudo apt-get install libapache2-mod-jk

What this command does is the followings:

  • installs and enables the mod_jk module for the Apache HTTP server
  • creates a default configuration file for the mod_jk module at /etc/apache2/mods-enabled/jk.conf
  • creates a default workers properties file at /etc/libapache2-mod-jk/workers.properties. This file contains a default worker definition named “ajp13_worker”

We can do the rest of the configuration either using the default files created during the installation of the module or using custom files.

Configuration using the default files

We need to tell the Apache HTTP server which URLs to map to the Apache Tomcat server. For that we edit the configuration file for Apache HTTP server –  /etc/apache2/sites-available/default

sudo nano /etc/apache2/sites-available/default

Map an URL to a Apache Tomcat worker by using JkMount directive in this file. In the following example we will map a sample Java Web App which has the context root “MyJavaApp”,  to  “ajp13_worker”. This is the default worker defined in workers.properties file.

<VirtualHost *:80>
        ...
        DocumentRoot /var/www
        JkMount /MyJavaApp/* ajp13_worker
        ...
</VirtualHost>

Edit the configuration file for the mod_jk:

sudo nano /etc/apache2/mods-enabled/jk.conf

Comment the sections related to jk-manager and jk-status:

    ... 
    # Configure access to jk-status and jk-manager
    # If you want to make this available in a virtual host,
    # either move this block into the virtual host
    # or copy it logically there by including "JkMountCopy On"
    # in the virtual host.
    # Add an appropriate authentication method here!
    # <Location /jk-status>
    #   # Inside Location we can omit the URL in JkMount
    #   JkMount jk-status
    #   Order deny,allow
    #   Deny from all
    #   Allow from 127.0.0.1
    # </Location>
    # <Location /jk-manager>
    #   # Inside Location we can omit the URL in JkMount
    #   JkMount jk-manager
    #   Order deny,allow
    #   Deny from all
    #   Allow from 127.0.0.1
    #</Location>
    ...

We need to restart the Apache HTTP server

service apache2 restart

Configuration using custom files

We start by creating a custom workers.properties file.

sudo nano /etc/apache2/workers.properties

Define a worker in this file by specifying the name of the worker, type, host and port. The host and port must match the ones configured for the Apache Tomcat server.

# Define a worker
worker.list=my_worker
worker.my_worker.type=ajp13
worker.my_worker.host=localhost
worker.my_worker.port=8009

Configure the mod_jk module to point to the new workers.properties file – in this example /etc/apache2/workers.properties. For that, edit the configuration file jk.conf:

sudo nano /etc/apache2/mods-enabled/jk.conf

Set the location of the workers file using JkWorkersFile property:

<IfModule jk_module>

    # We need a workers file exactly once
    # and in the global server
    JkWorkersFile /etc/apache2/workers.properties       
    ...

</IfModule>

We need to tell the Apache HTTP server which URLs to map to the Apache Tomcat server. For that we edit the configuration file for Apache HTTP server –  /etc/apache2/sites-available/default

sudo nano /etc/apache2/sites-available/default

As an example, we will map a sample Java Web App which has the context root “MyJavaApp”, to the worker defined earlier “my_worker”.

<VirtualHost *:80>
        ...
        DocumentRoot /var/www
        JkMount /MyJavaApp/* my_worker
        ...
</VirtualHost>

Restart the Apache HTTP server

service apache2 restart

Testing the configuration

You can test the new configuration by accessing http://myhost/MyJavaApp

Glossary:

Tomcat Worker – A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server.

References:

http://tomcat.apache.org/connectors-doc/reference/workers.html

http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html

http://wiki.apache.org/tomcat/FAQ/Connectors#Q3

Add a Comment

Your email address will not be published. Required fields are marked *