How to configure mod_jk with Apache http and Tomcat servers

Introduction

We will see here how to configure mod_jk with Apache http and Tomcat servers. The Apache Tomcat connector allows to use the Apache httpd server as a front-end for Apache Tomcat applications.

To run Tomcat and Apache together, Apache needs to load a “adapter” module, which uses a certain protocol, such as Apache JServ Protocol (AJP), to communicate with the Tomcat, via another TCP port (port 8009 is the default configuration in server.xml file under Tomcat server). When Apache server receives an HTTP request, it checks if the request belongs to Tomcat server and if so, forwards it to Tomcat.

AJP is a wire protocol and an optimized version of the HTTP protocol, which allows a standalone http server, such as, Apache to talk to Tomcat. Over the years, Apache http server has been much faster than Tomcat at serving static content. The idea is here to let Apache http server serve the static contents whenever possible, but use Apache http server as a proxy to the Tomcat server for Tomcat related contents.

Why use mod_jk instead of mod_proxy?

mod_jk is mature, stable and extremely flexible. mod_proxy_ajp is distributed with Apache httpd 2.2 or later and the communication protocol used is AJP.
mod_proxy_http is a cheap way to proxy without configuring JK and the communication protocol used is HTTP. It is an alternative to mod_jk if you do not need some of the features of mod_jk.

Why integrate Apache with Tomcat?

Here could be some of the features for which you can use Apache in front of Tomcat server. Please read the same here at https://wiki.apache.org/tomcat/FAQ/Connectors#Q3

Clustering: By using Apache as a front end you can let Apache act as a front door to your content to multiple Tomcat instances. If one of your Tomcats fails, Apache ignores it and your Sysadmin can sleep through the night. This point could be ignored if you use a hardware loadbalancer and Tomcat’s clustering capabilities.

Clustering/Security: You can also use Apache as a front door to different Tomcats for different URL namespaces (/app1/, /app2/, /app3/, or virtual hosts). The Tomcats can then be each in a protected area and from a security point of view, you only need to worry about the Apache server. Essentially, Apache becomes a smart proxy server.

Security: This topic can sway one either way. Java has the security manager while Apache has a larger mindshare and more tricks with respect to security. I won’t go into this in more detail, but let Google be your friend. Depending on your scenario, one might be better than the other. But also keep in mind, if you run Apache with Tomcat – you have two systems to defend, not one.

Add-ons: Adding on CGI, perl, PHP is very natural to Apache. Its slower and more of a kludge for Tomcat. Apache also has hundreds of modules that can be plugged in at will. Tomcat can have this ability, but the code hasn’t been written yet.
Decorators! With Apache in front of Tomcat, you can perform any number of decorators that Tomcat doesn’t support or doesn’t have the immediate code support. For example, mod_headers, mod_rewrite, and mod_alias could be written for Tomcat, but why reinvent the wheel when Apache has done it so well?

Speed: Apache is faster at serving static content than Tomcat. But unless you have a high traffic site, this point is useless. But in some scenarios, tomcat can be faster than Apache httpd. So benchmark YOUR site. Tomcat can perform at httpd speeds when using the proper connector (APR with sendFile enabled). Speed should not be considered a factor when choosing between Apache httpd and Tomcat

Socket handling/system stability: Apache has better socket handling with respect to error conditions than Tomcat. The main reason is Tomcat must perform all its socket handling via the JVM which needs to be cross platform. The problem is socket optimization is a platform specific ordeal. Most of the time the java code is fine, but when you are also bombarded with dropped connections, invalid packets, invalid requests from invalid IP’s, Apache does a better job at dropping these error conditions than JVM based program.

Prerequisites

Windows 64 bit

Apache http server 2.4

Tomcat 8.5.39

