SERVER ERROR CLINIC
503 Service Unavailable
서버가 지금은 요청을 받을 수 없다고 스스로 답했습니다. 고장이 아니라 거절이라는 점에서 502와 다릅니다.
이 도구는 여러분의 서버에 접속하지 않습니다. 답한 내용만으로 확인할 순서를 정해주는 도구이며, 실제 로그를 대신하지 않습니다.
- 브라우저요청을 보낸 곳
- 인터넷이름 찾기·연결
- 프록시여기가 의심됩니다
- 앱Node·Spring·Django
- DB·외부 API앱이 부르는 곳
어느 로그를 볼까 프록시 로그를 먼저 봅니다. 프록시가 스스로 낸 503인지, 앱이 만들어 보낸 503인지에 따라 원인이 완전히 갈립니다.
언제 나타나나요?
항상 나면 설정 문제, 몰릴 때만 나면 용량 문제일 때가 많습니다.
가장 먼저 확인할 것
넘겨줄 서버가 하나도 남지 않았다
프록시가 건강검사에 실패한 서버를 목록에서 빼다 보니 전부 빠졌습니다. 그래서 시도조차 하지 않고 503으로 답합니다.
다른 후보가 하나씩 제외되면서 남은 원인입니다.
프록시가 검사하는 그 주소가 실제로 답하는지 직접 확인합니다.
curl -i --max-time 5 http://127.0.0.1:3000/
그다음 건강검사 경로가 앱에 실제로 존재하는지 봅니다. /health를 검사하는데 앱에는 그 경로가 없어 404가 나면 계속 실패로 집계됩니다.
아니라면 다음
받을 수 있는 양을 넘겼다
동시 처리 한도나 대기줄이 가득 차서 새 요청을 즉시 거절합니다. 서버를 지키기 위한 의도된 동작입니다.
부하와 연결 수가 실제로 높은지 봅니다.
uptime && ss -s | head -5
그다음 한도를 올리는 건 그다음입니다. 먼저 요청 하나가 얼마나 오래 자리를 차지하는지 재봅니다.
동시 연결이 늘면 생기는 일 →아니라면 다음
점검 모드거나 요청 제한에 걸렸다
설정이 의도적으로 503을 돌려주고 있습니다. 점검 페이지나 요청 수 제한이 켜져 있는 경우입니다.
503을 직접 돌려주는 설정이 있는지 찾습니다.
grep -rn 'return 503\|limit_req\|maintenance' /etc/nginx /etc/caddy 2>/dev/null
그다음 점검 모드를 끄거나, 요청 제한이 정상 트래픽까지 막고 있지 않은지 기준을 다시 잡습니다.