태그 보관물: 아파치 톰캣

tomcat 세션 클러스터링 설정

apache tomcat이란?
아파치톰캣(apache tomcat)은 아파치 소프트웨어 재단에서 개발한 서블릿 컨테이너(또는 웹 컨테이너)만 있는 웹 애플리케이션 서버이다.

톰캣은 웹 서버와 연동하여 실행할 수 있는 자바 환경을 제공하여 자바서버 페이지(JSP)와 자바 서블릿이 실행할 수 있는 환경을 제공하고 있는 것이다. 톰캣은 관리툴을 통해 설정을 변경할 수 있지만, XML 파일을 편집하여 설정할 수도 있다. 그리고, 톰캣은 HTTP 서버도 자체 내장하기도 한다.

아파치 톰캣은 Apache Licence, Version 2를 채용한 오픈소스 소프트웨어로서, 자바서버 페이지이나 자바 서블릿를 실행하기 위한 서블릿 컨테이너를 제공하며, 상용 웹 애플리케이션 서버에서도 서블릿 컨테이너로 사용하는 경우가 많다. 버전 5.5 이후는 기본적으로 Java SE 5.0 이후를 대응한다.

이번 포스팅에서는 아파치 톰캣(apache tomcat) 세션 클러스터링 설정에 관한 내용이다.

tomcat 세션클러스터링을 구축하는것은 큰 어려움이 없다. 하지만 운영관리하는 부분에서 매우 중요하다. 아무리 구성 및 구축을 잘한다고 해도 유지보수를 잘하지 못하면 안 되는 것이다.

상황
tomcat1, tomcat2 라는 하나의 서버에 2개의 인스턴트가 존재한다. 2개의 인스턴트는 서로 세션클러스터링이 되고 있는 상황이기 때문에 어느한쪽이 장애가 발생해도 큰 문제가 생기지 않는다. 그럼 지금부터 스탭바이스탭으로 진행해보자

java 파일 다운로드

jdk-7u75-linux-x64.tar.gz
tar xvf jdk-7u75-linux-x64.tar.gz
mv jdk1.7.0_75/ ../
ln -s /usr/local/jdk1.7.0_75 /usr/local/java

vi /etc/profile
export JAVA_HOME=/usr/local/java

CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$CATALINA_HOME/lib-jsp-api.jar:$CATALINA_HOME/lib/servlet-api.jar
export PATH=$PATH:$JAVA_HOME/bin

source /etc/profile

tomcat 파일 다운로드

apache-tomcat-7.0.70.tar.gz
tar xvf apache-tomcat-7.0.70.tar.gz
mv apache-tomcat-7.0.70 ../
ln -s /usr/local/apache-tomcat-7.0.70 /usr/local/tomcat1

2번째 톰캣 생성

mv apache-tomcat-7.0.70 ../apache-tomcat-7.0.70_2
ln -s /usr/local/apache-tomcat-7.0.70_2 /usr/local/tomcat2

tomcat-jk 파일 다운로드

tomcat-connectors-1.2.41-src.tar.gz
tar xvf tomcat-connectors-1.2.41-src.tar.gz
cd tomcat-connectors-1.2.41-src
cd native/
chmod +x buildconf.sh
./configure --with-apxs=/usr/local/apache/bin/apxs && make && make install

httpd(아파치) 환경 파일 설정

vi /usr/local/apache/conf/httpd.conf

LoadModule jk_module modules/mod_jk.so

<IfModule mod_jk.c>
JkWorkersFile conf/workers.properties
JkLogFile logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %R %V %T %U %q"
</IfModule>

vi /usr/local/apache/conf/workers.properties

workers.tomcat_home=$CATALINA_HOME
workers.java_home=$JAVA_HOME
ps=/

worker.list=router

##1번째 인스턴스 생성

worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1
worker.worker1.route=worker1

##2번째 인스턴스 생성

worker.worker2.port=8019
worker.worker2.host=localhost
worker.worker2.type=ajp13
worker.worker2.lbfactor=1
worker.worker2.route=worker2
worker.router.type=lb
worker.router.balance_workers=worker1,worker2

httpd vhost 호스트 연결 설정

vi /usr/local/apache/conf/extra/httpd-vhosts.conf

