본문 바로가기
프로그램 활용/웹서버

톰캣 세션 클러스터링

by 3604 2023. 8. 16.
728x90
 

이번 테크 포스팅에서는 톰캣 세션 클러스터링(Tomcat Session Clustering)에 대해 알아볼텐데요, ① 1대 서버에서 WEB과 WAS를 같이 사용하는 방법 ② LB 1대 WEB, WAS 각 2대씩 사용하는 방법에 대해 알아보겠습니다.


톰캣 세션 클러스터링이란?

세션 클러스터링은 WAS가 2대 이상 설치되어 있을 경우 동일한 세션으로 세션관리 하는 것을 의미합니다. 보통 세션 클러스터링은 WAS 설정으로 세팅할 수 있습니다. Tomcat에서 조차도 세션 클러스터링을 설정하는 방법이 있습니다.

① 1대 서버에서 WEB, WAS 같이 사용하며 Tomcat Session Clustering 설정 방법

※ 1대 서버에서 Tomcat Session Clustering 설정은 이중화 구성이 아닙니다.

테스트 버전 : CentOS 6.9 64bit, Apache(2.2.13), Tomcat(7.0), JDK(1,7)

1. Tomcat2 생성

# cd /usr/local/ # cp aurp tomcat tomcat2 # vi /usr/local/tomcat2/bin/catalina.sh #아래 내용 추가 ###### Tomcat2 PATH ####### CATALINA_BASE=/usr/local/tomcat2 CATALINA_HOME=/usr/local/tomcat2 CATALINA_TMPDIR=/usr/local/tomcat2/temp JRE_HOME=/usr/local/java # vi /usr/local/tomcat2/conf/server.xml #아래 포트 변경 <Server address="127.0.0.1" port="8006" shutdown="SHUTDOWN"> <Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8444" URIEncoding="UTF-8"/> <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8" /> 기존 tomcat 포트에서 +1로 숫자 변경 예시) tomcat : 8005, 8080, 8009, tomcat2 : 8006, 8081, 8010 # /usr/local/tomcat/bin/catalina.sh start # netstat -nlp | grep 8081 # vi /usr/local/tomcat/conf/web.xml 아래 부분 주석 제거 <!-- <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> --> 고양이 그림 확인 후 다시 주석 처리

2. 로드밸런서 설정

# vi /usr/local/apache/conf/workers.properties #아래 내용 추가 worker.list=loadbalancer #실제 사용할 tomcat 인스턴스 리스트 worker.loadbalancer.type=lb # loadbalancer 타입 worker.loadbalancer.balanced_workers=tomcat1,tomcat2 #loadbalancer tomcat list worker.loadbalancer.sticky_session=1 #세션 유지를 위해 WAS에 지속해서 접근 worker.tomcat1.type=ajp13 #web<->was ajp3 통신 worker.tomcat1.host=localhost worker.tomcat1.port=8009 #tomcat Connector Port :8009 worker.tomcat1.lbfactor=1 #작업 비율 worker.tomcat2.type=ajp13 #web<->was ajp3통신 worker.tomcat2.host= localhost worker.tomcat2.port=8010 #tomcat Connector Port :8010 worker.tomcat2.lbfactor=1 #작업 비율 # vi /usr/local/apache/conf/vhosts.conf <VirtualHost *:80> ServerName 서버IP DocumentRoot /home/WAS1/www JkMount /*.do loadbalancer #.do 파일은 로드밸런서가 처리 JkMount /*.jsp loadbalancer #.jsp 파일은 로드밸런서가 처리 </VirtualHost> # vi /usr/local/tomcat/conf/server.xml #아래 내용 추가 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> # vi /usr/local/tomcat2/conf/server.xml #아래 내용 추가 <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">

3. 세션 클러스터링 설정

# vi /usr/local/tomcat/conf/server.xml #주석 처리된 ‘Cluster’ 아래에 내용 추가 # vi /usr/local/tomcat2/conf/server.xml #주석 처리된 ‘Cluster’ 아래에 내용 추가 <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.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" #tomcat2 4001 (+1 증가) 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=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/> <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/tomcat/webapps/ROOT/WEB-INF/web.xml #</web-app> 위에 아래 내용 추가 <distributable/>WEB-INF’ 폴더를 위에서 설정한 Tomcat 디렉토리 경로에 복사 예시) tomcat : /home/tripod/tomcat1, tomcat2 : /home/tripod/tomcat2 # cp -aurp WEB-INF /home/tripod/tomcat1 # cp -aurp WEB-INF /home/tripod/tomcat2

4. Apache, tomcat 재시작

# /usr/local/apache/bin/apachectl restart # /usr/local/tomcat/bin/catalina.sh restart # /usr/local/tomcat2/bin/catalina.sh restart

5. Tomcat Session Clustering test

