title: “mod_jk”
date: 2016-02-24T19:20:43
slug: mod_jk
nstalling mod_jk on apache httpd in CentOS 6.x/7.x
CentOS again. Today I’m going to show you how to install and configure mod_jk in apache httpd using a server with CentOS. Currently this tutorial was tested on Centos 6.x and 7.x so you should run out of troubles if you stick with one of those versions.
Introduction
So, what’s mod_jk? mod_jk is an apache httpd module used to make apache tomcat applications interact with a httpd server. In simple words, mod_jk allows us to connect an instance of tomcat with the apache httpd web server. This is useful for example if you have your httpd serving different kind of webapps (php, RoR, etc) and you want to publish a java app running on a tomcat instance. In this case, httpd run in port 80 and tomcat (usually) in port 8080, so we need to connect somehow the tomcat instance with httpd so our users can interact with our java app directly from port 80. In this case, the httpd server is giving us access to for example an internal network where your tomcat instances live. See the next diagram for a visual explanation:
Why not use mod_proxy?
This is indeed a good question. From a stackoverflow question/answer:
mod_proxy:
-
Pros:
-
No need for a separate module compilation and maintenance. mod_proxy, mod_proxy_http, mod_proxy_ajp and mod_proxy_balancer comes as part of standar Apache 2.2+ distribution.
-
Ability to use http/https or AJP protocols, even with the same balancer.
-
Cons:
-
mod_proxy_ajp does not support larke 8k+ packet sizes.
-
Basic load balancer.
-
Does not support Domain model clustering.
mod_jk:
-
Pros:
-
Advanced load balancer.
-
Advanced node failure detection.
-
Support for large AJP packet sizes.
-
Cons:
-
Need to build and mantain a separate module.
So, the discussion is there, no final answer. A good article covering this topic is: “Deciding between mod_jk, mod_proxy_http and mod_proxy_ajp” from Tomcat Experts.
Installation
The installation process for mod_jk is really simple but we’re going to need to compile the module first. Before doing any compile work, ensure you have both httpd and tomcat installed. Now:
yum install httpd-devel apr apr-devel apr-util apr-util-devel gcc gcc-c++ make autoconf libtool
| | |
| — | — |
|
1
|
yum install httpd-devel apr apr-devel apr-util apr-util-devel gcc gcc-c++ make autoconf libtool
|
Now, go to the official mod_jk website and download the latest version: http://tomcat.apache.org/download-connectors.cgi (1.2.41 at the published date of the post):
mkdir -p /opt/mod_jk/
cd /opt/mod_jk
wget http://www.eu.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.41-src.tar.gz
tar -xvzf tomcat-connectors-1.2.41-src.tar.gz
cd tomcat-connectors-1.2.41-src/native
| | |
| — | — |
|
1
2
3
4
5
|
mkdir -p /opt/mod_jk/
cd /opt/mod_jk
wget http://www.eu.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.41-src.tar.gz
tar -xvzf tomcat-connectors-1.2.41-src.tar.gz
cd tomcat-connectors-1.2.41-src/native
|
In the native folder (check the last step in the code above) we’re going to configure-make-make install the connector:
./configure –with-apxs=/usr/sbin/apxs
make
libtool –finish /usr/lib64/httpd/modules
make install
| | |
| — | — |
|
1
2
3
4
|
./configure –with-apxs=/usr/sbin/apxs
make
libtool –finish /usr/lib64/httpd/modules
make install
|
If all goes well you’re going to have the mod_jk.so installed on your /etc/httpd/modules folder.
Configuration
First, lets enable the AJP connection on your tomcat server, in your server.xml configuration file:
vim $TOMCAT_HOME/conf/server.xml
| | |
| — | — |
|
1
|
vim $TOMCAT_HOME/conf/server.xml
|
Add under the
<!– Define an AJP 1.3 Connector on port 8009 –>
| | |
| — | — |
|
1
2
|
<!– Define an AJP 1.3 Connector on port 8009 –>
|
And modify the Engine tag so its looks like:
| | |
| — | — |
|
1
|
|
Observation 1: for each tomcat instance linked to your httpd server, you need to define a different jvmRoute parameter. For example, for a second instance you could use:
| | |
| — | — |
|
1
|
|
Now, lets go with the httpd configuration. First, create a mod_jk.conf file in your conf.d folder:
vim /etc/httpd/conf.d/mod_jk.conf
| | |
| — | — |
|
1
|
vim /etc/httpd/conf.d/mod_jk.conf
|
And populate the file with the following:
LoadModule jk_module “/etc/httpd/modules/mod_jk.so”
JkWorkersFile /etc/httpd/conf/workers.properties
Where to put jk shared memory
JkShmFile /var/run/httpd/mod_jk.shm
Where to put jk logs
JkLogFile /var/log/httpd/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] “
JkRequestLogFormat “%w %V %T”
JkEnvVar SSL_CLIENT_V_START worker1
| | |
| — | — |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
LoadModule jk_module “/etc/httpd/modules/mod_jk.so”
JkWorkersFile /etc/httpd/conf/workers.properties
# Where to put jk shared memory
JkShmFile /var/run/httpd/mod_jk.shm
# Where to put jk logs
JkLogFile /var/log/httpd/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] “
#JkRequestLogFormat “%w %V %T”
#JkEnvVar SSL_CLIENT_V_START worker1
|
Before continuing, create the folder to store the shared memory of the module:
mkdir -p /var/run/mod_jk
chown apache:apache /var/run/mod_jk
| | |
| — | — |
|
1
2
|
mkdir -p /var/run/mod_jk
chown apache:apache /var/run/mod_jk
|
Now, create the workers.properties file: (look at the JkWorkersFile property on mod_jk.conf file):
vim /etc/httpd/conf/worker.properties
| | |
| — | — |
|
1
|
vim /etc/httpd/conf/worker.properties
|
With the next content:
workers.apache_log=/var/log/httpd
worker.list=app1Worker
worker.stat1.type=status
worker.app1Worker.type=ajp13
worker.app1Worker.host=app1.myhost.com #put your app host here
worker.app1Worker.port=8009
| | |
| — | — |
|
1
2
3
4
5
6
7
|
workers.apache_log=/var/log/httpd
worker.list=app1Worker
worker.stat1.type=status
worker.app1Worker.type=ajp13
worker.app1Worker.host=app1.myhost.com #put your app host here
worker.app1Worker.port=8009
|
For every app server from tomcat to httpd you’re going to have a specific worker. Don’t forget to define the worker first in the worker.list property. For example, lets assume we’re going to add another app from tomcat:
workers.apache_log=/var/log/httpd
worker.list=app1Worker,app2Worker
worker.stat1.type=status
worker.app1Worker.type=ajp13
worker.app1Worker.host=app1.myhost.com #put your app host here
worker.app1Worker.port=8009
worker.app2Worker.type=ajp13
worker.app2Worker.host=app2.myhost.com #put your app host here
worker.app2Worker.port=8009
| | |
| — | — |
|
1
2
3
4
5
6
7
8
9
10
11
|
workers.apache_log=/var/log/httpd
worker.list=app1Worker,app2Worker
worker.stat1.type=status
worker.app1Worker.type=ajp13
worker.app1Worker.host=app1.myhost.com #put your app host here
worker.app1Worker.port=8009
worker.app2Worker.type=ajp13
worker.app2Worker.host=app2.myhost.com #put your app host here
worker.app2Worker.port=8009
|
Well, everything looks good now. The final step is to configure the VirtualHost for every app on httpd:
vim /etc/httpd/conf.d/app1.conf
| | |
| — | — |
|
1
|
vim /etc/httpd/conf.d/app1.conf
|
It’s a good practice to maintain your VirtualHosts in separated files. Now, in your recently created app1.conf file:
ServerName app1.myhost.com
ServerAdmin admin@myhost.com
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-agent}i\”” combined
CustomLog /var/log/httpd/app1_access.log combined
ErrorLog /var/log/httpd/app1_error.log
JkMount /* app1Worker
| | |
| — | — |
|
1
2
3
4
5
6
7
8
9
10
|
ServerName app1.myhost.com
ServerAdmin admin@myhost.com
LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-agent}i\”” combined
CustomLog /var/log/httpd/app1_access.log combined
ErrorLog /var/log/httpd/app1_error.log
JkMount /* app1Worker
|
We are connecting httpd with tomcat using the JkMount directive in the VirtualHost configuration. If for example you’are adding a VirtualHost for your second app use the app2Worker configured previously and so on for other apps.
Final steps and conclusion
If you followed all the previous steps, you should be able to interact with your tomcat app directly from http://app1.myhost.com which is handled by httpd. Beautiful!
In this tutorial, we learned how to use mod_jk to connect different tomcat instances with the httpd web server. The procedure is straighforward but involves some compile tasks and a few configurations on each server. If you have any dobts don’t hesitate to initiate a converstion in the comments sections.

