본문 바로가기

Backend Development/Spring boot

Tomcat redis session cluster 설정

웹 개발 시 이중화 등의 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 --