LabHub

Tomcat & nginx 운영 · 업스트림 부하분산과 장애 격리 · 이론

서버를 두 대 두는 것과 장애를 견디는 것은 다르다

LabHub 에서 이어서 보기

한 줄 요약

부하분산의 첫 목적은 요청을 반씩 나누는 것이 아니라, 한 서버의 실패가 전체 서비스의
실패로 번지지 않게 만드는 것입니다.

왜 이게 필요했나

백엔드를 두 대 띄우고 nginx upstream 에 넣었다고 고가용성이 완성되지는 않습니다.
죽은 서버를 언제 제외할지, 연결을 재사용할지, 세션을 어디에 보관할지 정하지 않으면
사용자는 요청할 때마다 성공과 실패를 번갈아 보게 됩니다. 특히 WAS 메모리에 세션을
두고 ip_hash로만 고정하면 서버 추가·제거 순간에 배정이 달라져 대량 로그아웃이
발생할 수 있습니다.

어떻게 동작하나

라운드로빈은 요청을 순서대로 보내지만 처리 시간이 긴 요청이 섞이면 서버별 실제
부하는 달라집니다. least_conn은 처리 중인 연결 수를 기준으로 보내 이런 편차를
줄입니다. max_failsfail_timeout은 능동 헬스체크가 아니라 실제 요청 실패를
관찰해 서버를 잠시 제외하는 수동 방식입니다. 그래서 트래픽이 전혀 없으면 장애도
발견하지 못합니다. 업스트림 Keep-Alive는 연결 비용을 줄이지만 keepalive,
HTTP/1.1, Connection 헤더 정리 세 조건이 함께 맞아야 합니다.

현장에서 만나는 모습

장애가 가끔만 보이면 먼저 액세스 로그에 $upstream_addr를 남겨 백엔드별로 결과를
나눕니다. 특정 주소에서만 5xx가 나면 분배 알고리즘보다 배포·설정 차이를 먼저 봐야
합니다. 반대로 모든 주소가 동시에 느리면 공통 DB나 하류 서비스를 조사합니다.

다음 실습에서 할 것

두 백엔드를 직접 띄워 라운드로빈, 가중치, 세션 고정, 실패 제외와 연결 재사용을
비교합니다. 마지막에는 알고리즘마다 언제 쓰고 언제 피해야 하는지 운영 기준으로
정리합니다.