세션저장소로 데이터베이스 사용하기

LSM ·2022년 1월 23일
0

스프링부트로 프로젝트를 진행하면서 세션 관리에 대한 문제점 인식과 해결 방법에 대해서 정리해보겠다.

1. 문제점

현재 스프링부트로 서버를 구동하고 있다. 추가적으로 OAuth2를 이용하여 소셜로그인 기능이 정상적으로 진행되는 상황이다. 그런데 소셜로그인 이후 어플리케이션을 재실행 하면 로그인이 풀리는 상황이 생긴다. 그 이유에 대해 알아보니, 기본적으로 세션이 실행되는 WAS의 메모리에서 저장되고 호출된다. 따라서 스프링부트와 같은 내장 Tomcat(WAS)를 사용하는 구조에서는 어플리케이션 실행시에 WAS또한 재실행 됨으로 항상 WAS의 메모리 또한 초기화 되기에 세션이 유지되지 못하는 것이었다.

1) 즉, 스프링부트에서는 배포할 때마다 톰캣이 재시작 되는 것이다.

2) 추가적으로 2대 이상의 서버에서 서비스하고 있는 경우에는 톰캣마다 세션 동기화 설정을 해야만한다고 한다.

아래 그림이 2)의 예시이다.


2. 해결방법

실제 현업에서는 세션 저장소에 대해 다음의 3가지 중 한가지를 선택한다고 한다.

1) 톰캣 세션을 사용

  • 일반적으로 별다른 설정을 하지 않았을 때 기본적으로 선택되는 방식
  • 이렇게 될 경우 위 그림과 같이 WAS에 세션이 저장되기 때문에 2대이상의 WAS가 구동되는 환경에서는 톰캣들 간의 세션 공유를 위한 추가설정이 필요하다.
  • 모든 서버가 동일한 세션 객체를 가져야하기 때문에 많은 메모리가 필요하다.

2) MySQL,Oracle과 같은 데이터베이스를 세션 저장소로 사용한다.

  • 여러 WAS간 공용세션을 사용할 수 있는 가장 쉬운 방법
  • 많은 설정이 필요 없지만, 로그인 할 때마다 DB I/O가 발생하여 성능상 이슈가 발생할 수 있다.
  • 보통 로그인 요청이 많이 없는 백오피스, 사내 시스템 용도에서 사용한다.

3) Redis, Memcached와 같은 인메모리DB를 세션저장소로 이용

  • B2C 서비스에서 가장 많이 이용하는 방식
  • 실제 서비스로 사용하기 위해서는 Embedded Redis와 같은 방식이 아닌 외부 메모리 서버가 필요하다.
  • 이와 같은 서비스는 별도의 사용료를 지불하는 경우가 많다.

아래 그림이 Redis의 구조이다

실제 상용화 되는 서비스가 아니라, 본인은 두번째 방식인 데이터베이스를 세션 저장소로 사용하는 방식을 사용. 그 이유는, 간단하고 사용자가 많지 않아 로그인이 잦지 않으며, 비용적으로도 부담스럽기 때문. 추후 실제 서비스화가 된다면 Redis와 같은 메모리 DB도 고려해보겠다.


3. 스프링부트 추가 설정

1) build.gradle에 다음과 같은 의존성

complie('org.springframework.session:spring-session-jdbc')

2) application.properties에 세션 저장소를 jdbc로 선택하도록 설정

spring.session.store-type=jdbc

이렇게 하면, JPA로 인해 세션테이블이 자동 생성된다.


4. 참고자료

profile
개발 및 취준 일지

0개의 댓글