세션 클러스터링이란 두 개 이상의 WAS가 있을 때 두 개 이상의 WAS에서 같은 세션을 사용하게 처리하는것을 말합니다.
모든 서비스에서 세션이 중요하지만, 특히 실시간으로 빠르게 돈의 이동이 잦은 증권사나 은행같은 기관의 서비스 경우 서버가 아무리 이중화, 삼중화 돼있다고 해도 사용자가 속해있는 WAS서버가 다운됐을 때, 세션이 끊어지고 말텐데요.
아주 치명적이겠죠. 이럴 때를 대비해 어떤 기관에서는 세션만을 관리하는 별도의 세션 서버를 두기도 하죠.
이번 포스팅에서는 톰캣에서 세션을 공유하는 방법을 알아보려고 합니다.
WAS별로 세팅방법이 조금씩 다르지만, WAS설정으로 세팅할 수 있습니다.
로드밸런싱과의 차이는 분산이라고 합니다.
저는 로드밸런싱은 길을 두개로 나눠 부하를 나누는 것이고
세션 클러스터링은 같은 울타리 안에 있는 느낌으로 이해했습니다.
수정해주어야 하는 부분은 단 두 파일입니다.
server.xml과 web.xml
server.xml은 톰캣을 설치한 경로의 conf 폴더 밑에 있을것이고,
web.xml은 웹 어플리케이션의 WEB-INF 밑에 있겠죠.
스프링 부트에서는 web.xml을 배제하고 자바코드로 구현하기 때문에 자바 파일에 설정을 해주어야 되겠습니다.
server.xml에 추가해야하는 코드는
web.xml에 추가해야하는 코드는 다음과 같습니다.
</web-app> 전에 넣어주시면 되겠습니다.
<distributable/>
다음은 톰캣의 server.xml에 추가하는 코드입니다. 포트 사용을 위해 해당 포트를 방화벽 오픈해야합니다.
Membership과 Receiver의 포트 45564, 4000 포트는 각각 세션 공유와 세션 수신을 위한 포트이며,
channelSendOptions 의 8 은 비동기 방식입니다.
https://tomcat.apache.org/tomcat-8.5-doc/config/cluster.html#SimpleTcpCluster_Attributes
<!-- apache jk_mod의 경우 jvmRoute값을 이용하여 사용 was 판단 -->
<Engine name="Catalina" defaultHost="localhost" jvmRoute="was1">
<!-- channelSendOptions 비동기 세션 공유-->
<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" -- 자신의 IP
port="4000" -- 수신하기 위한 port
autoBind="10" -- 수신 포트에 실패 할 경우 확장할 수 10일 경우 4000 ~ 4010
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>
...
</Engine>
스프링 부트의 경우 web.xml 대신 다음과 같이 설정해주시면 되겠습니다.
//이 클래스가 있는 패키지(com.sample.test)와 패키지명이 다를시[ex)com.sample.common.util와 같은] 의존성 주입이 안되기때문에 어노테이션이 인식을 못해 에러발생
//이 패키지 이하의 클래스만 찾아 DI되기 때문
@SpringBootApplication(scanBasePackages={"com.sample"})
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
//원래 다른서버(톰캣이라면 톰캣의 server.xml에 추가설정 필요, was별로 다름)와 세션공유를 위해 web.xml 에 <distributable/> 설정해주는 부분 대체
private static boolean distributable;
public static boolean getDistributable() {
return distributable;
}
@Bean
public ServletWebServerFactory tomcatFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
TestApplication.distributable = context.getDistributable();
System.out.println("distributable is :"+distributable);
}
};
}
//원래 다른서버(톰캣이라면 톰캣의 server.xml에 추가설정 필요, was별로 다름)와 세션공유를 위해 web.xml 에 <distributable/> 설정해주는 부분 대체 끝
}
추가적으로 스프링부트가 내장톰캣을 실행시키는 jar방식이 아닌 서버가 있는 외부의 톰캣에서 실행시키는 war방식이기 때문에 다음과 같이 추가해줍니다. war방식에 맞게 pom.xml도 수정이 필요하겠습니다.
//스프링부트 내장톰캣을 실행시키는 jar 방식이 아닌 외부의 톰캣에서 실행시키는 war방식이기 때문에 필요한 코드
//이 코드를 main메서드가 있는 코드에 넣을 수도 있지만, 분리하여 설정관련 가독성 ↑
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication.class);
}
}
https://brownbears.tistory.com/168
'서버설정' 카테고리의 다른 글
톰캣 실행시 콘솔창 debug 설정 (0) | 2020.02.28 |
---|---|
톰캣 시작속도 개선방법 (1) | 2020.02.14 |