확장성을 위한 Tomcat 클러스터링 구성과 설정 방법

Tomcat Clustering (톰캣 클러스터링)

Tomcat 클러스터링은 여러 대의 Tomcat 서버를 함께 동작시켜 고가용성과 확장성을 제공하는 기술입니다. 클러스터링을 구성하면 트래픽 분산과 장애 대응을 위해 여러 서버가 협력하여 웹 애플리케이션을 처리할 수 있습니다.

  • `server.xml`에서 기본적인 클러스터 설정:
<!-- Connector 설정 -->
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           enableLookups="false"
           maxThreads="200"
           minSpareThreads="10"
           maxSpareThreads="100"
           acceptCount="100"
           disableUploadTimeout="true"
           enableLookups="false" />

<!-- Engine 설정 -->
<Engine name="Catalina" defaultHost="localhost">

    <!-- Cluster 설정 -->
    <Cluster 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">
            <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"
                      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="" />
        <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
    </Cluster>

    <!-- Host 설정 -->
    <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
    </Host>

</Engine>

 

  • 로드 밸런서 구성:
    클러스터링을 위해 로드 밸런서를 설정합니다. 로드 밸런서는 들어오는 요청을 여러 대의 Tomcat 서버로 분산하는 역할을 수행합니다. 일반적으로 Apache HTTP Server나 Nginx와 같은 웹 서버를 로드 밸런서로 사용합니다. 
    세션 복제 설정과 캐시 설정은 클러스터 내의 Tomcat 서버에서도 동일하게 구성해주어야 합니다. 이 부분은 아래 세션복제 설정과 캐시 설정을 각각 설명할 때 하도록 하겠습니다.      

nginx:

http {
    ...

    # 로드 밸런서 설정
    upstream tomcat_cluster {
        server tomcat-server1:8080;
        server tomcat-server2:8080;
        # 필요한 만큼 Tomcat 서버를 추가합니다.
    }

    # 세션 복제 설정
    # sticky:        세션 고정을 위해 사용 클라이언트와 연결된 Tomcat 서버가 변경되더라도 동일한 세션을 유지할 수 있도록 합니다.
    # sticky_header: 세션 식별을 위한 헤더를 설정. 클라이언트의 세션 ID를 사용하여 세션을 고정시킵니다.
    # upstream_session_cookie: 세션 식별에 사용될 쿠키를 지정.
    sticky;    
    sticky_header X-Session-ID;
    upstream_session_cookie session_id;

    # 캐시 설정
    # proxy_cache_path:      프록시 서버의 캐시 디렉토리와 설정을 정의.
    # proxy_cache_key:       캐시 키를 지정.
    # proxy_cache:           캐시를 사용할지 여부를 설정.
    # proxy_cache_valid:     캐시의 유효 기간을 정의.
    # proxy_cache_use_stale: 캐시 사용 중에 오류가 발생할 경우 오래된 캐시를 사용할지를 설정.
    proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
    proxy_cache_key "$scheme$request_method$host$request_uri";

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://tomcat_cluster;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;

            # 세션 복제 헤더 설정
            proxy_set_header X-Session-ID $http_cookie;

            # 캐시 설정
            proxy_cache my_cache;
            proxy_cache_valid 200 304 10m;
            proxy_cache_valid any 5m;
            proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        }
    }

    ...
}

 

  • 세션 복제 설정:
    클러스터 내의 서버들은 세션 정보를 공유하기 위해 세션 복제를 설정합니다. 세션 복제는 각 서버에서 생성된 세션 데이터를 다른 서버들과 동기화하여 일관성을 유지합니다. 이를 위해 요소를 사용하여 세션 관리자를 설정하고, 데이터를 공유할 위치를 지정합니다.

 

  • 캐시 설정:
    클러스터링 환경에서는 캐시 설정을 최적화하여 성능을 향상시킵니다. 정적 콘텐츠나 데이터베이스 쿼리 결과와 같이 자주 사용되는 데이터를 캐싱하여 중복된 작업을 피하고 응답 시간을 단축시킵니다.
    캐시 설정은 Tomcat의 `context.xml` 파일에 추가해주어야 합니다.  
<Context>
    ...
    <!-- 캐시 설정 -->
    <Resources cachingAllowed="true" cacheMaxSize="100000" cacheObjectMaxSize="1000">
        ...
    </Resources>
    ...
</Context>

 

  • 멀티캐스트 또는 유니캐스트 설정:
    클러스터 내의 서버들은 상호간의 통신을 위해 멀티캐스트나 유니캐스트 방식을 사용합니다. 멀티캐스트는 네트워크에서 멀티캐스트 그룹으로 메시지를 보내는 방식이며, 유니캐스트는 각 서버에 직접 메시지를 전송하는 방식입니다. 사용하는 네트워크 환경에 맞게 적절한 설정을 선택합니다.

 

  • 공유 리소스 설정:
    클러스터링된 서버들이 공유하는 리소스를 설정합니다. 예를 들어, 공유 디렉토리를 설정하여 파일 업로드나 파일 다운로드 시에 서버 간에 리소스를 공유할 수 있도록 합니다.
    • <Host> 요소 내에 <Context> 요소를 추가하여 공유 리소스 경로 지정 
    • 클러스터 내에서 공유할 디렉터리: `/shared`로 설정
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
    ...
    <Context path="/shared" docBase="/shared" />
    ...
</Host>