An Auto Installer for Integrating Apache 2.2 and Tomcat 6.0 for Clustering/Session Replication, Load Balancing with mod_jk 1.2 on CentOS 5.3
Author: Andowson Chang
Date: 2009.04.25
Modified: 2009.07.05 (Update the JDK new version's download URL)
2009.12.23 (Update Tomcat process stop status check method)
2010.01.04 (Update Tomcat's version information URL)
2010.04.14 (Update TOMCAT_VERSION and TOMCAT_CONNECTOR_VERSION and LOG4J_VERSION, remove install JDK section from the shell script)
2010.04.15 (Update Log4J version determination and use useradd -M for not create home directory for user tomcat)
2010.05.01 Add apr-devel for x86_64 support
Design:
1. One Apache and Two Tomcat workers on the same machine.
2. Use mod_jk for load balancer
3. Use mod_ssl for SSL
4. Enable cluster configuration on both Tomcat workers to do session replication
Steps:
1.Install CentOS 5.3 (
disbale SELinux and Firewall)
2.Install JDK
3.Install Apache and mod_ssl
4.Generate SSL key and certificate
5.Edit httpd.conf
6.Edit ssl.conf
7.Install Tomcat, mod_jk
8.Edit server.xml
9.Edit mod_jk.conf
10.Edit workers.properties
11.Edit uriworkermap.properties
12.Start Apache and Tomcat
Testing:
1.Browsing
http://<your_server_ip>/clustertest.jsp, add some keys and values.
2.Shutdown worker1
3.Browsing
http://<your_server_ip>/clustertest.jsp, check if the keys and values are still there.
4.Run restart.sh
5.Browsing
http://<your_server_ip>/clustertest.jsp, check if the keys and values are still there.
6.Browsing
https://<your_server_ip>/clustertest.jsp, check if the keys and values are still there.
Implementation:
1.See
http://www.howtoforge.com/perfect-server-centos-5.3-x86_64-ispconfig-2 for step1.
2.Install JDK(check
http://java.sun.com for latest version)
#
# install JDK 6.0 Update 20
#
if [ ! -r jdk-6u20-linux-i586-rpm.bin ]; then
wget "http://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/VerifyItem-Start/jdk-6u20-linux-i586-rpm.bin?BundledLineItemUUID=PBGJ_hCwt5wAAAEopeNsZ47R&OrderID=_1CJ_hCwkZcAAAEoleNsZ47R&ProductID=guBIBe.oc_wAAAEnaDJHqPYe&FileName=/jdk-6u20-linux-i586-rpm.bin" -O jdk-6u20-linux-i586-rpm.bin
fi
echo 'yes'|sh jdk-6u20-linux-i586-rpm.bin
3.Create a directory /root/setup and download the auto installer script for step 3-11, save it as httpd2_tomcat6-setup.sh in /root/setup
mkdir -p /root/setup
then run it
chmod 755 /root/setup/httpd2_tomcat6-setup.sh
cd /root/setup
./httpd2_tomcat6-setup.sh
httpd2_tomca6-setup.sh:
#!/bin/bash
# Name: Apache 2.2.x && Tomcat 6.0.x auto installer
# Author: Andowson Chang (andowson [at] gmail [dot] com)
# Version: 5.10
# Last Modified: 2010-05-01
# Source: http://www.andowson.com
# Assumption: JDK must be installed on /usr/java
# This program will
# 1.install httpd and mod_ssl
# 2.modify /etc/http/conf/httpd.conf
# 3.generate SSL key and a self-signed certificate
# 4.modify /etc/http/conf.d/ssl.conf
# 5.check for the lastest stable version of Tomcat 6.0.x
# 6.download apache-tomcat-6.0.x.tar.gz
# 7.unpack it into /var/apache-tomcat-6.0.x
# 8.make a symbolic link /var/tomcat6 to the above directory for easy upgrade
# to a later version
# 9.check memory size to determine some JVM parameters
# 10.check for the latest stable verion of Tomcat Connector 1.2.x
# 11.download tomcat-connectors-1.2.x-src.tar.gz
# 12.unpack it
# 13.configure, make and make install
# 14.create user tomcat with home directory /var/tomcat6
# 15.make two instances of tomcat for load balancing, here I put them under
# /var/robust/worker[1,2] for easy to backup all of them.
# 16.setup default host directory(for testing)
# 17.generate server.xml
# 18.generate tomcat-users.xml
# 19.modify web.xml for production use
# 20.generate mod_jk.conf
# 21.generate workers.properties
# 22.generate uriworkermap.properties
# 23.generate tomcat startup script
# 24.modify web.xml for cluster test
# 25.generate clustertest.jsp for cluster test
# 26.generate cleanup.sh for easy to uninstall everything
#
# intranet workaround
# If your server don't have Internet access, ie. in the intranet behind
# a firewall, you have to download all the files manually first. Copy them
# into ${SETUP_DIR}. And then change the following default version
# number to the correct number you have downloaded.
#
TOMCAT_VERSION=6.0.26
TOMCAT_CONNECTOR_VERSION=1.2.30
LOG4J_VERSION=1.2.16
#
# auto detect ip and hostname
#
ip=`/sbin/ifconfig|grep "inet addr"|awk '{print $2}'|cut -d":" -f2|head -1`
hostname=`/bin/hostname -f`
#
# adjustable parameters, you can modify any of them to fit your own need
#
DOMAIN=`/bin/hostname -d`
COUNTRY=TW
STATE=Taiwan
LOCATION=Taipei
COMPANY="Andowson Ltd."
ORGANIZATION=
HOSTNAME=${hostname}
hostname=${ip}
MIRROR_HOST=apache.ntu.edu.tw
CATALINA_HOME=/var/tomcat6
WORKER_ROOT=/var/robust
WEBAPP_ROOT=/var/webapps
SETUP_DIR=/root/setup/web
mkdir -p ${SETUP_DIR}
cd ${SETUP_DIR}
echo 'service tomcat stop' > ${SETUP_DIR}/cleanup.sh
echo 'service httpd stop' >> ${SETUP_DIR}/cleanup.sh
#
# install httpd and mod_ssl
#
yum -y install httpd mod_ssl
cp -rf /etc/httpd/conf/httpd.conf /tmp/httpd.conf
cp -rf /etc/httpd/conf.d/ssl.conf /tmp/ssl.conf
#
# modify httpd.conf
#
sed -i -e "44c\ServerTokens ProductOnly" \
-e "74c\KeepAlive On" \
-e "232c\Group tomcat" \
-e "251c\ServerAdmin webmaster@${DOMAIN}" \
-e "265a\ServerName 127.0.0.1:80" \
-e "281a\VirtualDocumentRoot /var/webapps/%0" \
-e "391c\DirectoryIndex sorry.html index.html index.htm default.html default.htm index.html.var index.jsp" \
-e '488a\LogFormat "%V %h %l %u %t \\"%r\\" %>s %b" vcommon' \
-e '488a\LogFormat "%V %h %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-Agent}i\\"" vcombined' \
-e '492c\LogFormat "%h %l %u %t \\"%r\\" %>s %b \\"%{Referer}i\\" \\"%{User-Agent}i\\" %I %O" combinedio' \
-e "514c\CustomLog logs/access_log combinedio\nCustomLog logs/vhost.log vcombined" \
-e "524c\ServerSignature Off" \
-e "731c\LanguagePriority zh-TW en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN" \
-e "954a\<Location />" \
-e "954a\ # Insert filter" \
-e "954a\ SetOutputFilter DEFLATE\n" \
-e "954a\ # Netscape 4.x has some problems..." \
-e "954a\ BrowserMatch ^Mozilla/4 gzip-only-text/html\n" \
-e "954a\ # Netscape 4.06-4.08 have some more problems" \
-e '954a\ BrowserMatch ^Mozilla/4\\.0[678] no-gzip\n' \
-e "954a\ # MSIE masquerades as Netscape, but it is fine" \
-e '954a\ # BrowserMatch \\bMSIE \!no-gzip \!gzip-only-text/html\n' \
-e "954a\ # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48" \
-e "954a\ # the above regex won't work. You can use the following" \
-e "954a\ # workaround to get the desired effect:" \
-e '954a\ BrowserMatch \\bMSI[E] \!no-gzip \!gzip-only-text/html\n' \
-e "954a\ # Don't compress images" \
-e '954a\ SetEnvIfNoCase Request_URI \\.(?:gif|jpe?g|png)$ no-gzip dont-vary\n' \
-e "954a\ # Make sure proxies don't deliver the wrong content" \
-e "954a\ Header append Vary User-Agent env=\!dont-vary" \
-e "954a\</Location>\n" \
-e "954a\RewriteEngine on" \
-e "954a\RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)" \
-e "954a\RewriteRule .* - [F]\n" /etc/httpd/conf/httpd.conf
echo 'cp -rf /tmp/httpd.conf /etc/httpd/conf/httpd.conf' >> ${SETUP_DIR}/cleanup.sh
#
# generate SSL key and cert
#
openssl genrsa -out /etc/pki/tls/private/${HOSTNAME}.key 2048
openssl req -new -key /etc/pki/tls/private/${HOSTNAME}.key -out /etc/pki/tls/certs/${HOSTNAME}.csr -subj "/C=${COUNTRY}/ST=${STATE}/L=${LOCATION}/O=${COMPANY}/OU=${ORGANIZATION}/CN=${HOSTNAME}"
openssl x509 -req -days 3650 -in /etc/pki/tls/certs/${HOSTNAME}.csr -signkey /etc/pki/tls/private/${HOSTNAME}.key -out /etc/pki/tls/certs/${HOSTNAME}.crt
echo 'rm -rf /etc/pki/tls/private/'${HOSTNAME}'.key' >> ${SETUP_DIR}/cleanup.sh
echo 'rm -rf /etc/pki/tls/certs/'${HOSTNAME}'.csr' >> ${SETUP_DIR}/cleanup.sh
echo 'rm -rf /etc/pki/tls/certs/'${HOSTNAME}'.crt' >> ${SETUP_DIR}/cleanup.sh
#
# modify ssl.conf
#
sed -i -e "86a\JkMountFile conf/uriworkermap.properties\n" \
-e "112c\SSLCertificateFile /etc/pki/tls/certs/${HOSTNAME}.crt" \
-e "119c\SSLCertificateKeyFile /etc/pki/tls/private/${HOSTNAME}.key" /etc/httpd/conf.d/ssl.conf
echo 'cp -rf /tmp/ssl.conf /etc/httpd/conf.d/ssl.conf' >> ${SETUP_DIR}/cleanup.sh
chkconfig --level 235 httpd on
echo 'chkconfig httpd off' >> ${SETUP_DIR}/cleanup.sh
#
# check the latest stable version of Tomcat 6.0.x
#
wget http://tomcat.apache.org/whichversion.html -q -t 1 -T 5 -O /tmp/tomcat.html
if [ -s /tmp/tomcat.html ]; then
TOMCAT_VERSION=`grep "6\.0\." /tmp/tomcat.html|grep -v "6\.0\.x"|cut -d">" -f2|cut -d"<" -f1`
fi
rm -rf /tmp/tomcat.html
echo "Install Tomcat ${TOMCAT_VERSION}"
if [ ! -r apache-tomcat-${TOMCAT_VERSION}.tar.gz ]; then
wget http://${MIRROR_HOST}/tomcat/tomcat-6/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz
fi
tar zxvf apache-tomcat-${TOMCAT_VERSION}.tar.gz -C /var
ln -s /var/apache-tomcat-${TOMCAT_VERSION} ${CATALINA_HOME}
echo 'rm -rf /var/apache-tomcat-'${TOMCAT_VERSION} >> ${SETUP_DIR}/cleanup.sh
echo 'rm -rf '${CATALINA_HOME} >> ${SETUP_DIR}/cleanup.sh
#
# check memory size to determine some JVM parameters
#
mem=`cat /proc/meminfo|grep "MemTotal:"|awk '{print $2}'`
let KB=1024
let memsize=$mem/$KB
let heapsize=$memsize/2
let newsize=$heapsize/4
echo 'JAVA_HOME="/usr/java/latest"
JAVA_OPTS="-server -XX:NewSize='${newsize}'m -XX:MaxNewSize='${newsize}'m -XX:SurvivorRatio=8 -XX:MaxPermSize=128m -Xss256k -Xms'${heapsize}'m -Xmx'${heapsize}'m -Djava.net.preferIPv4Stack=true -Djava.awt.headless=true"' > ${CATALINA_HOME}/bin/setenv.sh
chmod 755 ${CATALINA_HOME}/bin/setenv.sh
#
# check the latest stable version of Tomcat Connector 1.2.x
#
# pre-requirment
yum -y install httpd-devel apr-devel libtool automake make gcc gcc-c++
wget http://tomcat.apache.org/download-connectors.cgi -q -t 1 -T 5 -O /tmp/connector.html
if [ -s /tmp/connector.html ]; then
TOMCAT_CONNECTOR_VERSION=`grep "1\.2\." /tmp/connector.html|cut -d">" -f2|cut -d"<" -f1 |awk '{print $2}'|grep "1.2"|uniq`
fi
rm -rf /tmp/connector.html
echo "Install Tomcat Connector JK ${TOMCAT_CONNECTOR_VERSION}"
if [ ! -r tomcat-connectors-${TOMCAT_CONNECTOR_VERSION}-src.tar.gz ]; then
wget http://${MIRROR_HOST}/tomcat/tomcat-connectors/jk/source/jk-${TOMCAT_CONNECTOR_VERSION}/tomcat-connectors-${TOMCAT_CONNECTOR_VERSION}-src.tar.gz
fi
tar zxvf tomcat-connectors-${TOMCAT_CONNECTOR_VERSION}-src.tar.gz
cd tomcat-connectors-${TOMCAT_CONNECTOR_VERSION}-src/native
./buildconf.sh
./configure --with-apxs=/usr/sbin/apxs
make
make install
cd ${SETUP_DIR}
echo 'rm -rf /etc/httpd/modules/mod_jk.so' >> ${SETUP_DIR}/cleanup.sh
#
# check the latest stable version of Log4J
#
wget http://logging.apache.org/log4j/1.2/download.html -q -t 1 -T 5 -O /tmp/log4j.html
if [ -s /tmp/log4j.html ]; then
LOG4J_VERSION=`grep "1\.2\." /tmp/log4j.html|cut -d"<" -f3|cut -d">" -f2|awk '{print $4}'|head -1`
fi
rm -rf /tmp/log4j.html
echo "Install Log4J ${LOG4J_VERSION}"
if [ ! -r apache-log4j-${LOG4J_VERSION}.tar.gz ]; then
wget http://${MIRROR_HOST}/logging/log4j/${LOG4J_VERSION}/apache-log4j-${LOG4J_VERSION}.tar.gz
fi
tar zxvf apache-log4j-${LOG4J_VERSION}.tar.gz
cp -rf ${SETUP_DIR}/apache-log4j-${LOG4J_VERSION}/log4j-${LOG4J_VERSION}.jar ${CATALINA_HOME}/lib
#
# replace tomcat-juli.jar and add tomcat-juli-adapters.jar for log4j
#
if [ ! -r tomcat-juli.jar ]; then
wget http://${MIRROR_HOST}/tomcat/tomcat-6/v${TOMCAT_VERSION}/bin/extras/tomcat-juli.jar
fi
cp -rf tomcat-juli.jar ${CATALINA_HOME}/bin
if [ ! -r tomcat-juli-adapters.jar ]; then
wget http://${MIRROR_HOST}/tomcat/tomcat-6/v${TOMCAT_VERSION}/bin/extras/tomcat-juli-adapters.jar
fi
cp -rf tomcat-juli-adapters.jar ${CATALINA_HOME}/lib
#
# generate log4j.properties
#
echo 'log4j.rootLogger=INFO, R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=logs/tomcat.log
log4j.appender.R.MaxFileSize=10MB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
log4j.logger.org.apache.catalina=INFO, R' > ${CATALINA_HOME}/lib/log4j.properties
#
# add user tomcat
#
groupadd -g 80 tomcat
useradd tomcat -u 80 -g tomcat -d ${CATALINA_HOME}
echo 'userdel -r tomcat' >> ${SETUP_DIR}/cleanup.sh
echo 'groupdel tomcat' >> ${SETUP_DIR}/cleanup.sh
#
# setup workers' directory
#
mkdir -p ${WORKER_ROOT}/logs
mkdir -p ${WORKER_ROOT}/worker1/logs
mkdir -p ${WORKER_ROOT}/worker1/temp
mkdir -p ${WORKER_ROOT}/worker1/work
cp -rf ${CATALINA_HOME}/conf ${WORKER_ROOT}/worker1/conf
mkdir -p ${WEBAPP_ROOT}
ln -s ${WEBAPP_ROOT} ${WORKER_ROOT}/worker1/webapps
cp -rf ${WORKER_ROOT}/worker1 ${WORKER_ROOT}/worker2
echo 'rm -rf '${WEBAPP_ROOT} >> ${SETUP_DIR}/cleanup.sh
#
# setup default host directory
#
mkdir -p ${WEBAPP_ROOT}/${hostname}
cp -rf ${CATALINA_HOME}/webapps/ROOT/* ${WEBAPP_ROOT}/${hostname}/.
mkdir -p ${WORKER_ROOT}/worker1/conf/Catalina/${hostname}
mkdir -p ${WORKER_ROOT}/worker2/conf/Catalina/${hostname}
cp -rf ${CATALINA_HOME}/webapps/host-manager/manager.xml ${WORKER_ROOT}/worker1/conf/Catalina/${hostname}
cp -rf ${CATALINA_HOME}/webapps/host-manager/manager.xml ${WORKER_ROOT}/worker2/conf/Catalina/${hostname}
#
# generate server.xml
#
echo '<?xml version="1.0" encoding="utf-8"?>
<Server port="workerPort" shutdown="shutdownCode">
<GlobalNamingResources>
<!-- Used by Manager webapp -->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<!-- Define an AJP 1.3 Connector on port ajpPort -->
<Connector port="ajpPort" address="127.0.0.1"
enableLookups="false" maxThreads="1000" connectionTimeout="3000"
protocol="AJP/1.3" />
<Engine name="Catalina" defaultHost="mydomain" jvmRoute="workerNo">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
' > /tmp/server.header.template
sed -e "s/workerPort/8105/g" -e "s/shutdownCode/`head -1024c /dev/urandom | md5sum | cut -d " " -f1`/g" -e "s/ajpPort/8109/g" -e "s/workerNo/worker1/g" -e "s/mydomain/${hostname}/g" /tmp/server.header.template > ${WORKER_ROOT}/worker1/conf/server.header
sed -e "s/workerPort/8205/g" -e "s/shutdownCode/`head -1024c /dev/urandom | md5sum | cut -d " " -f1`/g" -e "s/ajpPort/8209/g" -e "s/workerNo/worker2/g" -e "s/mydomain/${hostname}/g" /tmp/server.header.template > ${WORKER_ROOT}/worker2/conf/server.header
rm -rf /tmp/server.header.template
echo ' <Host name="'${hostname}'" appBase="webapps/'${hostname}'"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="'${hostname}'_access_log." suffix=".txt"
pattern="combined" resolveHosts="false"/>
<Context path="" docBase="" reloadable="false" />
</Host>' > ${WORKER_ROOT}/worker1/conf/server.host
cp -rf ${WORKER_ROOT}/worker1/conf/server.host ${WORKER_ROOT}/worker2/conf/server.host
echo ' </Engine>
</Service>
</Server>' > ${WORKER_ROOT}/worker1/conf/server.footer
cp -rf ${WORKER_ROOT}/worker1/conf/server.footer ${WORKER_ROOT}/worker2/conf/server.footer
cd ${WORKER_ROOT}/worker1/conf
cat server.header server.host server.footer > server.xml
cd ${WORKER_ROOT}/worker2/conf
cat server.header server.host server.footer > server.xml
#
# generate tomcat-users.xml
#
MANAGER_PASSWORD=`head -1024c /dev/urandom | md5sum | cut -d " " -f1 | awk '{print substr($1,1,8)}'`
echo '<tomcat-users>
<user username="manager" password="'${MANAGER_PASSWORD}'" roles="manager"/>
</tomcat-users>' > ${WORKER_ROOT}/worker1/conf/tomcat-users.xml
echo
echo "Your Tomcat Manager's login is 'manager', password is '${MANAGER_PASSWORD}'"
echo
cp -rf ${WORKER_ROOT}/worker1/conf/tomcat-users.xml ${WORKER_ROOT}/worker2/conf/tomcat-users.xml
#
# modify web.xml for production use
#
sed -i -e "97a\ <init-param>\n <param-name>readonly</param-name>\n <param-value>true</param-value>\n </init-param>" \
-e "246a\ <init-param>\n <param-name>genStringAsCharArray</param-name>\n <param-value>true</param-value>\n </init-param>" \
-e "246a\ <init-param>\n <param-name>trimSpaces</param-name>\n <param-value>true</param-value>\n </init-param>" ${WORKER_ROOT}/worker1/conf/web.xml
cp -rf ${WORKER_ROOT}/worker1/conf/web.xml ${WORKER_ROOT}/worker2/conf/web.xml
chmod 600 ${WORKER_ROOT}/worker*/conf/server.*
chmod 600 ${WORKER_ROOT}/worker*/conf/tomcat-users.xml
chown -R tomcat:tomcat /var/apache-tomcat-*
chown -R tomcat:tomcat ${WORKER_ROOT}
#
# generate mod_jk.conf
#
echo 'LoadModule jk_module modules/mod_jk.so
JkWorkersFile /etc/httpd/conf/workers.properties
JkShmFile logs/jk-runtime-status
JkLogFile "|/usr/sbin/rotatelogs /var/log/httpd/mod_jk.log 86400"
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkRequestLogFormat "%w %V %T"
LogFormat "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
CustomLog logs/worker_access_log mod_jk_log
# Load mount points
JkMountFile conf/uriworkermap.properties
# Deny direct access to WEB-INF
<LocationMatch ".*WEB-INF.*">
deny from all
</LocationMatch>' > /etc/httpd/conf.d/mod_jk.conf
echo 'rm -rf /etc/httpd/conf.d/mod_jk.conf' >> ${SETUP_DIR}/cleanup.sh
#
# generate workers.properties
#
echo '# workers.properties - ajp13
#
# List workers
#
worker.list=loadbalancer, jkstatus
#
# Define worker1
#
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8109
worker.worker1.socket_timeout=1200
worker.worker1.connection_pool_size=1
worker.worker1.connection_pool_timeout=1300
worker.worker1.lbfactor=1
# Define prefered failover node for worker1
worker.worker1.redirect=worker2
#
# Define worker2
#
worker.worker2.type=ajp13
worker.worker2.host=localhost
worker.worker2.port=8209
worker.worker2.socket_timeout=1200
worker.worker2.connection_pool_size=1
worker.worker2.connection_pool_timeout=1300
worker.worker2.lbfactor=1
# Disable worker2 for all requests except failover
worker.worker2.activation=d
#
# Defining a load balancer
#
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=worker1, worker2
#
# Define status worker
#
worker.jkstatus.type=status' > /etc/httpd/conf/workers.properties
echo 'rm -rf /etc/httpd/conf/workers.properties' >> ${SETUP_DIR}/cleanup.sh
#
# generate uriworkermap.properties
#
echo '/jkmanager/*=jkstatus
/*.jsp=loadbalancer
/*.do=loadbalancer
/*.page=loadbalancer
/dwr/*=loadbalancer
/servlet/*=loadbalancer
/manager/*=loadbalancer' > /etc/httpd/conf/uriworkermap.properties
echo 'rm -rf /etc/httpd/conf/uriworkermap.properties' >> ${SETUP_DIR}/cleanup.sh
#
# generate tomcat startup script
#
echo '#!/bin/sh
#
# Startup script for Tomcat, the Apache Servlet Engine
#
# chkconfig: - 84 16
# description: Tomcat Servlet Engine
# processname: tomcat
# pidfile: /var/run/worker1.pid /var/run/worker2.pid
# Source function library.
. /etc/rc.d/init.d/functions
# User under which tomcat will run
TOMCAT_USER=tomcat
RETVAL=0
CATALINA_HOME='${CATALINA_HOME}'
WORKER_ROOT='${WORKER_ROOT}'
WORKER_LIST=( worker1 worker2 )
WORKER_PORT=( 8105 8205 )
# start, debug, stop, and status functions
start() {
i=$1
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
if [ $SHUTDOWN_PORT -ne 0 ]; then
echo "Tomcat ${WORKER_LIST[i]} already started"
else
echo "Starting tomcat ${WORKER_LIST[i]}..."
CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
chown -R $TOMCAT_USER:$TOMCAT_USER $CATALINA_HOME
chown -R $TOMCAT_USER:$TOMCAT_USER $WORKER_ROOT
su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/startup.sh"
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
while [ $SHUTDOWN_PORT -eq 0 ]; do
sleep 1
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
done
echo "Tomcat ${WORKER_LIST[i]} started in normal mode"
RETVAL=$?
[ $RETVAL = 0 ] && touch /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
fi
}
debug() {
i=$1
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
if [ $SHUTDOWN_PORT -ne 0 ]; then
echo "Tomcat ${WORKER_LIST[i]} already started"
else
echo "Starting tomcat ${WORKER_LIST[i]} in debug mode..."
CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
rm -rf $CATALINA_BASE/work/*
chown -R $TOMCAT_USER:$TOMCAT_USER $CATALINA_HOME
chown -R $TOMCAT_USER:$TOMCAT_USER $WORKER_ROOT
su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/catalina.sh jpda start"
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
while [ $SHUTDOWN_PORT -eq 0 ]; do
sleep 1
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
done
echo "Tomcat ${WORKER_LIST[i]} started in debug mode"
RETVAL=$?
[ $RETVAL = 0 ] && touch /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
fi
}
stop() {
i=$1
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
if [ $SHUTDOWN_PORT -eq 0 ]; then
echo "Tomcat ${WORKER_LIST[i]} already stopped"
else
echo "Stopping tomcat ${WORKER_LIST[i]} ..."
CATALINA_BASE="$WORKER_ROOT/${WORKER_LIST[i]}"
su -l $TOMCAT_USER -c "export CATALINA_BASE=$CATALINA_BASE; $CATALINA_HOME/bin/shutdown.sh"
SHUTDOWN_PORT=`ps -ef|grep ${WORKER_LIST[i]}|grep -v grep|wc -l`
while [ $SHUTDOWN_PORT -ne 0 ]; do
sleep 1
SHUTDOWN_PORT=`ps -ef|grep ${WORKER_LIST[i]}|grep -v grep|wc -l`
done
echo "Tomcat ${WORKER_LIST[i]} stopped"
RETVAL=$?
[ $RETVAL=0 ] && rm -f /var/lock/subsys/${WORKER_LIST[i]} /var/run/${WORKER_LIST[i]}.pid
fi
}
status() {
for (( i = 0 ; i < ${#WORKER_LIST[@]} ; i++ ))
do
SHUTDOWN_PORT=`netstat -vatn|grep LISTEN|grep ${WORKER_PORT[i]}|wc -l`
if [ $SHUTDOWN_PORT -eq 0 ]; then
echo "Tomcat ${WORKER_LIST[i]} stopped"
else
MODE="normal"
JPDA_PORT=`netstat -vatn|grep LISTEN|grep 8000|wc -l`
if [ $JPDA_PORT -ne 0 ]; then
MODE="debug"
fi
echo "Tomcat ${WORKER_LIST[i]} running in $MODE mode"
fi
done
}
case "$1" in
start)
start 0
start 1
;;
debug)
debug 0
debug 1
;;
stop)
stop 0
stop 1
;;
restart)
stop 0
start 0
stop 1
start 1
;;
redebug)
stop 0
debug 0
stop 1
debug 1
;;
status)
status
;;
*)
echo "Usage: $0 {start|debug|stop|restart|redebug|status}"
exit 1
esac
exit $RETVAL' > /etc/rc.d/init.d/tomcat
chmod 755 /etc/rc.d/init.d/tomcat
chkconfig --add tomcat
chkconfig --level 235 tomcat on
echo 'chkconfig tomcat off' >> ${SETUP_DIR}/cleanup.sh
echo 'chkconfig --del tomcat' >> ${SETUP_DIR}/cleanup.sh
echo 'rm -rf /etc/rc.d/init.d/tomcat' >> ${SETUP_DIR}/cleanup.sh
chmod 755 ${SETUP_DIR}/cleanup.sh
echo 'Tomcat installation is completed!'
echo
echo 'You can type "service tomcat start" to start using tomcat now.'
echo 'You can type "service httpd start" to start using apache now.'
echo 'Open a browser, and go to http://'${hostname}' to see it.'
#
# modify web.xml for cluster test
#
sed -i -e "27a\ <distributable/>" ${WEBAPP_ROOT}/${hostname}/WEB-INF/web.xml
#
# generate clustertest.jsp for cluster test
#
echo '<%@ page contentType="text/html; charset=UTF-8" import="java.util.*"%>
<html>
<head>
<title>Cluster Session Replication Test</title>
</head>
<body>
<%
out.println("Session ID=" + session.getId() + "<br>");
String key = request.getParameter("key");
if (key != null && key.length() > 0) {
String value = request.getParameter("value");
session.setAttribute(key, value);
}
out.println("<b>Session Listing</b><br>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = (String)session.getAttribute(name);
out.println(name + " = " + value + "<br>");
}
%>
<form method="post">
key:<input type="text" size="20" name="key">
value:<input type="text" size="20" name="value">
<input type="submit">
</form>
</body>
</html>' > ${WEBAPP_ROOT}/${hostname}/clustertest.jsp
4.Then you can use the following two commands to do step12
service tomcat start
service httpd start
5. For testing, you can use the following command to shutdown or startup a single Tomcat worker:
su -l tomcat -c "export CATALINA_BASE=/var/robust/worker1; /var/tomcat6/bin/shutdown.sh"
su -l tomcat -c "export CATALINA_BASE=/var/robust/worker1; /var/tomcat6/bin/startup.sh"
su -l tomcat -c "export CATALINA_BASE=/var/robust/worker2; /var/tomcat6/bin/shutdown.sh"
su -l tomcat -c "export CATALINA_BASE=/var/robust/worker2; /var/tomcat6/bin/startup.sh"
Or you may use a shell script to restart Tomcat repeatedly to verify if the session replication really works.
restart.sh
for (( i = 0 ; i < 10 ; i++ ))
do
service tomcat restart
done
If you can see all of the session objects no matter how Tomcat is restarted, then Tomcat clustering(session replication) is done.
Note: If you have enabled firewall like iptables, please add
45564:udp port to the allowed list.
6. Finally, browse
https://<your_server_ip>/ to check SSL works. You have to add this site as your trust site because we use a self-signed SSL certificate.
Reference:
http://tomcat.apache.org/connectors-doc/reference/apache.html
http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html
http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html
http://tomcat.apache.org/tomcat-6.0-doc/jasper-howto.html
http://tomcat.apache.org/tomcat-6.0-doc/logging.html
http://www.easywayserver.com/implementation-tomcat-clustering.htm