A. “Tomcat Session Clustering Test” 아래 내용 참고하여 index.jsp 파일 생성

<%@ page contentType="text/html; charset=euc-kr" %> <% System.out.println( "Session ID : " + session.getId() ); %> <HTML> <HEAD> <TITLE>Session Clustering Test</TITLE> </HEAD> <BODY> <h1>Session Clustering Test</h1> <% Integer ival = (Integer)session.getAttribute("_session_counter"); if(ival==null) { ival = new Integer(1); } else { ival = new Integer(ival.intValue() + 1); } session.setAttribute("_session_counter", ival); System.out.println("here~~~~"); %> Session Counter = [<b> <%= ival %> </b>]<p> <a href="./sc.jsp">[Reload]</a> <p> Current Session ID : <%= request.getRequestedSessionId() %><br /> <center><h3>[ 세션 정보를 얻어오는 메소드를 사용한 예제 ]</h3></center> <hr> <% String id_str=session.getId(); long lasttime=session.getLastAccessedTime(); long createdtime=session.getCreationTime(); long time_used=(lasttime-createdtime)/60000; int inactive=session.getMaxInactiveInterval()/60; boolean b_new=session.isNew(); %> [1] 세션 ID[<%=session.getId()%>] 입니다.<br><hr> [2] 당신의 웹사이트에 머문 시간은 <%=time_used%> 입니다.<br><hr> [3] 세션의 유효시간은 <%=inactive%> 분입니다.<br><hr> [4] 세션이 새로 만들어 졌나요?<br><hr> <% if(b_new) out.println("예 !! 새로운 세션을 만들었습니다."); else out.println("아니오 !! 새로운 세션을 만들지 않았습니다."); %> <hr> </BODY> </HTML>

B. Session Clustering 확인

http://서버IP/index.jsp 접속

C. Current Session ID : E34CA3BFD1A71D68A3CB6D03CA8D97D3.tomcat2 마지막 Tomcat2 확인

※ Tomcat2번으로 연결된 것

D. tomcat2 중지

※ C번에서 Tomcat1 확인 시 Tomcat1번 중지

E. http://서버IP/index.jsp 새로 고침 후 ‘Current Session ID’ 확인 시 세션 값이 기존과 동일하고 Tomcat1 확인

Current Session ID : E34CA3BFD1A71D68A3CB6D03CA8D97D3.tomcat1 마지막 Tomcat1 확인

※ 세션 값 동일 Tomcat2번에서 Tomcat1번으로 변경된 것 확인

F. 반대로 Tomcat1번 중지 후 Tomcat2번 실행 시 E번 내용과 일치 여부 확인

② LB 1대 WEB, WAS 각 2대씩 사용하여 Tomcat Session Clustering 설정 방법

테스트 환경 : LB 1대, WEB 2대, WAS 2대

※ 각 서버에는 Apache 및 Tomcat 환경이 구성되었다는 전제로 진행

WEB : Apache2.4 WAS : JAVA1.8, Tomcat8.X

1. WEB 서버 설정 (2대 공통)

workers.properties 설정 (내용 추가) # vi /usr/local/apache/conf/workers.properties worker.list=loadbalancer #실제 사용할 tomcat 인스턴스 리스트 worker.loadbalancer.type=lb # worker.loadbalancer.balanced_workers=tomcat1,tomcat2 #loadbalancer tomcat list worker.loadbalancer.sticky_session=1 #세션 유지를 위해 WAS에 지속해서 접근 worker.tomcat1.type=ajp13 #web<->was ajp3통신 worker.tomcat1.host=172.27.1.3 #WAS1 서버 IP worker.tomcat1.port=8009 #tomcat Connector Port :8009 worker.tomcat1.lbfactor=100 #작업 비율 worker.tomcat2.type=ajp13 #web<->was ajp3통신 worker.tomcat2.host=172.27.0.81 #WAS2 서버 IP worker.tomcat2.port=8010 #tomcat Connector Port :8010 worker.tomcat2.lbfactor=100 #작업 비율

2. httpd.conf 설정 (내용 추가)

# vi /usr/local/apache/conf/httpd.conf <IfModule mod_jk.c> JkWorkersFile conf/workers.properties #mod_jk 설정 파일 및 위치 JkLogFile logs/mod_jk.log #mod_jk 로그 위치 JkShmFile logs/mod_jk.shm JkLogLevel error JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " #로그파일 포맷 형식 JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories JkRequestLogFormat "%w %V %T" #로그파일 포맷 형식 </IfModule>

3. vhosts.conf 설정 (내용 추가)

# vi /usr/local/apache/conf/vhosts.conf <VirtualHost *:80> DocumentRoot "/usr/local/tomcat/webapps/ROOT" ServerName 211.253.25.96 #웹서버 IP JkUnmount /index.html loadbalancer #index.html Apache 처리 JKMount /* loadbalancer #JkUnmount 값을 제외한 모든 확장자 tomcat 처리 </VirtualHost>

