Load Balancer / Health Check / Traffic Routing
3줄 요약
- Load Balancer는 트래픽을 나누는 장비가 아니라 target 선택, health 판단, connection 유지, 배포 전환을 책임지는 운영 경계다.
- Health check 200은 “프로세스가 응답했다”에 가까울 수 있으므로 liveness, readiness, 핵심 기능 smoke test를 구분해야 한다.
- 배포 품질은 readiness false, target draining, graceful shutdown, idle timeout, sticky/session 전략이 맞물릴 때 안정된다.
핵심 정리
- LB는 listener, rule, target group, routing algorithm, health check, idle timeout, access log로 동작한다.
- Routing은 round robin, least connections, weighted/canary, host/path/header rule, stickiness 같은 정책을 포함한다.
- Readiness는 새 트래픽을 받아도 되는지의 신호이고, liveness는 프로세스를 재시작해야 하는지의 신호다.
- Draining은 target을 새 요청에서 제외하되 기존 연결과 진행 중 요청이 끝날 시간을 주는 절차다.
- WebSocket, SSE, long polling, gRPC는 idle timeout, keepalive, connection draining, target rebalance에 민감하다.
헷갈리는 지점
- LB가 있으면 장애 target은 자동으로 완벽히 숨겨진다고 생각하기 쉽다.
- 핵심 판단 포인트는 모든 target이 unhealthy거나 health check가 실제 장애를 못 보면 LB도 잘못된 target으로 보낼 수 있다는 것이다.
- readiness에 모든 dependency를 넣으면 안전하다고 생각하기 쉽다.
- 핵심 판단 포인트는 공통 dependency 장애 때 모든 target이 unready가 되어 전체 트래픽이 끊길 수 있다는 것이다.
- 배포 실패를 앱 코드 문제로만 보기 쉽다.
- 핵심 판단 포인트는 readiness 전환, LB deregistration delay, app shutdown timeout, connection close 순서가 배포 성공률을 결정한다는 것이다.
- sticky session은 세션 문제를 간단히 해결한다고 생각하기 쉽다.
- 핵심 판단 포인트는 특정 target 과부하, 배포 중 세션 끊김, scale-in 시 사용자 영향이 생길 수 있다는 것이다.
확인 질문
- Health check는 정상인데 실제 API가 실패하는 이유는 무엇인가?
- health path가 실제 API와 다른 route, dependency, Host, protocol, auth, DB migration 상태를 사용하기 때문이다.
- readiness와 liveness를 나누는 이유는 무엇인가?
- 살아 있는 프로세스와 트래픽을 받을 준비가 된 프로세스를 다르게 다루기 위해서다.
- draining이 배포에서 필요한 이유는 무엇인가?
- 새 요청은 막으면서 기존 요청과 장기 연결이 갑자기 끊기지 않게 시간을 주기 위해서다.
- cloud LB 5xx를 볼 때 앱 로그와 함께 무엇을 봐야 하는가?
- LB access log의 target status, target health reason, listener/rule, security group, subnet/NACL, idle timeout, 최근 배포를 함께 봐야 한다.