크게 많이 사용하는 로그인 방식으로는 세션방식과 토큰방식이 있습니다. 이 글은 세션 방식에 대해 다룹니다. 세션 방식은 보통 서버에 로그인 정보를 저장합니다.
Scale-out을 하기 전에는 한대의 WAS 서버로 세션을 처리했습니다.
하지만 서버의 대수를 늘린 후에는 세션을 어디에 저장할 것인지라는 이슈가 발생합니다. 만약 1번 서버에 어떤 사용자의 세션을 저장하고 배달 주문을 하는 Request가 2번 서버로 전달된다면 B서버에는 이 사용자의 세션이 없기 때문에 로그인이 유지되지 않는 문제가 발생합니다. 따라서 이러한 Session 정합성 문제를 해결해야했고 여러 가지 방법을 고민해보았습니다.
첫째로 고려한 방법은 Sticky Session입니다.
Sticky Session은 어떠한 사용자의 세션이 1번 서버에서 생성되었다면 이 사용자의 Request는 1번 서버로만 보내지는 방식입니다. 이러한 방법은 로드밸런서에 의해 이루어집니다. 세션이 만료되기 전까지 A 사용자의 세션이 생성된 서버로 로드밸런스가 A 사용자의 요청을 리다이렉트합니다.
위 그림은 request를 아무 서버에서나 보내지만 스티키세션이 적용된 밑 그림은 request를 정해진 서버로만 보냅니다.
하지만 이 방식의 단점으로 특정 사용자의 세션은 한 서버에 의존하고 있기 때문에 특정 서버에 트래픽이 집중된다면 장애가 발생할 수 있습니다. 서버의 대수가 많고 다른서버가 여유롭더라도 트래픽이 몰린 서버로만 요청을 보내야하는 경우가 생길 수 있기 때문입니다. 또한 하나의 서버에 문제가 발생했을 시, 그 서버에 저장된 세션정보들이 분실될 수도 있고 그동안 그 서버에 저장된 세션을 이용하지 못할 수 있습니다.
두번째로 Tomcat에서 지원하는 Session Clustering을 고려해봤습니다.
세션 클러스터링 방식은 여러대의 WAS가 있어도 동일한 세션으로 관리하여 Sticky Session의 단점을 극복했다는 장점이 있습니다.
Session Clustering이란?
Session clustering은 WAS가 2대 이상 설치되어 있을 경우 모든 세션정보를 여러 대의 서버에 다 가지고 있는 것입니다. 따라서 세션이 변경 될 때 마다 세션정보를 모든 다른 서버에도 저장시킵니다. 즉 밑 그림에서처럼 1번서버에 세션이 생성되면 2번, 3번 서버에도 그 세션 정보를 저장시키는 것입니다. Tomcat의 deltamanger라는 이름의 all to all 방식이 이방식에 해당합니다.
세션 클러스터링의 단점
하지만 모든 서버에 세션정보를 다 저장해야하기 때문에 서버 메모리의 비효율이 생깁니다. 또한 세션 정보를 추가해야할 때마다 모든 서버에 세션정보를 다 추가해야하기 때문에 모든 서버에 네트워크 요청을 해야하므로 많은 네트워크 요청이 발생합니다. 또한 서버의 대수가 늘어나면 늘어날 수록 더 많은 네트워크 요청이 발생합니다. 따라서 세션 클러스터링 정보는 성능에서 비효율적인 방식일 수 있습니다.
세번째로 고려한 점은 세션서버를 레디스에 따로두어 세션 스토리지를 관리하는 것입니다.
레디스는 Inmemory DB이며 Session Storage로 사용될 수 있습니다. 서버에 세션 정보를 저장하는 것이 아닌 외부에 레디스 서버를 띄우고 이 서버에 모든 세션 정보를 저장하는 것입니다. 즉 WAS서버들이 레디스에서 세션 정보를 읽어오는 것입니다.
따라서 서버들끼리 네트워크 요청을 할 필요도 없고 서버를 stateless하게 유지할 수 있다는 점에서 세션 클러스터링 방식의 단점을 극복한 방식입니다. 또한 한 서버에 문제가 생겨도 외부에 세션정보를 저장하여 서버 장애 문제를 극복하고 한대의 서버에 트래픽이 몰릴일이 없어졌기 때문에 스티키 세션의 방법을 극복한 방식입니다. 따라서 레디스를 이용해 서버 외부에서 세션정보를 관리하기로 결정하였습니다.
프로젝트 url
https://github.com/f-lab-edu/make-delivery
참고자료
https://www.imperva.com/learn/availability/sticky-session-persistence-and-cookies/
https://ignite.apache.org/use-cases/caching/web-session-clustering.html
https://thenewstack.io/how-to-build-intelligence-into-your-session-stores/
'make-delivery 프로젝트' 카테고리의 다른 글
[#6] Jenkins를 이용하여 CI/CD 환경 구축해보기 (2) | 2020.11.26 |
---|---|
[#5] 성능을 위해 Redis keys 대신 scan 이용하기 (0) | 2020.10.25 |
[#4] Spring에서 중복되는 로그인 체크 기능을 AOP로 분리하기 (0) | 2020.10.16 |
[#3] 정확히 트랜잭션이 롤백 되었을 때 장바구니를 복원하기 -TransactionSynchronization afterCompletion (Rollback hook) (0) | 2020.10.15 |
[#2] Redis에 한번에 많은 데이터 추가 시 네트워크 병목 개선하기 - Redis Pipeline 이용하기 (0) | 2020.10.08 |
댓글