웹 개발 시 이중화 등의 HA 구성을 할때나 다른 서버와의 인증 정보를 공유 하고자 할 때는 Tomcat 간에 session cluster 기능을 통해 세션 동기화를 할 수 있다.
이때 공용 세션 저장소로 redis 메모리 DB를 활용할 수 있고 아래 리포지터리에서 제공하는 라이브러를 가지고 구현을 할 수 있다.
https://github.com/ran-jit/tomcat-cluster-redis-session-manager/wiki
현재 사용하는 Tomcat이 버전이 9.0.65 대로 위 tomcat-cluster-redis-session 라이브러리 중 tomcat-cluster-redis-session-manager-2.0.4 버전을 사용해 보기로 했다.
다운로드를 하고 압축을 풀면 아래 4가지 라이브러리가 풀린다.
// java 라이브러리
tomcat-cluster-redis-session-manager-2.0.4.jar
commons-logging-1.2.jar
commons-pool2-2.4.2.jar
jedis-2.9.0.jar
// tomcat redis용 conf 파일
redis-data-cache.properties
위 4개의 라이브러리는 tomcat이 설치된 폴더 lib 이하에 복사를 해준다.
예를 들어 tomcat 9.0.65버전을 다운 받았다면 아래와 같이 경로가 되어 있을 것이다.
apache-tomcat-9.0.65\lib
그리고 redis-data-cache.properties 는 tomcat의 conf 디렉토리 밑으로 복사한다.
apache-tomcat-9.0.65_8082\conf
단 여기서 conf 파일내의 redis.hosts 주소는 환경에 맞게 수정해 준다.
#-- Redis data-cache configuration
#- redis hosts ex: 127.0.0.1:6379, 127.0.0.2:6379, 127.0.0.2:6380, ....
redis.hosts=xxx.xxx.xxx.xxx:49153
#- redis password (for stand-alone mode)
#redis.password=
#- set true to enable redis cluster mode
redis.cluster.enabled=false
#- redis database (default 0)
#redis.database=0
#- redis connection timeout (default 2000)
#redis.timeout=2000
그리고 실제 서버 구동시 세션 상태를 확인하기 위해 아래 jsp 파일을 tomcat deploy 경로에 복사해준다.
추후 서버URL/session_check.jsp를 호출해서 세션 상태를 웹 화면으로 보기 위함이다.
session_check.jsp
<%@page contentType="text/html; charset=UTF-8"%>
<%@ page import="java.text.*"%>
<%@ page import="java.util.*"%>
<%
String RsessionId = request.getRequestedSessionId();
String sessionId = session.getId();
boolean isNew = session.isNew();
long creationTime = session.getCreationTime();
long lastAccessedTime = session.getLastAccessedTime();
int maxInactiveInterval = session.getMaxInactiveInterval();
Enumeration e = session.getAttributeNames();
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>Session Test</title>
</head>
<body>
<table border=1 bordercolor="gray" cellspacing=1 cellpadding=0 width="100%">
<tr bgcolor="gray">
<td colspan=2 align="center"><font color="white"><b>Session Info</b></font></td>
</tr>
<tr>
<td>Server HostName</td>
<td><%=java.net.InetAddress.getLocalHost().getHostName()%></td>
</tr>
<tr>
<td>Server IP</td>
<td><%=java.net.InetAddress.getLocalHost().getHostAddress()%></td>
</tr>
<tr>
<td>Request SessionID</td>
<td><%=RsessionId%></td>
</tr>
<tr>
<td>SessionID</td>
<td><%=sessionId%></td>
</tr>
<tr>
<td>isNew</td>
<td><%=isNew%></td>
</tr>
<tr>
<td>Creation Time</td>
<td><%=new Date(creationTime)%></td>
</tr>
<tr>
<td>Last Accessed Time</td>
<td><%=new Date(lastAccessedTime)%></td>
</tr>
<tr>
<td>Max Inactive Interval (second)</td>
<td><%=maxInactiveInterval%></td>
</tr>
<tr bgcolor="cyan">
<td colspan=2 align="center"><b>Session Value List</b></td>
</tr>
<tr>
<td align="center">NAME</td>
<td align="center">VAULE</td>
</tr>
<%
String name = null;
while (e.hasMoreElements()) {
name = (String) e.nextElement();
%>
<tr>
<td align="left"><%=name%></td>
<td align="left"><%=session.getAttribute(name)%></td>
</tr>
<%
}
%>
</table>
<%
int count = 0;
if(session.getAttribute("count") != null)
count = (Integer) session.getAttribute("count");
count += 1;
session.setAttribute("count", count);
out.println(session.getId() + " : " + count);
%>
</body>
</html>
위 설정이 다 끝나고 tomcat에 배포된 서버를 실행한다.
그리고 session_check 페이지를 호출해보면 현재 설정된 세션 정보를 확인할 수 있다.
여기서 tomcat을 중단 시키고 서버를 내린 후 다시 서버 재 기동 후 위 세션 정보를 보면 세션이 그대로 유지되어 있음을 볼 수 있다. Redis로 세션을 저장해 두었기 때문에 새로 새션을 만들지 않고 유지되고 있는 것이다.
이 원리로 여러 서버 인스턴스를 가동중일때 redis 저장소를 활용해서 어디서든 동일한 세션을 사용할 수 있도록 세션 클러스터링을 구현할 수 있게 된다.
-- The End --
'Backend Development > Spring boot' 카테고리의 다른 글
Embedded Redis 로 redis junit 작성하기 (0) | 2023.02.20 |
---|---|
kakao 로그인 (javascript) (1) | 2023.01.28 |
[Backend] Konga api gateway admin 활용 (0) | 2022.12.02 |
[Backend] Kong Api Gateway 설치 (0) | 2022.11.07 |
[Spring boot] Chrome Cookie SameSite 해결하기 (0) | 2022.10.20 |