작년 말 관련 업무 진행하면서 정리했었던 스프링 시큐리티에서의 다중 로그인 제어 방식
[SPRING SECURITY] ConcurrentSessionFilter 이용하여 동시접속 제어하기 https://juran-devblog.tistory.com/240
[SPRING SECURITY] SessionRegistry 이용하기 https://juran-devblog.tistory.com/241
스프링 시큐리티 필터를 이용한 방법과 스프링 시큐리티의 제어를 받지 않는 상황을 위한 SessionRegistry 이용 두 가지를 알아봤었다.
그 이후로 다중 서버 환경에서 스프링 시큐리티의 세션 정보가 공유되지 않는 이슈로 인해 위의 수정했던 내용 싹 들어내고 다시 개발했었다. 그때 당시 세션 클러스터링의 문제가 있는 줄 알고 외부 저장소를 활용해 세션 정보를 저장하고 중복 관리를 하는 방향으로 수정했었다. 지금 생각해보면 각 서버에서 각각의 어플리케이션이 구동되며 스프링 시큐리티의 세션까지는 전파되지 않는 걸로 보인다. 구글링하다 관련해서 읽었던거 같은데 다시 찾아보니 안나온다... 시간이 흘러 올해 또 비슷한 업무를 하게되었는데 알고보니 세션 클러스터링은 잘 되고 있었다..! 당연히 그랬겠지 멀쩡히 운영 잘 되고 있는 서비스인데... 안그래도 작년에 하면서 이게 맞나 싶었는데 그때 좀 더 찾아보고 테스트도 많이 해볼걸 그랬다.
말 그대로 고정 세션이다. 사용자 A가 서버 A에 세션을 생성하였다면 사용자 A의 모든 요청은 본인의 세션 정보가 있는 서버 A에서 처리된다.
로드 밸런서는 사용자 A의 모든 요청을 서버 A로 보내 처음 생성된 세션만 사용하게 한다. 이를 위해 로드 밸런서는 요청을 받으면 가장 먼저 요청에 쿠키가 존재하는지 확인한다. 쿠키가 있으면 해당 요청을 쿠키에 지정된 서버(세션이 저장된 서버)로 전송한다. 쿠키가 없는 경우, 기존 로드 밸런싱 알고리즘 기반으로 요청을 전달할 서버를 선정한다. 사용자가 계속 동일한 서버에 요청을 보낼 수 있도록 지속적으로 서버 정보가 쿠키를 통해 응답에 삽입되어 보내진다.
하지만 단점이 있다. 특정 서버에 트래픽이 집중될 위험이 있다. 사용자가 사용할 수 있는 서버가 정해져있기 때문에 하나의 서버에 트래픽이 집중된 상황에서도 다른 서버를 사용할 수 없다. 정합성 이슈는 해결할 수 있지만 다중 서버 환경의 이점을 살리기는 어렵다. 또한 사용자의 요청을 받던 서버가 다운되었을 때 해당 사용자의 세션 정보가 소실될 수 있다.
* 세션(session)과 쿠키(cookie)
여러 서버의 세션 저장소를 하나로 묶어 하나의 세션 저장소로 이용하는 것이다. 즉, 여러대의 서버를 하나의 서버처럼 이용하는 것
한 서버에 세션이 생성되면 다른 서버 모두에 해당 세션을 전파(복사)한다. 모든 서버가 동일한 세션을 가지고있기 때문에 특정 서버로만 트래픽이 몰리지 않으며, 하나의 서버가 다운되어도 세션 정보를 잃어버릴 일은 없다.
하지만 모든 서버의 세션 데이터를 동일하게 유지하기 위해 하나에 세션 관련 작업이 생기면 모든 서버의 세션 스토리지를 업데이트 해줘야 한다. 그만큼 트래픽이 발생하고 장애 상황에서 문제가 될 수 있으며 세션에 대한 메모리가 필요하기에 성능 저하를 유발할 수 있다. 또한 새로운 서버가 추가될 때마다 기존의 세션 데이터를 옮겨 클러스터링 해줘야하는 번거로움도 존재한다. 이때 WAS마다 세션 클러스터링의 방식이 다를 수 있으니 이 또한 확인이 필요하다.
따라서 해당 방식은 소규모 클러스터에서 좋은 효율을 보여준다. 서버 4대 이상의 대규모 클러스터는 추천하지 않는다.
서버마다 세션 저장소를 두는 방식이 아닌 외부에 따로 세션 관리를 위한 저장소(서버)를 두는 것이다. 동일하게 바라보는 세션 서버가 별도로 있기에 한 서버에서 세션 정보 생성 시 다른 서버에 세션 복제, 업데이트 과정은 필요 없으며 클러스터링도 필요 없다.
하지만 결국 세션 서버가 죽으면 모든 세션 정보를 잃는다는 위험이 있다. 이런 상황을 대비하여 세션 저장 시 다른 서버에 실시간으로 복사본을 생성해 백업을 준비하는 방법도 고려해볼 수 있다.
* 세션 스토리지는 보통 인메모리(IN-memory) DB를 사용한다. 인메모리 DB란 데이터 스토리지의 메인 메모리에 설치되어 운영되는 방식의 DBMS로, 디스크에서 데이터를 읽어오는 것이 아니라 메모리에서 데이터를 읽어오기 때문에 조회 시 속도가 더 빠르다. 메인 메모리에 설치되기 때문에 휘발성이다.
* 일반 DBMS로 사용 가능하나 세션을 통한 접근이 많고 그만큼 조회 빈도도 높기에 인메모리 DB를 사용하는게 더 효율적이다. 주로 Redis를 많이 사용한다.
Nginx & Spring Boot 구성하기(1) Mac M1 버전과 설정 기본 (0) | 2024.06.30 |
---|---|
MAC CORS 무시하고 크롬 실행하기 (0) | 2023.10.14 |
[SERVLET, JSP] 다양한 이벤트 리스너(Listener) (0) | 2022.12.27 |
JS와 SQL 그리고 JAVA.. 데이터 가공과 비즈니스 로직은 어디에 (0) | 2022.11.22 |
[WEB] RESTful API란 (0) | 2021.08.30 |
댓글 영역