2. 다중 서버에서 로그인이 세션 유지될까?
Last updated
Last updated
로그인 세션 저장 위치를 알아보고, 다중 서버 환경에서 로그인 세션을 유지하는 방법들을 정리해보았다.
앞선 글에서 로그인 세션(HttpSession
)은 서버의 서블릿 컨테이너에 저장됨을 알아보았다. 즉 로그인 세션은 서버의 메모리에 저장된다. 위 그림은 서버가 하나인 상황이다. 그렇다면 서비스의 규모가 커져서 Scale-out 할 경우에는 로그인 세션이 유지될까?
Scale-out
은 서버의 갯수를 늘린다는 의미이다. (Scale-up은 한 서버의 성능을 개선한다는 의미)
서버들끼리 각자의 메모리를 공유하지는 않는다. 세션은 서버의 메모리에 저장되므로, 다중 서버에서는 서버들끼리 세션이 공유되지 않는다.
만약 로그인 후 다른 페이지로 이동할 때, 로드 밸런서에 의해 다른 포트로 접속하게 될 수 있다. 이런 경우, 세션(로그인 상태)이 유지되지 않는다. 즉, 다중 서버일 경우에는 로그인 세션이 유지되지 않는다! 이대로면 유저가 로그인 후 페이지 이동 시, 혹은 새로고침 할 때마다 다시 로그인해야 한다. 서버가 바뀌더라도 로그인 세션을 유지하는 방법이 있을까?
스프링으로 로그인 구현한 지금 상태(스프링 시큐리티 사용X)에서 로그인 세션을 유지하는 방법에는 크게 3가지가 있다.
Sticky Session : 유저가 접속하는 서버 고정
Session Clustering : 서버들끼리 세션 복제하여 공유
Session Storage : 외부 세션 저장소에 세션을 따로 저장
Sticky Session은 유저가 접속하는 서버를 고정하는 방법이다. 위 그림에서는 최초 접속 시 8081 포트 서버로 연결되었다. 이후부터 이 유저는 해당 서버로만 접속되어, 로그인 세션이 유지될 수 있다. 유저의 고정 서버 정보는 쿠키에 담아 전송한다.
그러나, 이 방식은 다중 서버의 장점을 활용하지 못하고 유저가 특정 서버에 몰릴 수 있다. 또한 해당 서버가 서비스 장애 시 세션 정보를 잃어버리게 된다.
Session Clustering은 서버들끼리 세션 복제하여 공유하는 방식이다.
All-to-all 방식 : 한 서버에 새로운 세션이 저장되면, 다른 서버들에도 모두 복제한다.
Primary-Secondary 방식 : 한 서버(Primary)에 새로운 세션이 저장되면, 백업 서버(Secondary 서버)에는 세션 전체를 복제한다. 나머지 서버에는 세션 ID만 저장한다.
All-to-all 방식은 모든 서버에 중복 저장해야 하므로 메모리를 비효율적으로 사용하게 된다. Primary-Secondary 방식은 세션을 모두 복제하지는 않아 All-to-all 보다는 메모리를 절약한다. 그러나 Primary/Secondary 이외의 서버들은 세션 ID로 Primary 서버에서 세션 정보를 가져오는 시간이 걸린다.
Session Storage은 외부 세션 저장소에 세션을 따로 저장하는 방법이다. 이 경우 앞선 2가지 방법의 단점이 다 해소된다. 다중 서버의 장점을 가지고(고정 서버가 아니므로) 하나의 서버가 다운되더라도 세션은 문제없다. 또한 서버의 메모리를 비효율적으로 사용하지도 않는다. 외부 세션 저장소는 Redis나 Memcached를 많이 사용한다.
로그인 세션은 서버의 메모리에 저장되기 때문에, 다중 서버에서는 로그인 세션이 유지되지 않는다. 유저가 페이지 이동 시에도 로그인 상태를 유지해주기 위해 세션 유지 방법들을 알아보았다. 다음 글에서는 Spring Security를 사용한 로그인 구현 방식과 Security를 사용하면서 세션을 유지하는 방식에 대해 알아볼 예정이다.