Apache and Tomcat are the A and B of middleware that everyone learns and they have widely used web server and application server across the world( sometimes referred to as just web container as it does have no EJB)
It's like a sandbox for every rookie to learn things and manipulate them later wherever it may require
If you are not very well aware of mod_jk and AJP protocol, go and search in google you will get numerous links.
This article's main objective is to cover the apache and tomcat integration using mod_jk practically. therefore I have not gone any deep into apache HTTP server (or) tomcat either.
This article presumes that you have the Linux machine with the Apache2.4+ installed
Let's go
Step1: Make sure the apache services are running
apachectl status
Start the service ( if not already)
apachectl start
Step2: Install Dependencies
Before Installing Mod_JK, there are few dependencies you have to install
yum install httpd-devel ( source of apxs ) yum install gcc libtool
Step3: Download mod_jk connector (tar.gz format) from tomcat website
https://tomcat.apache.org/download-connectors.cgi
You will get some downloadable link like shown below.
you can optionally use wget utilty to download the tar ball directory to your server by placing the mirror link
Once you got the tar.gz file in the server at any temp location, untar it using tar -xvf
tar -xvf tomcat-connectors-1.2.42-src.tar.gz
After untar, go to the untarred directory and then to the native directory
tomcat-connectors-1.2.42-src/native
Step4: Configure with APXS
Run the following command in the same native directory
./configure -with-apxs=/usr/bin/apxs
root@mw-web01# ./configure -with-apxs=/usr/bin/apxs
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
Note*: Sometimes apxs could be found in /usr/sbin also, Please use locate apxs (or) find / -name "apxs" commands to find the location of apxs and use the respective path with configure command
Step5: Execute the Make Command
Execute the make
command to build the .so (system object) file on the same native
directory
root@mw-web01# make
Making all in common
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
/usr/lib64/apr-1/build/libtool – silent – mode=compile gcc -std=gnu99 -I. -I/usr/include/httpd -DHAVE_CONFIG_H -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong – param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -pthread -DHAVE_APR -I/usr/include/apr-1 -I/usr/include/apr-1 -DHAVE_CONFIG_H -DLINUX -D_REENTRANT -D_GNU_SOURCE -c jk_ajp12_worker.c -o jk_ajp12_worker.lo
/usr/lib64/apr-1/build/libtool – silent – mode=compile gcc -std=gnu99 -I. -I/usr/include/httpd -DHAVE
...........................
............................
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native'
make[1]: Nothing to be done for `all-am'.
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native'
target="all"; \
list='common apache-2.0'; \
for i in $list; do \
echo "Making $target in $i"; \
if test "$i" != "."; then \
(cd $i && make $target) || exit 1; \
fi; \
done;
Making all in common
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/common'
Making all in apache-2.0
make[1]: Entering directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'
../scripts/build/instdso.sh SH_LIBTOOL='/usr/lib64/apr-1/build/libtool – silent' mod_jk.la `pwd`
/usr/lib64/apr-1/build/libtool – silent – mode=install cp mod_jk.la /etc/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0/
libtool: install: warning: remember to run `libtool – finish /usr/lib64/httpd/modules'
make[1]: Leaving directory `/usr/lib64/httpd/modules/tomcat-connectors-1.2.42-src/native/apache-2.0'
Now you should be able to see the apache2.0
directory created under the native
directory,
Step6: Copy the Generated mod_jk.so file to apache modules
If you list the content of the directory you could see the mod_jk.so
file created, copy it to modules
directory of your apache web server
root@ mw-web01 # pwd
/tmp/tomcat-connectors-1.2.42-src/native/apache-2.0
root@ mw-web01 # ls -rlt
total 4960
-rw-r--r – 1 root bin 1335 Sep 13 2010 config.m4
-rw-r--r – 1 root bin 11019 Nov 14 2011 mod_jk.dsp
-rw-r--r – 1 root bin 6351 Nov 16 2011 NWGNUmakefile
-rw-r--r – 1 root bin 9541 Nov 16 2011 bldjk.qclsrc
-rw-r--r – 1 root bin 10350 Nov 16 2011 bldjk54.qclsrc
-rw-r--r – 1 root bin 6947 Mar 9 2012 Makefile.vc
-rw-r--r – 1 root bin 1434 Dec 20 2014 Makefile.apxs.in
-rw-r--r – 1 root bin 3068 Dec 20 2014 Makefile.in
-rw-r--r – 1 root bin 147853 Sep 22 2016 mod_jk.c
-rw-r--r – 1 root root 3328 Nov 6 14:37 Makefile
-rw-r--r – 1 root root 1622 Nov 6 14:37 Makefile.apxs
-rw-r--r – 1 root root 365288 Nov 6 14:49 mod_jk.o
-rw-r--r – 1 root root 270 Nov 6 14:49 mod_jk.lo
-rwxr-xr-x 1 root root 1553336 Nov 6 14:49 mod_jk.so
-rw-r--r – 1 root root 920 Nov 6 14:49 mod_jk.la
-rw-r--r – 1 root root 2917994 Nov 6 14:49 mod_jk.a
In my case its /etc/httpd/modules
cp mod_jk.so /etc/httpd/modules
here is my directory listing of server_root /etc/httpd
for your reference
root@ mw-web01 # ls -rlt
total 4
drwxr-xr-x. 2 root root 78 Oct 31 13:58 conf.d
drwxr-xr-x. 2 root root 4096 Oct 31 13:58 conf.modules.d
lrwxrwxrwx 1 root root 19 Oct 31 13:58 logs -> ../../var/log/httpd
lrwxrwxrwx 1 root root 29 Oct 31 13:58 modules -> ../../usr/lib64/httpd/modules
lrwxrwxrwx 1 root root 10 Oct 31 13:58 run -> /run/httpd
drwxr-xr-x. 2 root root 35 Nov 6 14:55 conf
Step7: Load the Module mod_jk.so
Now it is a time to load the module .SO
file, we have just copied to the modules directory
In an earlier version of apache if we want to Load any module we would use LoadModule
directive in httpd.conf
file.
But, in Apache2+ every configuration files are in a distinct directory and imported into httpd.conf
using Include directive.
You can see there are multiple INCLUDES in httpd.conf
root@ mw-web01 # grep -i ^Include conf/httpd.conf
Include conf.modules.d/*.conf
Include sites-enabled/*
IncludeOptional conf.d/*.conf
and all the module related configurations are loaded from conf.modules.d directory
our LoadModule
has to be put under /etc/httpd/conf.modules.d
directory as a new file. This setup would help in categorizing and managing the modules effectively
here is the Snap of my conf.modules.d
directory before adding a new file.
root@ mw-web01 # cd conf.modules.d
root@ mw-web01 # pwd
/etc/httpd/conf.modules.d
root@ mw-web01 # ls -rlt
total 32
-rw-r--r--. 1 root root 43 Aug 19 2014 10-wsgi.conf
-rw-r--r – 1 root root 451 Jul 26 04:43 01-cgi.conf
-rw-r--r – 1 root root 88 Jul 26 04:43 00-systemd.conf
-rw-r--r – 1 root root 957 Jul 26 04:43 00-proxy.conf
-rw-r--r – 1 root root 742 Jul 26 04:43 00-mpm.conf
-rw-r--r – 1 root root 41 Jul 26 04:43 00-lua.conf
-rw-r--r – 1 root root 139 Jul 26 04:43 00-dav.conf
-rw-r--r – 1 root root 3739 Jul 26 04:43 00-base.conf
root@ mw-web01 #
Now we need to Create a new file named mod_jk.conf
and add the following lines
LoadModule jk_module "/etc/httpd/modules/mod_jk.so"
JkWorkersFile /etc/httpd/conf/workers.properties
JkLogFile /etc/httpd/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"
Here
JkWorkersFile is the file where we would be defining the application server details and nodes etc
JkLogFile is the log for the mod_jk, It is good to troubleshoot in case of issues
The other four directive's tasks could be easily interpreted by their very name
Step8: Creating Workers ( they are our minions!!)
We have defined theJkWorkersFile file name and location on the Step7 inside the mod_jk.conf
file
Now Its a time to create a Workers file and define the application server (tomcat) details, In my case I have tomcat servers running at following hostnames and ports tc_node1.techolaf.com:8009
andtc_node2.techolaf.com
:8009
Here 8009
is the AJP port number on the backend Tomcat Servers.
#Define the list of workers you have
worker.list=jkstatus,lb_router
# Set LOADBALANCER
worker.lb_router.type=lb
worker.jkstatus.type=status
# HERE is where you decide on how many Tomcat Server's there are in the cluster
worker.lb_router.balance_workers=tc-node1,tc-node2
worker.lb_router.sticky_session=1
# Set Worker
worker.tc-node1.port=8009
worker.tc-node1.host=tc_node1.techolaf.com
worker.tc-node1.type=ajp13
worker.tc-node1.lbfactor=1
worker.tc-node2.port=8009
worker.tc-node2.host=tc_node1.techolaf.com
worker.tc-node2.type=ajp13
worker.tc-node2.lbfactor=1
Note:*
mwitc-node1 is the worker name (member) here, there will be a dedicated worker for each application server node. Name of this worker should be matched to the JVM_Route parameter value in the back-end tomcat's server.xml file
Step8: Adding JVMRoute in server.xml
in the backend servers you need to add a jvmRoute parameter and the value of jvmRoute should be as same as the worker name mentioned in the workers.properties
file.
Hostname | WorkerName | JvmRoute Value |
tc_node1.techolaf.com | tc-node1 | tc-node1 |
tc_node2.techolaf.com | tc-node2 | tc-node2 |
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tc-node1">
Step9: Update your Apache Virtual Host file and add JKMount
Update your virtual Host Configuration to enable URI forwarding
Now go back to your virtual host configuration file on the Apache webserver end based on your apache server configuration you can find the file in any of these paths
/etc/apache2/sites-enabled/<your-app-name>.conf /etc/apache2/conf.d/<your-app-name>.conf
Now, it's time to configure apache to forward the requests to the application server
If the URI path aka context-root matches to a certain string. These Strings are basically referred to as Context-root (or) war file names in the tomcat end.
At the end of your virtual host file, add the below line
JkMount /<Your Application Name>/* lb_router
JkMount /myapp/* lb_router
Here
JKMount
instructs, this should be handled by mod_jk
Here myapp
refers to the application war file name (or) the context root
lb_router
worker name referring to the workers.properties
file
What we basically do here is, mapping the worker to th URI or Context Root. More like Location in Virtual Host configuration
Now we are all set to test the route.
Test your application now with the web server name
http://<virtualhost name>/<contextroot>
In my case it is
http://appbase.mwinventory.in/myapp
Step9 : Validate the Logs - Audit the Logs
Time to AUDIT the Logs
root@mw-web01#
tail -20f /etc/httpd/mod_jk.log
[Mon Nov 06 16:50:16 2017]lb_router appbase.mwinventory.in 0.002238
[Mon Nov 06 16:55:28 2017][24044:139753907869824] [info] init_jk::mod_jk.c (3595): mod_jk/1.2.42 initialized
[Mon Nov 06 16:55:28 2017][24044:139753907869824] [info] init_jk::mod_jk.c (3595): mod_jk/1.2.42 initialized
[Mon Nov 06 16:55:46 2017]lb_router appbase.mwinventory.in 0.002961
[Mon Nov 06 16:55:46 2017]lb_router appbase.mwinventory.in 0.013606
[Mon Nov 06 16:55:49 2017]lb_router appbase.mwinventory.in 0.005105
Hope this article helps.
Cheers,
Sarav AK
Follow me on Linkedin My Profile Follow DevopsJunction onFacebook orTwitter For more practical videos and tutorials. Subscribe to our channel
Signup for Exclusive "Subscriber-only" Content