웹 서비스 장애의 첫 단서는 거의 항상 HTTP 상태코드입니다. "안 된다"가 아니라 "몇 번이 떴는가"로 시작하면, 클라이언트 문제인지 서버 문제인지, 앱 문제인지 프록시 문제인지가 빠르게 갈립니다. 특히 리버스 프록시(nginx 등) 뒤에서 뜨는 5xx는 어느 구간이 끊겼는지를 코드가 말해줍니다.
큰 그림 — 4xx와 5xx의 책임 구분
4xx는 요청 쪽 문제, 5xx는 서버 쪽 문제입니다. 책임 주체가 다르니 보는 곳도 다릅니다.
| 코드 | 의미 | 1순위 점검 |
|---|---|---|
| 400 | 잘못된 요청 형식 | 클라이언트 요청 바디·헤더 |
| 401 / 403 | 인증 없음 / 권한 없음 | 토큰·인증 헤더·권한 정책 |
| 404 | 경로 없음 | 라우팅·리라이트 규칙 |
| 429 | 요청 과다 | 레이트 리밋 설정 |
| 500 | 앱 내부 예외 | 애플리케이션 로그 |
| 502 / 504 | 업스트림 연결 실패 / 응답 지연 | 프록시-백엔드 구간 |
502 vs 504 — 결정적 차이
둘 다 프록시가 백엔드(업스트림)와 통신하다 실패한 것이지만, 실패 방식이 다릅니다.
502 Bad Gateway— 프록시가 백엔드에 연결했는데 응답이 깨졌거나 백엔드가 죽음. 연결 거절, 비정상 종료, 잘못된 응답이 전형적. 즉시 실패에 가깝습니다.504 Gateway Timeout— 프록시가 백엔드를 기다렸으나 시간 안에 응답이 안 옴. 백엔드는 살아 있지만 느린(슬로우 쿼리·블로킹) 경우. 정해진 타임아웃을 다 채우고 실패합니다.
즉 502는 "백엔드가 끊겼다", 504는 "백엔드가 느리다"로 읽으면 됩니다.
로컬 또는 서버
curl -v https://app.example.com/api # 어느 코드·어느 단계인지
진단 순서
상태코드를 읽었다면 구간을 좁힙니다.
- 클라이언트에서 직접 호출 —
curl -i로 응답 코드와 헤더 확인.Server헤더로 어느 계층이 응답했는지(프록시인지 앱인지) 가립니다. - 프록시 로그 확인 — nginx라면
error.log에upstream관련 메시지가 502·504의 직접 원인을 적어줍니다. - 백엔드를 프록시 우회해 직접 호출 — 프록시를 빼고 백엔드 포트로 바로
curl. 여기서 정상이면 프록시 설정 문제, 여기서도 실패면 앱 문제.
로컬 또는 서버
curl -i http://127.0.0.1:3000/health # 백엔드 직접 (프록시 우회)
ss -tlnp | grep :3000 # 백엔드가 실제 리슨 중인지
504가 잦다면 프록시의 proxy_read_timeout 같은 타임아웃과 백엔드 처리 시간을 함께 봅니다. 타임아웃만 늘리는 건 근본 해결이 아니라 슬로우 응답을 가리는 것일 수 있습니다.
점검 체크리스트
로컬 또는 서버
curl -i <URL> # 상태코드·Server 헤더
curl -i http://127.0.0.1:<백엔드포트>/ # 프록시 우회 직접 호출
ss -tlnp | grep :<백엔드포트> # 백엔드 리슨 여부
# 502 → 백엔드 다운/거절, 504 → 백엔드 지연
상태코드로 구간을 좁히고 프록시·백엔드를 직접 끊어보며 진단하는 실습은 네트워크 트랙에서 회원가입 없이 무료로 할 수 있습니다.