1. 도입배경
- 프로젝트(웹소설) 진행 중 다음과 같은 고려 사항이 발생했습니다.
- 잦은 사용자 인증으로 MainDB 오버헤드가 증가했습니다.
- MainDB의 디스크 I/O 속도가 느려 비효율적이었습니다.
- 이에 대한 대안을 찾던 중, 다른 개발자들이 Redis를 세션 스토어로 사용하는 것을 알게 되어 이를 프로젝트에 적용해 보았습니다.
2. 왜 Redis 를 session store 로 사용하는가?
1) 인메모리 DB(빠른 입출력 속도)
- Redis는 메인 메모리에서 동작하는 DB로 있어 읽기/쓰기 속도가 빠릅니다.
- 세션 인증은 빠른 응답 속도가 중요하기 때문에, HDD나 SSD(SSD가 빠르더라도 RAM보다는 느림)를 사용하는 DB보다 Redis를 사용하는 것이 더 효율적입니다.
- 또한, WAS 인스턴스가 여러 개일 경우에도 메모리에 있는 Redis를 공유하면 되므로 확장성이 뛰어납니다.
2). MainDB 오버헤드 감소(리소스 효율성 측면)
- MainDB는 세션 외에도 많은 요청으로 인해 오버헤드가 큰 상황입니다.
- 특히 세션은 로그인한 모든 유저가 요청하는 부분이기 때문에 session store를 MainDB에 두면 리소스 낭비가 커집니다.
3). 프로젝트 요구사항(잦은 인증요청)
- JWT 기반 로그인을 고려할 수도 있지만, 프로젝트(웹소설) 특성상 잦은 사용자 요청이 요구됩니다.
- 구매 기록, 결제 기록 인증이 자주 이루어져야 하기 때문에 JWT보다는 세션 기반 로그인을 선택하는 것이 적합했습니다.
3. 설계
- 세션 관련 라이브러리는 사용 중인 Spring Session과 Spring Security를 사용했습니다.
- 다중 인스턴스 환경에서도 사용할것을 고려하여 전체적인 흐름을 설계하였습니다.
전체적인 흐름
1) 로그인 과정
- 클라이언트에서 유저 인증 정보를 WAS로 전송합니다 (실제 프로젝트에서는 OAuth 방식으로 다소 다릅니다).
- WAS에서 인증을 처리하며 DB에서 유저 정보를 확인합니다.
- 인증 실패 시 BAD_REQUEST를 반환합니다.
- 인증 성공 시 SecurityContext에 인증 정보를 저장합니다.
- Spring Session이 동작하여 SessionRepositoryFilter가 HttpSession을 가로채 Redis 기반 세션으로 교체합니다.
- 세션 ID가 생성되어 Redis에 저장되고, 생성된 세션 ID는 세션 쿠키(JSESSIONID)에 담겨 클라이언트로 전송됩니다.
2). 요청 세션 인증 처리
- 클라이언트의 요청에 세션 쿠키(JSESSIONID)가 자동으로 포함되어 전송됩니다.
- WAS는 해당 세션 쿠키를 처리하며, JSESSIONID로 Redis에서 세션 정보를 조회합니다.
- 세션 정보가 유효하지 않을 경우 예외 처리(로그인 페이지로 이동)됩니다.
- 유효한 경우, 요청을 정상적으로 처리합니다.
'Spring' 카테고리의 다른 글
[Spring] OAuth2 기반 회원 인증 시스템 도입 (1) - 도입배경,이론 (1) | 2024.11.07 |
---|---|
[Spring] Full-Text Index를 활용한 DB 검색 성능 최적화 (2) - Spring 코드 구현, 성능 비교 테스트 (1) | 2024.11.06 |
[Spring] Full-Text Index를 활용한 DB 검색 성능 최적화 (1) 도입배경, MySQL Full-Text Index 생성 (0) | 2024.11.06 |
[Spring] Redis 기반 세션 스토리지 구축 (3)- Redis vs MySQL 성능비교 (0) | 2024.11.01 |
[Spring] Redis 기반 세션 스토리지 구축 (2)- 구현 (1) | 2024.11.01 |