4. WAS 서버 설정 (2대 공통)

#vi /usr/local/tomcat/conf/server.xml 설정 (내용 추가) - jvmRoute 설정 추가 (mod_jik 커넥터에서 톰캣 프로세스를 구분하는데 사용) 설정 전 : <Engine name="Catalina" defaultHost="localhost"> 설정 후 : <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1"> <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2"> - Cluster 설정 추가 (Cluster className 부분 밑에다 아래 내용 삽입) <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="224.0.0.116" # 116 ~ 205 Port 사이 설정 권장 port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="172.27.1.3" # tomcat IP port="4010" # 4000 ~ 4100 Port 사이 설정 권장 autoBind="100" selectorTimeout="100" 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.ClusterSessionListener"/> </Cluster>

5. web.xml 설정 (내용 추가)

# vi /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml Session Clustering을 위해 프로젝트 web.xml에 반드시<distributable/>설정을 넣어야 함 ※ 제일 마지막 </web-app> 바로 위에 삽입 <distributable/> </web-app>

6. Tomcat Session Clustering 구성 확인

→ Session Clustering 확인 절자

WAS 2대 Tomcat start log 확인

아래와 같이 각 WAS 서버에서 로그 확인 시 멤버 추가 로그와 IP, Port 확인

- WAS01 (IP : 172.27.1.3)

17-May-2017 21:07:22.416 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 27, 0, 81}:4011,{172, 27, 0, 81},4011, alive=19538, securePort=-1, UDP Port=-1, id={35 -123 -62 23 10 -31 73 -5 -78 -89 2 -41 41 84 105 -57 }, payload={}, command={}, domain={}, ]

- WAS02 (IP : 172.27.0.81)

17-May-2017 21:07:23.127 INFO [Membership-MemberAdded.] org.apache.catalina.ha.tcp.SimpleTcpCluster.memberAdded Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp://{172, 27, 1, 3}:4010,{172, 27, 1, 3},4010, alive=1019, securePort=-1, UDP Port=-1, id={-15 -5 -50 50 41 119 73 -57 -89 103 25 62 3 -100 -77 -108 }, payload={}, command={}, domain={}, ]

7. Tomcat Session Clustering Test

A. “Tomcat Session Clustering Test” 아래 내용 참고하여 index.jsp 파일 생성

<%@ page contentType="text/html; charset=euc-kr" %> <% System.out.println( "Session ID : " + session.getId() ); %> <HTML> <HEAD> <TITLE>Session Clustering Test</TITLE> </HEAD> <BODY> <h1>Session Clustering Test</h1> <% Integer ival = (Integer)session.getAttribute("_session_counter"); if(ival==null) { ival = new Integer(1); } else { ival = new Integer(ival.intValue() + 1); } session.setAttribute("_session_counter", ival); System.out.println("here~~~~"); %> Session Counter = [<b> <%= ival %> </b>]<p> <a href="./sc.jsp">[Reload]</a> <p> Current Session ID : <%= request.getRequestedSessionId() %><br /> <center><h3>[ 세션 정보를 얻어오는 메소드를 사용한 예제 ]</h3></center> <hr> <% String id_str=session.getId(); long lasttime=session.getLastAccessedTime(); long createdtime=session.getCreationTime(); long time_used=(lasttime-createdtime)/60000; int inactive=session.getMaxInactiveInterval()/60; boolean b_new=session.isNew(); %> [1] 세션 ID[<%=session.getId()%>] 입니다.<br><hr> [2] 당신의 웹사이트에 머문 시간은 <%=time_used%> 입니다.<br><hr> [3] 세션의 유효시간은 <%=inactive%> 분입니다.<br><hr> [4] 세션이 새로 만들어 졌나요?<br><hr> <% if(b_new) out.println("예 !! 새로운 세션을 만들었습니다."); else out.println("아니오 !! 새로운 세션을 만들지 않았습니다."); %> <hr> </BODY> </HTML>

B. Session Clustering 확인

http://LBIP/index.jsp 접속

→ WEB서버 상단에는 LB가 있으므로 LB IP로 접근하여 확인

1. WEB 서버 2대는 LB로 이중화 되어있으므로 1대 서버에 장애가 발생하여도 Session은 동일

2. WAS 서버 2대 또한 mod_jk 설정으로 이중화 되어있으므로 1대 서버에 장애가 발생하여도 Session은 동일

※ Tomcat 8.x 특이사항

톰캣 8.x 버전에서 server.xml 중 아래 옵션 넣을 시 실행 에러가 발생하고 있습니다.

8.x 버전 넘어오면서 없어진 라이브러리로 확인되며 해당 옵션 없어도 클러스터링 정상 동작

<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>

- 시스템통합운영센터

728x90