출처: https://www.didim365.com/blog/20200526-blog-2/
이번 테크 포스팅에서는 톰캣 세션 클러스터링(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 확인
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 확인
→ 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”/>
작성 : 시스템통합운영센터
'프로그램 활용 > 웹서버' 카테고리의 다른 글
AJP (0) | 2023.10.24 |
---|---|
세션 클러스터링 (1) | 2023.10.23 |
[분산처리] WAS 이중화와 세션클러스터링 (1) | 2023.10.23 |
로드 밸런싱 & 인프라 이중화 구축 (1) | 2023.10.23 |
톰캣 세션 클러스터링 (0) | 2023.08.16 |