tomcat_clustering

Tomcat Clsutering

이강우 2020/12/08 17:19

본 문서는 Tomcat 8.x 이상에서 정상 동작함을 확인하였습니다. Tomcat 7.x 이하에서는 테스트 되지 않았습니다.

Tomcat Clustering 관련 문서는 공식문서 https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html 를 참조하면 아주 쉽게 구성할 수 있다.

  • web.xml 내에 <distributable/> 선언 필수
  • Session attributes는 반드시 java.io.Serializable을 구현해야합니다. 만약 그렇지 않다면 sessionAttributeFilter를 사용할 수 있습니다.
  • DeltaManager를 사용하는 경우에는 org.apache.catalina.ha.session.ClusterSessionListener가 필요합니다.
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

위의 내용만 추가하면 바로 구성할 수 있다.

위 구성을 사용하면 DeltaManager를 사용 하여 전체 세션 복제를 활성화 할 수 있습니다. 모든 세션이 클러스터 의 다른 모든 노드 에 복제 됨을 의미 합니다. 소규모 클러스터에는 효과적이지만 4 개 이상의 노드와 같은 대규모 클러스터에는 권장하지 않습니다.
또한 DeltaManager를 사용할 때 Tomcat은 모든 노드, 심지어 애플리케이션이 배포되지 않은 노드까지 세션을 복제합니다 .

이 문제를 해결하려면 BackupManager를 사용하여야 합니다. BackupManager는 세션 데이터를 단지 응용 프로그램이 배포 된 노드에만 복제 합니다. 클러스터의 노드 수를 4대이상 늘릴 예정이라면 DeltaManagerBackupManager로 마이그레이션하는 것이 좋습니다.

다음은 몇 가지 중요한 기본값입니다.

  • 멀티 캐스트 주소는 228.0.0.4입니다.
  • 멀티 캐스트 포트는 45564입니다 (포트와 주소는 클러스터 구성원을 결정합니다)
  • 브로드 캐스트 된 IP는 java.net.InetAddress.getLocalHost().getHostAddress() 입니다. (127.0.0.1을 브로드 캐스트하지 않아야합니다. 이는 일반적으로 오류를 발생시킵니다)
  • 복제 메시지를 수신하는 TCP 포트는 4000-4100 범위에서 사용 가능한 첫 번째 서버 소켓입니다.
  • 리스너는 ClusterSessionListener로 구성됩니다.
  • TcpFailureDetectorMessageDispatchInterceptor 두 개의 인터셉터가 구성됩니다.

네트워크간에 Multicast가 차단되어있어서 노드간 클러스터 확인이 되지 않는경우가 있다. 요즘 최신의 네트워크 스위치 제품들은 기본적으로 IGMP가 차단되어 있는경우가 많기때문에 이런일이 빈번하다.
해결방법은 당연히 IGMP를 차단 해제 해주고 Multicast를 이용하면 되지만 여타 여건상 안되는경우 TCP로 Static Cluster Membership을 구성하면 된다.

  1. McastService Membership을 제거한다.
  2. TCPPingInterceptor 구성
  3. StaticMembershipInterceptor 구성

다음은 TCP StaticMember 클러스터 구성 예제 입니다.

        <!-- channelSendOptions 값이 6:동기 방식 8:비동기 방식
        8:비동기 방식 사용시 Receiver의 selectorTimeout을 5000(5초) 이상으로 설정 권장 -->
        <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="6" channelStartOptions="3">

          <!-- Delta Manager -->
          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

          <!-- Backup Manager
          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"
                   mapSendOptions="6"/>
          -->

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">

            <!-- Multicast Member -->
            <!--
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="${tomcat.cluster.member.address}"
                        port="${tomcat.cluster.member.port}"
                        frequency="500"
                        dropTime="3000"/>
            -->

            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="${tomcat.cluster.receiver.address}"
                      port="${tomcat.cluster.receiver.port}"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>

            <!-- 이 인터셉터는 모든 노드에 핑으로 체크를 해주는 인터셉터이다.
                 이 인터셉터는 다른 노드가 클러스터를 떠났을 때 모든 노드가 인식 할 수 있도록 다른 노드를 ping 체크한다.
                 이 클래스가 없으면 클러스터가 제대로 작동하는 것처럼 보일 수 있지만 노드를 제거하고 다시 도입하면 세션 복제가 중단 될 수 있다.
                 TcpFailureDetector보다 위쪽에 위치하여야 한다. -->
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpPingInterceptor"/>
            
            <!-- 멤버간 데이터 통신 오류 또는 시간 초과등의 문제가 발생하였을시 감지하는 인터셉터 -->
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>

            <!-- StaticMember 인터셉터는 멀티캐스팅멤버 대신에 고정값으로 사용할때 선언한다. -->
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
              <!-- 자기자신 선언
                   9.0.17 버전 이후로는 LocalMember대신 Member로 동일하게 설정해도 된다.
                   https://tomcat.apache.org/tomcat-9.0-doc/config/cluster-membership.html#Setting
              -->
              <LocalMember className="org.apache.catalina.tribes.membership.StaticMember"
                           domain="staging-cluster"
                           uniqueId="{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1}"/>

              <!-- 고정멤버로 선언할 다른 노드 정보 -->
              <Member className="org.apache.catalina.tribes.membership.StaticMember"
                      port="4000"
                      securePort="-1"
                      host="tomcat2"
                      domain="staging-cluster"
                      uniqueId="{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,2}"/>
            </Interceptor>

          </Channel>

          <!-- 해당 필터에 포함되는 요청은 세션데이터 갱신에서 제외한다 -->
          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

          <!-- route 변경시 현재 jvmRoute를 변경해주는 밸브.
               이게 없는경우 route가 변경되어도 jvmRoute값이 유지되어 failback효과를 유도한다 -->
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

          <!-- 클러스터 노드간 자동배포를 위한 디플로이어 일반적으로 사용하지 않으며 <Host 엘리먼트에 넣어야 정상 동작함
          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>
          -->

          <!-- DeltaManager 사용시 필요함 -->
          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

로그인하면 댓글을 남길 수 있습니다.
  • tomcat_clustering.txt
  • 마지막으로 수정됨: 2020/12/08 11:32
  • 저자 koov