
서비스 규모가 커지면 서버를 여러 대 두는 Scale-Out이 필수적입니다. 하지만 Scale-Out 시 발생하는 문제가 세션 불일치입니다. 이 문제와 해결 방안에 대해 알아보겠습니다.
HTTP는 상태가 없는(Stateless) 프로토콜입니다. 따라서 서버는 사용자를 식별하기 위해 브라우저에 JSESSIONID라는 쿠키를 발급하고, 서버 메모리에 해당 ID와 연결된 세션 객체를 생성합니다.
만약 서버 A에서 로그인을 해서 세션을 생성했는데, 다음 요청이 로드밸런서에 의해 서버 B로 전달된다면 어떻게 될까요?
특정 사용자의 요청을 처음 연결된 서버로만 고정하는 방식입니다.
여러 서버가 공용 저장소(Redis 등)를 공유하여 세션을 관리하는 방식입니다.
Spring Boot와 Redis가 있다면 의존성 추가만으로도 세션 클러스터링을 구현할 수 있습니다.
내장 Tomcat의 세션 관리 대신 Redis를 사용하도록 설정합니다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.session:spring-session-data-redis' // 핵심!
}
서버를 8080포트와 8081포트 두 대를 띄우고 테스트해 봅니다.
8080/set?q=data 접속 → 세션 저장
8081/get 접속 → 데이터 조회 성공!
이때 브라우저를 확인해 보면 기존의 JSESSIONID 대신 SESSION이라는 이름의 새로운 쿠키가 생성된 것을 볼 수 있습니다.

기본적으로 Java 직렬화를 사용하면 Redis 내 데이터를 읽기 어렵습니다.

사람이 읽을 수 있는 JSON 형태로 저장하려면 아래 설정을 추가합니다.
RedisConfig.java
@Configuration
public class RedisConfig {
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
// 세션 데이터를 JSON 형태로 직렬화하여 저장
return RedisSerializer.json();
}
}

⚠️ 주의사항: SecurityContext와 같이 기본 생성자가 없는 객체를 세션에 담을 경우, JSON 직렬화/역직렬화 과정에서 오류가 발생할 수 있습니다. 이 경우 커스텀 Serializer를 구성하거나 Java 기본 직렬화를 유지해야 할 수도 있으니 유의하세요!
서버가 1대일 때는 체감하기 어렵지만, 실무 환경에서는 Session Clustering이 필수입니다. 특히 Redis는 인메모리 DB로서 지연 시간이 매우 짧아 세션 저장소로 가장 많이 선호됩니다.