NestJS 성능과 확장

수평 확장은 트래픽을 나누기 전에 상태 의존성을 밖으로 빼는 일이다

load balancer 뒤에 replica를 늘려도 session, 파일, queue가 특정 인스턴스에 묶이면 확장이 깨집니다. readiness, drain, shared store를 함께 확인해야 재배포 중에도 요청이 이어집니다.

Client requests 로그인, 업로드, 작업 요청 Load balancer ready replica만 선택 Replica A stateless app Replica B stateless app Replica C scale out target Redis session sticky 없이 로그인 유지 Object storage local file 의존 제거 External queue worker 재시작에도 작업 보존 Readiness gate 준비 전 트래픽 차단 Sticky risk 특정 instance에 묶임 Drain window 종료 중 요청 마무리 운영 결론 replica 수보다 먼저 상태 저장 위치, 헬스 체크, 종료 drain 시간을 증거로 남긴다.
1 Load balancer ready 상태인 replica로만 요청을 보낸다.
2 Stateless replica 인스턴스 내부 session, local file, memory queue 의존을 제거한다.
3 Shared store Redis, object storage, external queue로 상태를 밖에 둔다.
4 Drain 검증 배포 종료 중 in-flight 요청과 session 유지 여부를 재현한다.

상태를 밖으로 빼는 기준

session

JWT 또는 Redis session store로 replica 교체 뒤에도 인증 상태를 유지한다.

file

local disk 대신 object storage를 써서 업로드 파일을 공유 상태로 둔다.

queue

in-memory queue 대신 외부 queue를 사용해 worker 재시작에도 작업을 보존한다.

트래픽 경계

readiness

초기화 전 instance를 load balancer 대상에서 제외한다.

liveness

회복 불가능한 instance를 재시작하되 readiness와 목적을 섞지 않는다.

drain

SIGTERM 이후 새 요청을 막고 진행 중 요청이 끝날 시간을 준다.

위험 신호

sticky

sticky session 없이는 로그인 유지가 안 되면 확장성이 아직 부족하다.

local

업로드 파일이나 임시 작업이 특정 instance 디스크에만 있으면 배포 중 깨진다.

no log

instance별 분산 비율과 shutdown 로그가 없으면 장애 원인을 좁히기 어렵다.

01 상태 위치 감사 session, file, queue가 프로세스 메모리나 local disk에 남아 있는지 찾는다.
02 헬스 체크 분리 readiness는 트래픽 진입, liveness는 재시작 판단으로 나눠 설정한다.
03 Scale out 재현 replica를 늘리고 로그인 유지, 업로드 접근, queue 처리 중복을 확인한다.
04 Shutdown drain rolling deploy 중 새 요청 차단과 기존 요청 완료 시간을 로그로 남긴다.
분산 증거

instance별 request count, session store latency, health 실패율을 함께 본다.

장애 재현

unready instance, store 지연, SIGTERM, replica 교체를 테스트 시나리오에 넣는다.

완료 기준

sticky 없이도 같은 사용자가 유지되고 in-flight 요청 손실이 없어야 한다.

Scaling 운영 점검

질문: load balancer 뒤 replica가 바뀌어도 session과 in-flight request가 유지되는가
순서: 상태 외부화 -> readiness 분리 -> scale out -> graceful shutdown 테스트
위험: in-memory session, local file, sticky session은 요청을 특정 instance에 묶는다.