502/503/504 장애 런북

Web Server와 WAS 사이에서 자주 만나는 502, 503, 504를 계층별로 좁히는 운영 런북


이 런북의 범위

Client
  -> LB / WAF
  -> Nginx or Apache HTTP Server
  -> Tomcat
  -> Application / DB / external API

502, 503, 504는 대부분 앞단 Web Server나 Gateway가 뒤쪽 서버와 통신하는 과정에서 드러난다. 상태 코드는 원인을 확정하지 않고, 어느 계층부터 볼지 알려주는 단서로 사용한다.

상태 코드 감 잡기

코드보통의 의미먼저 볼 곳
502upstream에서 정상 응답을 받지 못함WAS 포트, 프로세스, proxy 설정, protocol mismatch
503서비스가 일시적으로 처리 불가backend down, health check, worker 한계, maintenance
504upstream 응답을 기다리다 timeoutTomcat thread, DB query, 외부 API, proxy timeout

같은 502라도 Nginx, Apache mod_proxy, mod_jk, LB가 만든 오류 페이지가 다를 수 있다. 브라우저 화면보다 access log와 error log를 기준으로 판단한다.

처음 5분

  1. 장애 시간, URL, Host, client IP, 재현 여부를 적는다.
  2. Web Server access log에 요청이 남았는지 확인한다.
  3. 같은 시간대 Web Server error log를 본다.
  4. Tomcat process와 Connector port가 살아 있는지 확인한다.
  5. Tomcat access/application/catalina log에 같은 요청 흔적이 있는지 찾는다.
  6. 직전 배포, 설정 reload, 인증서 교체, 방화벽 변경이 있었는지 확인한다.

공통 명령

date
hostname
ss -lntp
ps -ef | grep tomcat
systemctl status nginx
systemctl status httpd
systemctl status tomcat

앞단에서 직접 호출:

curl -sv -H 'Host: example.com' http://127.0.0.1/
curl -sv http://127.0.0.1:8080/
curl -sv http://127.0.0.1:8080/app/health

로그 확인:

tail -n 200 /var/log/nginx/error.log
tail -n 200 /var/log/httpd/error_log
tail -n 200 $CATALINA_BASE/logs/catalina.out
journalctl -u nginx -n 200
journalctl -u httpd -n 200
journalctl -u tomcat -n 200

502 접근

502는 앞단이 backend로 연결했지만 정상적인 HTTP 응답을 받지 못했을 때 자주 나온다.

흔한 단서확인
connection refusedTomcat 미기동, 포트 불일치, process crash
no route / timed out while connecting방화벽, 보안 그룹, routing
upstream prematurely closedTomcat 재기동, JVM crash, 애플리케이션 강제 종료
invalid responseHTTP/AJP protocol mismatch, 잘못된 upstream 포트
bad gateway after deploycontext path, proxy path, 애플리케이션 기동 실패

확인 순서:

  1. proxy_pass, ProxyPass, JkMount가 가리키는 host와 port를 확인한다.
  2. 해당 포트가 listen 중인지 ss -lntp로 본다.
  3. Web Server에서 backend URL을 직접 curl로 호출한다.
  4. Tomcat이 재기동되었는지 catalina log와 system journal을 본다.
  5. AJP 구성이라면 HTTP 포트에 AJP로 붙거나, AJP 포트에 HTTP로 붙은 것은 아닌지 확인한다.

503 접근

503은 backend가 없거나, health check에서 제외되었거나, 현재 요청을 받을 수 없는 상태일 때 나타난다.

흔한 단서확인
no live upstreamsNginx upstream health, backend 전체 down
service unavailableTomcat 미기동, maintenance, application startup 실패
worker downmod_jk worker 상태, AJP 연결 실패
queue full / overloadApache worker, Tomcat thread, DB pool

확인 순서:

  1. backend 전체가 죽었는지 일부 node만 죽었는지 나눈다.
  2. health check URL이 실제로 200을 반환하는지 직접 호출한다.
  3. mod_jk라면 workers.properties, jk.log, worker 상태를 확인한다.
  4. Apache MPM worker 여유와 Tomcat thread 여유를 같이 본다.
  5. 점검 페이지나 maintenance 설정이 켜져 있는지 확인한다.

504 접근

504는 앞단이 backend 응답을 기다리다 timeout된 상태다. 앞단에서는 실패로 끝났어도 Tomcat이나 애플리케이션에서는 요청 처리가 계속 진행 중일 수 있다.

흔한 단서확인
upstream timed outproxy_read_timeout, ProxyTimeout, backend 지연
특정 API만 504해당 API의 DB query, 외부 API 호출, lock
전체적으로 느림Tomcat thread 고갈, GC pause, DB 장애
재시도 후 성공backend 일부 node 지연, connection pool 대기

확인 순서:

  1. access log의 request time과 upstream time을 본다.
  2. Tomcat thread dump를 10초 간격으로 여러 번 남긴다.
  3. application log에서 같은 요청 ID나 시간대의 지연 지점을 찾는다.
  4. DB slow query, lock, connection pool 대기를 확인한다.
  5. timeout을 늘리기 전에 실제 처리 시간이 왜 길어졌는지 확인한다.

Tomcat thread dump:

jcmd <PID> Thread.print > /tmp/tomcat-thread-1.txt
jcmd <PID> Thread.print > /tmp/tomcat-thread-2.txt
jcmd <PID> Thread.print > /tmp/tomcat-thread-3.txt

로그 문구별 빠른 매핑

로그 문구우선 의심
connect() failedbackend 포트 닫힘, 방화벽
connection refusedTomcat down, 포트 불일치
upstream timed outbackend 응답 지연, timeout
prematurely closed connectionbackend crash, restart, 연결 종료
worker is in error statemod_jk worker down
Broken pipeclient 중단, proxy 연결 종료

문구는 제품과 버전에 따라 달라질 수 있다. 핵심은 요청이 어느 로그까지 도달했는지와, 연결 실패인지 응답 지연인지 구분하는 것이다.

임시 조치와 원인 분석 분리

목적가능한 조치
사용자 영향 완화문제 node 제외, rollback, maintenance 안내
처리량 회복Tomcat 재기동, worker 수 조정, DB connection 회복
지연 완화느린 API 차단, 외부 연동 우회, timeout 임시 조정
근거 확보로그 백업, thread dump, heap dump, 설정 diff 보관

임시 조치 후에는 반드시 원인을 다시 좁힌다. timeout을 늘려서 504가 사라졌다면 장애가 해결된 것이 아니라 느린 처리를 더 오래 기다리게 만든 것일 수 있다.

관련 문서

관련 블로그 기록

공식 문서

닫기 전 질문

  • 이 오류 페이지는 LB, Nginx, Apache HTTP Server, Tomcat 중 누가 만든 것인가?
  • 요청은 Web Server access log, error log, Tomcat log 중 어디까지 도달했는가?
  • 502/503/504 중 연결 실패, backend 제외, 응답 지연 중 어느 쪽인가?
  • 임시 조치로 증상이 사라진 뒤에도 원인 근거를 남겼는가?