Apache Tomcat Connector – tomcat-connectors-1.2.40-windows-x86_64-httpd-2.4.x.zip (https://archive.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/windows/)

Configuration Steps with Source Code

Step 1. Install Apache http server. Here my installation home directory of Apache is C:\Apache24.

Step 2. Install Tomcat server. Here my installation home directory for Tomcat is C:\apache-tomcat-8.5.39.

Step 3. Now extract the downloaded Apache Tomcat connector (mentioned in Prerequisites section) and copy the mod_jk.so file into C:\Apache24\modules. If the file name is not mod_jk.so then you can rename it to mod_jk.so. The image is shown below for your reference:

configure mod_jk with apache http and tomcat servers

Step 4. Configure the Apache HTTP Server to load and initialize the JK module. Create a configuration file called mod_jk.conf as follows and place it in C:\apache-tomcat-8.5.39\conf:

configure mod_jk with apache http and tomcat servers
# Load mod_jk module
LoadModule jk_module C:/Apache24/modules/mod_jk.so
# workers.properties
JkWorkersFile C:/apache-tomcat-8.5.39/conf/workers.properties
# put jk logs
JkLogFile C:/apache-tomcat-8.5.39/logs/mod_jk.log
# Set the jk log level [debug/error/info]
JkLogLevel info
# Select the log format
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
JkRequestLogFormat "%w %V %T"
# Send everything for context /web-app-global-exceptions to worker ajp13
JkMount /web-app-global-exceptions ajp13
JkMount /web-app-global-exceptions/* ajp13 

We used JKMount statement for web context (/web-app-global-exceptions) that is to be forwarded from Apache to Tomcat. In the above configuration, Apache forwards all requests to web contexts /web-app-global-exceptions to Tomcat, via a “worker” called “ajp13”. If you need more web contexts to be forwarded from Apache to Tomcat then you can write similar JKMount statement as shown above.

Note: Unix’s forward slash is used as the directory separator instead of backward slash.

Step 5. In order to let Apache http server know about the above configuration file, include the above mod_jk.conf file into Apache’s httpd.conf file. At the end of the httpd.conf file add the following line.

Step 6. It is observed that the above configuration file refers to a worker file called workers.properties, and forward certain requests to a JK worker called ajp13. So create workers.properties file under C:\apache-tomcat-8.5.39\conf as follows:

configure mod_jk with apache http and tomcat servers
# Define 1 real worker named ajp13
worker.list=ajp13
# Set properties for worker named ajp13 to use ajp13 protocol,
# and run on port 8009
worker.ajp13.type=ajp13
worker.ajp13.host=localhost
worker.ajp13.port=8009
worker.ajp13.lbfactor=50
worker.ajp13.cachesize=10
worker.ajp13.cache_timeout=600
worker.ajp13.socket_keepalive=1
worker.ajp13.socket_timeout=300

Step 7. make sure your AJP protocol 8009 is not commented out in server.xml file:

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

Step 8. Make sure you run the command prompt in Administrator mode (type cmd in Run from Start menu and right-click->run as Administrator).

Then navigate to C:Apache24\bin in command prompt and type the command httpd.exe -k install to install the JK module. Then type the command httpd.exe -k start or simply type httpd.exe into command prompt to start the Apache server.

Then confirm that JK module was started successfully by looking at the log file (C:\Apache24\logs\error.log) for the similar message as shown below:

Apache/2.4.25 (Win64) PHP/7.0.15 mod_jk/1.2.40 configured -- resuming normal operations

Step 9. Start the tomcat server. Observe that AJP1.3 service is initiated and the ajp13 worker is listening at port 8009. Make sure you put your application under tomcat installation webapps directory:

configure mod_jk with apache http and tomcat servers

The sample application can be found here https://roytuts.com/global-exception-configuration-using-web-xml-servlet-and-jsp/

You can also download the source code without going through above tutorial directly from here.

Step 10. Verify the installation. Hit the URL http://localhost/web-app-global-exceptions instead of
http://localhost:8080/web-app-global-exceptions in the browser. You will see the following output in the browser.

configure mod_jk with apache http and tomcat servers

We know that Apache http server uses port 80 as a default port, so we don’t need to put any port while we type the URL(
http://localhost/web-app-global-exceptions) but if you use some other port then you must type port in the URL to access the application.

Thanks for reading.

5 thoughts on “How to configure mod_jk with Apache http and Tomcat servers

  1. Error :
    httpd.exe: Syntax error on line 537 of C:/Apache24/conf/httpd.conf: Include takes one argument, Name(s) of the config file(s) to be included; fails if the wildcard does not match at least one file

    1. When ever including module, if there is spaces in between the module name. This error arises. Put the module name inside double quotes to fix it.

Leave a Reply

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