<VirtualHost *:80>
     DocumentRoot "/usr/local/tomcat1/webapps/ROOT/"
     ServerName 210.114.223.192
     JkMount /*.jsp router
     JkMount /servlet/* router
</VirtualHost>

<VirtualHost *:80>
     DocumentRoot "/usr/local/tomcat2/webapps/ROOT/"
     ServerName 210.114.223.192
     JkMount /*.jsp router
     JkMount /servlet/* router
</VirtualHost>

tomcat1 셋팅

vi /usr/local/tomcat1/bin/catalina.sh

export  CATALINA_OPTS=-Djava.awt.headless=true
vi /usr/local/tomcat1/conf/server.xml

<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">

     <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
     <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>

     <Channel className="org.apache.catalina.tribes.group.GroupChannel">
          <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.105" port="45564" frequency="500" dropTime="3000"/>
          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="210.114.223.192" port="4000"  autoBind="100" selectorTimeout="5000" maxThreads="6"/>
          <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
               <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
          </Sender>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
     </Channel>

     <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
     <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

     <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/>
     <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
     <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
     </Cluster>
vi /usr/local/tomcat1/conf/web.xml

<display-name>Clustering Test</display-name>
<distributable/>
vi /usr/local/tomcat1/webapps/ROOT/WEB-INF/web.xml

<display-name>Clustering Test</display-name>
<distributable/>

tomcat2 셋팅

vi /usr/local/tomcat2/bin/catalina.sh

export CATALINA_HOME=/usr/local/tomcat2
export TOMCAT_HOME=/usr/local/tomcat2
export CATALINA_BASE=/usr/local/tomcat2
CATALINA_PID=/usr/local/tomcat2/bin/tomcat.pid
vi /usr/local/tomcat2/conf/server.xml

<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker2">

    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
     <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>

     <Channel className="org.apache.catalina.tribes.group.GroupChannel">
          <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.105" port="45564" frequency="500" dropTime="3000"/>
          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="210.114.223.192" port="4001" autoBind="100" selectorTimeout="5000" maxThreads="6"/>
          <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
               <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
          </Sender>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
          <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
     </Channel>

     <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
     <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

     <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/>
     <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
     <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
vi /usr/local/tomcat2/conf/web.xml

<display-name>Clustering Test</display-name>
<distributable/>
vi /usr/local/tomcat2/webapps/ROOT/WEB-INF/web.xml

<display-name>Clustering Test</display-name>
<distributable/>
vi /usr/local/tomcat1/webapps/ROOT/index.jsp

vi /usr/local/tomcat2/webapps/ROOT/index.jsp

######추가#####
<%
  session.setAttribute("a","a");
%>

<html>
<head>
<title>Test JSP</title>
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr bgcolor="#CCCCCC">
    <td width="13%">Tomcat1 Machine</td>
    <td width="87%"> </td>
  </tr>
  <tr>
    <td>Session ID :</td>
    <td><%=session.getId()%></td>
  </tr>
</table>
    <div>Im WAS server hello snowman</div>
</body>
</html>
########

서비스시작

/usr/local/apache/bin/apachectl start
/usr/local/tomcat1/bin/catalina.sh start
/usr/local/tomcat2/bin/catalina.sh start

vi catalina.out

아래와 같은 메시지가 나오면 성공.

정보: Manager [localhost#], requesting session state from org.apache.catalina.tribes.membership.MemberImpl[tcp://{210, 114, 223, 192}:4001,{210, 114, 223, 192},4001, alive=-2462217, securePort=-1, UDP Port=-1, id={29 -120 115 -102 -15 -83 73 28 -113 105 24 -77 33 86 -30 26 }, payload={}, command={}, domain={}, ]. This operation will timeout if no session state has been received within 60 seconds

웹브라우저에서 tomcat1, tomcat2 를 번갈아 보게되면 세션값은 동일하게 보인다. 서비스 하나를 내려도 세션에는 변화 없고 유지됨.

결과

그림과 같이 세션값이 동일하다는걸 확인할 수 있다.

이 상황에서 tomcat1를 죽여봤다. 아래 그림처럼 8080포트가 올라오지 않는걸 확인할 수 있다.

세션값이 동일하면서 tomcat2이 단독으로 서비스 되고 있는걸 확인할 수 있다.