본문 바로가기
오픈소스/Tomcat

[TOMCAT] 톰캣 세션 클러스터링 테스트

by sangyeon 2021. 12. 6.
728x90

이번 글에서는 아파치 톰캣 9.0에서 세션 클러스터링 테스트 내용을 정리해보고자 한다.

 

세션 클러스터링이란 간단하게 설명하면, WAS간의 세션을 공유하는 기술이다.

 

대부분의 시스템이라면 WAS 인스턴스를 다수 기동시켜 운영할텐데, 그 중 하나의 WAS가 장애가 났을 때 다른 WAS에서 세션 정보를 read하여 사용자로 하여금 지속적인 서비스를 제공받을 수 있게끔하는 기술이다.

 

 

이 글은 아파치 공식문서의 내용을 정리하여 작성하였다.

https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html

 

Apache Tomcat 9 (9.0.55) - Clustering/Session Replication How-To

Simply add to your or your element to enable clustering. Using the above configuration will enable all-to-all session replication using the DeltaManager to replicate session deltas. By all-to-all, we mean that every session gets replicated to all the other

tomcat.apache.org

 

1. server.xml 수정

- server.xml > 141 Line "<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>" 주석 해제

- server.xml > 136 Line "<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">" 

jvmRoute에 tomcat 서버명으로 변경(JSESSION ID 끝에 어떤 서버에서 서비스 중인지 tag를 걸 때 사용)

- server.xml > about 176 Line에 하기 내용 추가

##################################################################
<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"
                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.MessageDispatchInterceptor"/>
    </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>
 </Engine>
</Service>
</Server>
##################################################################

> 위 설정에서 몇 가지 중요한 값이 있다.

 

- 세션 매니저 DeltaManager는 all-to-all 세션 복제로 모든 세션 클러스터 멤버에 데이터를 저장한다. 이 방법은 소규모 클러스터에 적합하지만, 노드가 4개 이상인 대규모 클러스터에서는 권장하지 않음. 

(다른 옵션으로는 BackupManager가 있으며 이는 Primary/Backup 방식으로 데이터를 복제함)

- 멀티캐스트 주소 : 228.0.0.4

- 멀티캐스트 포트 : 45564

- 세션 복제 메세지를 수신하는 TCP 포트 : 4000(port-range 4000-4100)

* 해당 포트는 각 인스턴스별로 고유해야 함

- 리스너는 ClusterSessionListener, 인터셉터는 TcpFailureDetector와 MessageDispatchInterceptor가 설정된다.

 

 

2. Application web.xml에 파라미터 추가

> web.xml에 <distributable/> 추가

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
    
    <distributable/>

    <display-name>Hello, World Application</display-name>
    <description>
This is a simple web application with a source code organization
based on the recommendations of the Application Developer's Guide.
    </description>

</web-app>

 

3. 세션 클러스터링 테스트

테스트 시나리오

- ohs web proxy를 통해 호출

- tomcat1 shutdown

- tomcat2 번으로 기존 세션ID로 count가 초기화되지 않고 증가하는지 확인


> JSESSIONID 뒤에 .tomcat1을 보면 tomcat1번 서버에서 처리 중인 것을 확인할 수 있다.

###############################################################################
tomcat1번 서버 shutdown
###############################################################################

[root@sydev bin]# ./stop.sh
====================================================
JAVA_HOME=/usr/java/java8_64
CATALINA_HOME=/apache/tomcat_9.0.21/engine
SERVER_HOME=/apache/tomcat_9.0.21/servers/testM1
HTTP_PORT=8083
SSL_PORT=8443
AJP_PORT=8009
SHUTDOWN_PORT=8005
Using CATALINA_BASE:   /apache/tomcat_9.0.21/servers/testM1
Using CATALINA_HOME:   /apache/tomcat_9.0.21/engine
Using CATALINA_TMPDIR: /apache/tomcat_9.0.21/servers/testM1/temp
Using JRE_HOME:        /usr/java/java8_64
Using CLASSPATH:       /apache/tomcat_9.0.21/engine/bin/bootstrap.jar:/apache/tomcat_9.0.21/servers/testM1/bin/tomcat-juli.jar


> JSESSIONID 뒤에 .tomcat2로 변경됨으로써 tomcat 2번 서버에서 세션 공유를 통해 사용자에게 지속적인 서비스를 제공하고 있다.

 

4. BackupManager 설정 방법

4-1. 설정방법

- server.xml의 <Cluster> 태그 내에 

<Manager className="org.apache.catalina.ha.session.BackupManager">를 선언하면 활성화 됨.

 

4-2. 동작방식

 

- 인스턴스가 세션을 생성하면 해당 인스턴스가 세션의 primary 노드가 된다. 다른 하나의 노드는 backup 노드가 되며 둘은 제외한 모든 다른 노드는 proxy 노드가 된다.

(ex. nodeA = primary, nodeB = backup, node C,D = proxy)

 

- nodeA에서는 생성된 세션 정보를 Local에 저장하고 나머지 node 중 1개(backup)에 복제 세션 정보를 전송한다. 

(backup이 결정되는 기준은 노드간 heartbeat 교환을 하면서 처음으로 인지된 노드가 된다.)

 

- nodeA에서는 node C와 D에 세션 아이디 값의 primary 저장 위치(node A) 값을 전달하여 nodeA는 Primary, nodeB는 backup, node C, D는 Porxy가 된다.

 

- 이후 클라이언트가 node C또는 D에 접속해 해당 세션 정보를 조회하면 해당 노드에서는 node A에 요청해서 서비스를 제공한다.

(node A와 B는 자체적으로 세션정보를 가지고 있기 때문에 바로 서비스를 제공)

 

 

5. 기타

AWS를 포함한 모든 클라우드 서비스는 멀티캐스트를 지원하지 않고 있어 tomcat clustering 방식을 사용할 수 없다.

 

 

 

728x90