Apache + Tomcat 세션 클러스터링
- -
로드밸런싱을 사용하여 Apache + Tomcat(N개) 환경을 구성했을 때, 일반적인 서비스에서 세션 클러스터링은 필수일 것입니다. 오늘은 세션 클러스터링 설정에 관한 내용을 정리해봤습니다.
해당 포스팅에서는 Apache, Tomcat은 설치 및 서비스 등록이 되어 있다는 가정하에 로드밸런싱 설정부터 소개합니다.
테스트 환경
- Windows 10
- Spring boot
- Tomcat 9
먼저 로드밸런싱 테스트를 위해 index.jsp 페이지를 다음과 같이 만들었다.
WAS1 : port - 8080 / ajp - 8009
WAS2 : port - 8090 / ajp - 8099
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
Hello world1<br>
session : <%=session.getId() %>
</body>
</html>
1. 로드밸런싱
1-1. Apache 설정
먼저 Apache + Tomcat 연동을 위해 mod_jk를 사이트에서 다운받는다.
다운받은 mod_jk.so를 apache가 설치된 폴더 - modules 폴더로 옮긴다.
Apache 설정 파일 httpd.conf 파일이 위치한 폴더(보통은 Apache24-conf)에 workers.properties(로드밸런싱 설정 파일)을 생성한다.
workers.properties
worker.list=loadbalancer
worker.loadbalancer.type=lb
worker.loadbalancer.balance_workers=was1,was2
worker.was1.type=ajp13
worker.was1.host=localhost
worker.was1.port=8009
worker.was1.lbfactor=1
worker.was2.type=ajp13
worker.was2.host=localhost
worker.was2.port=8099
worker.was2.lbfactor=1
그리고 httpd.conf 파일에 아래와 같이 설정 파일을 추가해준다.(위치는 자유)
httpd.conf
LoadModule jk_module modules/mod_jk.so
<IfModule jk_module>
JkWorkersFile conf/workers.properties
JkLogStampFormat "[%a %b %d %H: %M: %S %Y]"
JkLogFile "|bin/rotatelogs.exe -l logs/mod_jk_%Y%m%d.log 86400"
JkLogLevel Info
JkMount /* loadbalancer
</IfModule>
1-2. Tomcat 설정
각각의 Tomcat - server.xml에 AJP 포트에 대한 주석을 풀어주면 된다.
AJP 기본 포트는 8009이며, 현재 같은 서버내에서 두 대의 Tomcat을 돌리는 환경이기에 충돌 방지를 위해 WAS2는 8099로 설정했다.
server.xml
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector protocol="AJP/1.3" port="8009" redirectPort="8443" secretRequired="false"/>
server.xml
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector protocol="AJP/1.3" port="8099" redirectPort="8443" secretRequired="false"/>
로드밸런싱 설정은 여기까지이다. Apache, Tomcat 실행을 해서 접속을 할 때마다 세션 아이디가 달라진다면 성공이다.
2. 세션 클러스터링
이제 두 대의 WAS 세션을 공유하여 세션 아이디가 같도록 변경시키는 작업을 해보자.
Spring boot가 아니라면 web.xml을 설정하는 방법이 있다.
@SpringBootApplication 어노테이션이 위치한 메인 클래스에서 ServletWebServerFactory 클래스 빈을 등록해준다.
WasTestApplication.java
package com.example.demo;
import org.apache.catalina.Context;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class WasTestApplication {
public static void main(String[] args) {
SpringApplication.run(WasTestApplication.class, args);
}
private static boolean distributable;
public static boolean getDistributable() {
return distributable;
}
@Bean
public ServletWebServerFactory tomcatFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
WasTestApplication.distributable = context.getDistributable();
}
};
}
}
각각의 Tomcat - server.xml에 <Engine> 태그에 jvmRoute 설정을 추가한다.
이 때 jvmRoute값은 Apache 로드밸런싱 설정시 지정한 workers 이름을 입력한다.
worker.loadbalancer.balance_workers=was1,was2
<Engine name="Catalina" defaultHost="localhost" jvmRoute="was1">
<Engine name="Catalina" defaultHost="localhost" jvmRoute="was2">
<Engine> 태그 아래에 주석처리된 <Cluster> 태그를 해제해주고 아래와 같이 추가한다.
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="10"
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"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
설정이 잘되었다면 접속을 여러번해도 같은 세션 아이디가 조회되는 것을 확인할 수 있다.
참고자료
'Server' 카테고리의 다른 글
[Error]java.io.EOFException (0) | 2023.09.08 |
---|---|
[Tomcat]JNDI 설정으로 인한 오류 (0) | 2023.03.02 |
[WAS]Tomcat 한글 깨짐(???? 현상) (0) | 2020.09.15 |
[WAS]POST 방식에서 파라미터 개수 제한 (0) | 2020.05.26 |
아파치 SSL 설정 (5) | 2020.02.05 |
소중한 공감 감사합니다.