본문 바로가기

리눅스

톰캣 인스턴스 간의 멀티캐스트 기반 세션 클러스터링을 설정하는 방법

반응형

톰캣 인스턴스 간의 멀티캐스트 기반 세션 클러스터링을 설정하는 방법

JDK, NGINX, Tomcat 설치 및 구성

curl -fsSL https://raw.githubusercontent.com/anti1346/zz/main/ubuntu/install_jdk_nginx_tomcat.sh | bash

NGINX 설정

vim /etc/nginx/conf.d/default.conf
upstream tomcat_servers {
    server localhost:8081;  # 첫 번째 Tomcat 인스턴스
    server localhost:8082;  # 두 번째 Tomcat 인스턴스
}

server {
    listen 80;
    
    server_name localhost;

    access_log /var/log/nginx/host.access.log main;

    location / {
        proxy_pass http://tomcat_servers;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo systemctl restart nginx

Tomcat 설정

server.xml 파일 수정

  • 각 톰캣 인스턴스의 server.xml 파일을 열어 클러스터 설정을 추가합니다.
  • server.xml 파일의 <Engine>요소 내에 <Cluster>요소를 추가합니다. 멀티캐스트 주소, 포트, 주기, 타임아웃 등을 설정합니다.
vim /app/tomcat/tomcat1/conf/server.xml
<Server port="8001" shutdown="SHUTDOWN">
  <!-- 기존 설정 유지 -->

  <Service name="Catalina">
    <Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8501" />
    
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
      <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" />
                      
          <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
            <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender" />
          </Sender>
          
          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="auto"
                    port="4000"
                    autoBind="100"
                    selectorTimeout="5000"
                    maxThreads="6" />
                    
          <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="" />
        <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" />
      </Cluster>
      
      <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>
  </Service>
</Server>
cp /app/tomcat/tomcat1/conf/server.xml /app/tomcat/tomcat2/conf/server.xml
  • tomcat2의 설정은 jvmRoute를 tomcat2로 변경하고 다른 설정은 동일하게 유지합니다.
vim /app/tomcat/tomcat2/conf/server.xml

server.xml 설정 예시

더보기

---

  • tomcat1의 server.xml 설정 예시
<Server port="8001" shutdown="SHUTDOWN">

  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">

    <Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8501"
               maxParameterCount="1000"
               />

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
      <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" />

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

          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="auto"
                    port="4000"
                    autoBind="100"
                    selectorTimeout="5000"
                    maxThreads="6" />

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

      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <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>
  </Service>
</Server>
  • tomcat2의 server.xml 설정 예시
<Server port="8002" shutdown="SHUTDOWN">

  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">

    <Connector port="8082" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8502"
               maxParameterCount="1000"
               />

    <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat2">
      <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" />

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

          <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="auto"
                    port="4000"
                    autoBind="100"
                    selectorTimeout="5000"
                    maxThreads="6" />

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

      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <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>
  </Service>
</Server>

---

web.xml 파일에 <distributable/> 요소 추가

톰캣에서 세션 클러스터링을 사용하려면 세션을 공유하고자 하는 각 웹 애플리케이션의 web.xml 파일에 <distributable/> 요소를 추가해야 합니다.

  • <distributable/> : 이 요소를 추가하면 해당 웹 애플리케이션이 클러스터 환경에서 동작할 수 있게 됩니다. 이 요소가 포함된 애플리케이션의 세션은 클러스터된 모든 톰캣 인스턴스 간에 복제되고 공유됩니다.
vim /app/tomcat/tomcat1/webapps/ROOT/WEB-INF/web.xml
   <!-- 세션 클러스터링을 위한 distributable 요소 -->
   <distributable/>
cp /app/tomcat/tomcat1/webapps/ROOT/WEB-INF/web.xml /app/tomcat/tomcat2/webapps/ROOT/WEB-INF/web.xml
vim /app/tomcat/tomcat2/webapps/ROOT/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
  version="4.0"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>

  <!-- 세션 클러스터링을 위한 distributable 요소 -->
  <distributable/>

</web-app>

context.xml 파일의 <Context> 요소 수정

  • <Context 요소>에 docBase, path, reloadable, crossContext, sessionCookiePath 속성을 설정합니다.
vim /app/tomcat/tomcat1/conf/context.xml
<?xml version="1.0" encoding="UTF-8"?>

<Context path="" docBase="." reloadable="true" crossContext="true" sessionCookiePath="/">

    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
        <Store className="org.apache.catalina.session.FileStore" directory="/app/tomcat/sessions" />
    </Manager>
</Context>
vim /app/tomcat/tomcat2/conf/context.xml
<?xml version="1.0" encoding="UTF-8"?>

<Context path="" docBase="." reloadable="true" crossContext="true" sessionCookiePath="/">

    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true">
        <Store className="org.apache.catalina.session.FileStore" directory="/app/tomcat/sessions" />
    </Manager>
</Context>
728x90

서버 재시작

  • 각 톰캣 인스턴스를 시작합니다.
sudo systemctl restart tomcat1 tomcat2

로그 확인

  • 각 인스턴스의 로그 파일을 확인하여 클러스터링이 올바르게 설정되었는지 확인합니다.
tail -f /app/tomcat/tomcat1/logs/catalina.out
tail -f /app/tomcat/tomcat2/logs/catalina.out

세션 정보 출력 JSP 파일 생성

  • 세션 정보를 출력하는 sessioninfo.jsp 파일입니다.
vim /app/tomcat/tomcat1/webapps/ROOT/sessioninfo.jsp
<!DOCTYPE html>
<html>
<head>
    <title>HttpSession Information</title>
</head>
<body>
    <h1>HttpSession Information:</h1>
    <p>Served From Server: <%= request.getServerName() %></p>
    <p>Server Port Number: <%= request.getServerPort() %></p>
    <p>Executed From Server: <%= request.getLocalName() %></p>
    <p>Executed Server IP Address: <%= request.getLocalAddr() %></p>
    <p>Instance Path: <%= application.getRealPath("/") %></p>
    <p>Session ID: <%= session.getId() %></p>
    <p>Session Created: <%= new java.util.Date(session.getCreationTime()) %></p>
    <p>Last Accessed: <%= new java.util.Date(session.getLastAccessedTime()) %></p>
    <p>Session will go inactive in <%= session.getMaxInactiveInterval() %> seconds</p>
</body>
</html>
cp /app/tomcat/tomcat1/webapps/ROOT/sessioninfo.jsp /app/tomcat/tomcat2/webapps/ROOT/sessioninfo.jsp

웹 브라우저 테스트

http://localhost/sessioninfo.jsp

sessioninfo_jsp

  • 세션 파일 확인
ls -l /app/tomcat/sessions
$ ls -l
total 8
-rw-r----- 1 tomcat tomcat 265 May 21 12:04 819075992C7383C6823E5237BD154055.tomcat2.session
-rw-r----- 1 tomcat tomcat 265 May 21 12:04 FED5B41551A501E3507CBD61174F7491.tomcat1.session

 

참고URL

- Apache Tomcat Documentation : Clustering/Session Replication How-To

 

728x90
반응형