반응형
톰캣 인스턴스 간의 멀티캐스트 기반 세션 클러스터링을 설정하는 방법
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 "%r" %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 "%r" %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 "%r" %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
- 세션 파일 확인
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
반응형
'리눅스' 카테고리의 다른 글
YUM EPEL 저장소에서 메타링크를 가져올 수 없는 오류 (0) | 2024.05.28 |
---|---|
apt-cacher-ng 컨테이너를 Docker Compose로 설정하는 방법 (0) | 2024.05.27 |
우분투에 Laravel을 설치하고 HelloWorld 프로젝트를 생성하여 웹 브라우저에서 테스트하는 방법 (0) | 2024.05.20 |
Redis를 통한 세션 클러스터링을 구현하는 방법 (0) | 2024.05.20 |
Tomcat 세션 클러스터링이란 무엇일까요? (0) | 2024.05.20 |