503 Service Unavailable
사용법
503 Service Unavailable 상태 코드는 일시적인 이유로 서버가 HTTP 요청을 수행할 수 없다는 뜻입니다. 갑작스러운 트래픽 급증으로 서버에 과부하가 걸렸거나, 리소스가 잠겨 있거나, 서버가 재부팅 중이거나, 방화벽 설정 오류가 요청을 막고 있는 상황입니다.
많은 사이트가 사이트 점검 중에 503 Service Unavailable 상태 코드를 반환하며, 이는 검색 순위에 영향을 주지 않도록 하기 위해 권장되는 방식입니다.
잠긴 리소스나 과부하된 리소스처럼 서버가 문제를 인지하고 있는 경우, Retry-After HTTP 헤더가 클라이언트에게 언제 요청을 다시 보낼지 알려 줍니다.
Amazon S3는 요청 속도가 접두사별 처리량 한도를 초과하면 503 Slow Down을 반환합니다. 이 임계값을 넘는 갑작스러운 급증은 S3가 백그라운드에서 파티션을 확장하는 동안 스로틀링을 유발합니다. 객체를 여러 접두사에 분산하고, 지수 백오프를 구현하며, 요청 속도를 점진적으로 올리면 이 오류를 피할 수 있습니다. S3는 503 응답에 대해 과금하지 않습니다.
Fastly는 요청이 같은 Fastly 서비스로 되돌아가는 것처럼 보이거나 너무 많은 Fastly 서버를 거친 경우 “Loop detected”라는 사유 문구와 함께 503 Service Unavailable을 반환합니다. Fastly는 Fastly-FF와 CDN-Loop 헤더로 요청의 홉을 추적합니다. 요청이 다음 한도 중 하나라도 초과하면 루프로 간주되어 거부됩니다. 같은 서비스에 대해 같은 POP를 세 번 넘게 거친 경우, 요청 경로에 여섯 개를 넘는 고유 Fastly 서비스가 있는 경우, 또는 전체 서비스에 걸쳐 총 홉이 스무 번을 넘는 경우입니다. 루프는 흔히 동일한 호스트명이 서비스의 도메인이자 백엔드로 설정되어 있고 그 호스트명의 DNS가 Fastly로 해석될 때 발생합니다. 백엔드에 별도의 오리진 호스트명(예: origin.example.re)이나 IP 주소를 사용하면 루프를 피할 수 있습니다.
참고
503은 서버가 모든 클라이언트에 대해 일시적으로 사용 불가능하다는 뜻입니다(과부하, 점검). 429는 특정 클라이언트가 자신의 속도 제한을 초과했다는 뜻입니다. 클라이언트별 스로틀링에는 429를, 서버 전체의 사용 불가에는 503을 사용하세요.
SEO 영향
Googlebot은 5xx 오류를 사이트 전체의 크롤링 속도를 일시적으로 줄이라는 신호로 취급합니다. 이전에 색인된 URL은 처음에는 유지되지만, 장애가 길어지면 Google이 색인에서 제거합니다. 503 응답과 함께 반환된 콘텐츠는 무시됩니다. Google은 500, 502, 503을 동일하게 취급합니다. 흔히 그렇게 조언하지만, 계획된 점검에서 503이 다른 5xx 코드보다 특별히 유리하지는 않습니다. robots.txt 파일의 5xx 오류는 사이트의 다른 모든 페이지가 200을 반환하더라도 훨씬 심각합니다. Google은 최대 12시간 동안 크롤링을 중단한 뒤, 최대 30일까지 캐시된 사본으로 대체합니다. 오류가 계속되면 Google은 해당 사이트를 완전히 색인에서 제외합니다. Bingbot은 재방문 일정을 잡을 때 503 응답의 Retry-After를 존중합니다. 503 응답이 지속되면 Bing에서 색인이 이루어지지 않습니다.
예시
클라이언트가 리소스를 요청하고, 해당 리소스를 일시적으로 사용할 수 없으므로 서버는 503 Service Unavailable로 응답합니다. Retry-After 헤더는 30분 뒤에 요청을 다시 보낼 것을 제안합니다.
요청
GET /latest_quotes HTTP/1.1
Host: example.com
응답
HTTP/1.1 503 Service Unavailable
Content-Type: text/html; charset=UTF-8
Content-Length: 124
Retry-After: 1800
<html>
<head>
<title>Resource Busy</title>
</head>
<body>
<p>Try again after 30 minutes.</p>
</body>
</html>
해결 방법
해당 503이 의도된 것인지(점검 모드) 계획에 없던 것인지(과부하, 크래시) 판단하세요. Retry-After 헤더와 함께 제공되는 의도된 503은 디버깅이 필요 없으며, 점검이 끝나기를 기다리기만 하면 됩니다.
계획에 없던 503 오류라면 다음의 흔한 원인들을 확인하세요.
서버 자원 고갈. 서버에서 top, htop, vmstat를 실행하세요. CPU나 메모리 사용률이 높다면 서버의 용량이 부족한 것입니다. Apache에서는 모든 워커 슬롯이 사용 중일 때 오류 로그에 “server reached MaxRequestWorkers setting”이 나타납니다. Apache 설정에서 MaxRequestWorkers(그리고 prefork MPM의 경우 ServerLimit)를 올리세요. nginx에서는 events 블록의 worker_connections를 늘리세요.
애플리케이션 풀 크래시. PHP-FPM, Gunicorn 또는 유사한 프로세스 관리자가 부하를 받다 종료되면 웹 서버가 요청을 처리할 백엔드를 잃게 됩니다. 프로세스 관리자 로그를 확인한 뒤 풀 크기를 늘리세요(PHP-FPM의 pm.max_children, Gunicorn의 —workers).
커넥션 풀 고갈. 데이터베이스나 외부 API 커넥션 풀이 바닥나면 애플리케이션이 새 요청을 거부하게 됩니다. 애플리케이션 설정에서 풀 크기를 늘리고, 사용 후 커넥션이 제대로 반납되는지 확인하세요.
속도 제한. nginx의 limit_req와 limit_conn 모듈은 임계값을 초과하면 503(또는 지정한 상태)을 반환합니다. limit_req_zone과 limit_conn_zone 지시문을 검토하세요. 트래픽 급증을 흡수하려면 burst 값을 올리거나 nodelay를 추가하세요.
로드 밸런서 헬스 체크 실패. 헬스 체크가 실패하면 서버가 순환에서 빠집니다. AWS ALB/NLB에서는 콘솔에서 대상 상태를 확인하세요. nginx의 upstream 블록에서는 max_fails와 fail_timeout 설정을 검토하세요.
배포로 인한 재시작. 인스턴스 수가 너무 적은 상태의 롤링 배포는 짧은 503 구간을 만듭니다. 최소 정상 인스턴스 수를 늘리거나 블루-그린 배포를 사용하세요.
AWS S3 스로틀링(503 Slow Down). S3는 접두사별 요청 속도 한도를 초과하는 요청을 스로틀링합니다. 무작위 키 접두사(예: hex-hash/original-key)를 사용해 객체를 여러 접두사에 분산하세요. 1초에서 시작하는 지수 백오프를 구현하세요. 트래픽을 한꺼번에 몰아 보내지 말고 요청 속도를 점진적으로 올리세요. AWS SDK는 올바르게 설정하면 503 SlowDown 응답을 백오프와 함께 자동으로 재시도합니다.
트래픽 급증에 대해서는 정적 요청을 덜어내도록 CDN이나 캐싱 계층을 추가하세요. 자원 제약이 전면 장애로 번지기 전에 드러나도록 503 비율에 대한 모니터링과 알림을 설정하세요.
코드 참고
.NET
HttpStatusCode.ServiceUnavailable
Rust
http::StatusCode::SERVICE_UNAVAILABLE
Rails
:service_unavailable
Go
http.StatusServiceUnavailable
Symfony
Response::HTTP_SERVICE_UNAVAILABLE
Python3.5+
http.HTTPStatus.SERVICE_UNAVAILABLE
Java
java.net.HttpURLConnection.HTTP_UNAVAILABLE
Apache HttpComponents Core
org.apache.hc.core5.http.HttpStatus.SC_SERVICE_UNAVAILABLE
Angular
@angular/common/http/HttpStatusCode.ServiceUnavailable