모래성 말고 철옹성

[Tomcat] 톰캣 클러스터링 - Multicast 본문

DevOps/SRE

[Tomcat] 톰캣 클러스터링 - Multicast

JDhyeok 2025. 9. 3. 00:35

들어가며

회사에서 아주 오래된 On-premise서버의 OS가 EoS가 되며, 신규 서버로 Clean-install을 진행하며 tomcat을 처음부터 다시 설치해야하는 요건이 생겼다.

이중화 구조여서 Clustering을 해야했고, 직면한 문제가 있어 트러블슈팅한 기록과 알게된 개념을 남긴다.

문제 발생

기존 Tomcat 을 기동하니 아래와 같은 오류가 발생했다.

Unable to join multicast group, make sure your system has multicasting enabled.
Unable to start cluster.

알아보니 내가 맡게된 서버의 tomcat은 Multicast 방식으로 clustering 하고 있었다. 보통 내 구축 경험으로는 Unicast로 1:1 통신을 통한 clustering을 했는데, 이런 Multicast 방식은 생소했고 어떤 통신 방식인지 궁금해졌다.

 

아래 설정은 Unicast, Multicast 방식이니 참고하길 바란다.

더보기
더보기

# Multicast Clustering server.xml 설정 예시

<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>

 

# Unicast Clustering server.xml 설정 예시

(Tomcat 9부터 공식 지원된다)

<Cluster channelSendOptions="8" channelStartOptions="3" className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
<Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/>
<Channel className="org.apache.catalina.tribes.group.GroupChannel">
  <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
    <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
  </Sender>
  <Receiver address="1.1.1.1" autoBind="0" className="org.apache.catalina.tribes.transport.nio.NioReceiver" maxThreads="6" port="3101" selectorTimeout="5000"/>
  <Interceptor className="org.apache.catalina.tribes.group.interceptors.StaticMembershipInterceptor">
    <Member className="org.apache.catalina.tribes.membership.StaticMember" port="3101" host="1.1.1.2" uniqueId="{0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2}"/>
  </Interceptor>
</Channel>
	<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

 

Multicast란? (feat. Unicast, Broadcast)

간단히 비교해보면

  • Unicast: 1:1 통신 (클라이언트 → 서버)
  • Broadcast: 네트워크 대역 내 모든 장비에 뿌림
  • Multicast: 특정 그룹에 가입된 장비들만 받음

Tomcat은 같은 클러스터에 속한 서버들이 서로의 상태를 주고받기 위해 멀티캐스트 그룹에 조인(join) 하는 구조를 사용한다. 예를 들어, 세션 변경 사항을 동시에 여러 서버에 전송할 때 Multicast가 효율적이다.

<Membership className="org.apache.catalina.tribes.membership.McastService"
      address="228.0.0.4"
      port="45564"
      frequency="500"
      dropTime="3000" />

 

이렇게 Tomcat을 사용하게 되면

  • Tomcat 노드들은 228.0.0.4:45564 멀티캐스트 그룹에 들어간다.
  • 각 노드는 0.5초(500ms)마다 hearbeat 신호를 그룹에 UDP 통신으로 전송한다.
  • 만약 어떤 노드가 3초 동안 응답하지 않으면, 클러스터에서 제외된다.

문제가 뭘까?

Unable to join multicast group, make sure your system has multicasting enabled.
Unable to start cluster.

위 에러로 보았을 때 Tomcat이 Multicast 그룹에 가입을 시도했으나 실패했다는 의미.

이 경우 원인은 OS 레벨과, 네트워크 장비 레벨 둘 중 하나일 것이라 판단했다.

  • 서버/OS 레벨
    • NIC(Network Interface Card)가 멀티캐스트를 미지원
    • 방화벽에서 멀티캐스트 트래픽 차단
  • 네트워크 장비 정책
    • 스위치/라우터 단에서 멀티캐스트 패킷을 필터링 하는 경우
    • IGMP Snooping 설정이 필요하거나, 방화벽 정책 때문에 막히는 경우

아직 네트워크 담당자에게 확인 중이라 결과는 더 지켜봐야 하지만, 둘 중 하나로 예상된다.

 

내 환경은 보안이 중요시되는 폐쇄망 환경이다 보니 whitelist 기반으로 접근하다 보니 초기 설정에 공수가 많이 든다. 특히 오래된 서버일 수록 히스토리가 쌓이고 담당자가 변경되다 보면 이런 경우가 많은데, 이런 조사를 어떻게 해야할지 고민해 봐야겠다.

대안 아키텍처

만약 네트워크단에서 Multicast가 안된다면, tomcat9은 Unicast가 가능하지만 tomcat7,8 에는 Unicast가 공식 지원이 아니기에 불가능은 아니지만 권장되진 않을것이다. 그렇다면 StickySession, 혹은 third-party로 redis같은 메모리 캐시를 두면 되지 않을까 싶다.

반응형
Comments