Node.js 멀티 프로세스 환경에서 세션 공유 문제 해결
문제 상황
단일 프로세스로 운영하던 Node.js API 서버를 PM2 클러스터 모드로 전환했다. CPU 코어 수만큼 프로세스를 띄워 성능 개선을 기대했는데, 로그인 후 인증이 간헐적으로 실패하는 문제가 발생했다.
원인은 간단했다. express-session의 기본 메모리 스토어는 각 프로세스의 메모리에 세션을 저장한다. 로드밸런서가 요청을 다른 프로세스로 라우팅하면 해당 프로세스는 세션 정보를 찾을 수 없었다.
해결 방법
Redis를 세션 스토어로 사용하도록 변경했다. connect-redis 패키지를 활용하면 설정이 간단하다.
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: 6379,
legacyMode: false
});
redisClient.connect().catch(console.error);
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: process.env.NODE_ENV === 'production',
maxAge: 1000 * 60 * 60 * 24
}
}));
결과
모든 프로세스가 동일한 Redis 인스턴스를 바라보면서 세션이 정상적으로 공유되었다. 부하 테스트에서도 인증 실패 없이 안정적으로 동작했다.
Redis 장애 시나리오도 고려해야 한다. 현재는 Redis가 다운되면 모든 세션이 유실되는 구조다. 다음 단계로 Redis Sentinel이나 Cluster 구성을 검토할 예정이다.
참고사항
- PM2 클러스터 모드에서 프로세스 간 메모리는 공유되지 않는다
- Redis 외에도 Memcached, MongoDB 등 다른 세션 스토어 선택지가 있다
- 세션 만료 정책은 Redis TTL로 자동 관리된다