503 Service Unavailable: 과부하인가요, 점검 중인가요?
· 읽는 데 2분
오류의 의미
503은 웹 서버가 “여기 있지만 지금은 응답할 수 없습니다”라고 말하는 것입니다. 502와 달리, 뒤쪽의 무언가가 반드시 고장 난 것은 아닙니다. 서버는 세 가지 상황에서 일부러 503을 보냅니다. 점검 모드이거나, 지키도록 설정된 한도(연결, 워커, 대역폭, 요청 속도 제한)에 도달했거나, 너무 과부하되어 살아남기 위해 요청을 쳐내는 경우입니다. 503에는 클라이언트가 언제 다시 와야 하는지 알려 주는 Retry-After 헤더가 포함될 수 있으며, 검색 엔진은 짧은 503을 일시적인 것으로 보고 페이지를 제외하지 않습니다.
흔한 원인
- 점검 모드가 켜진 채 남아 있습니다. WordPress는 업데이트하는 동안
.maintenance파일을 만들고 업데이트가 끝날 때까지 503으로 응답합니다. 업데이트가 중단되면 파일이 그대로 남고 오류도 계속됩니다. Laravel, Magento, Drupal 등 대부분의 프레임워크에도 같은 기능의 스위치가 있습니다. - 과부하. 설정된 워커가 처리할 수 있는 것보다 많은 요청이 들어옵니다. Apache의
MaxRequestWorkers에 도달했거나, PHP-FPM의pm.max_children이 소진되었거나, 데이터베이스가 너무 느려서 모든 워커가 기다리는 경우입니다. - 호스팅 한도. 공유 호스팅은 계정당 CPU 시간, 동시 프로세스, “entry processes”에 상한을 둡니다. 상한에 도달하면 호스팅 업체의 게이트웨이가 내 사이트에 대해서만 503으로 응답합니다.
- 로테이션에서 제외된 백엔드. 로드 밸런서나 CDN 뒤에서 503은 모든 백엔드가 상태 확인에 실패했다는 뜻입니다. Cloudflare는 원본 서버가 과부하 상태이거나 요청 속도 제한에 걸리면 자체 503 페이지를 표시합니다.
- 봇과 스크래퍼. 수천 개의 페이지를 가져가는 크롤러나
wp-login.php또는xmlrpc.php에 대한 무차별 대입 공격이 워커를 소진시켜 정상 방문자가 503을 받습니다. - 가득 찬 디스크 또는 소진된 메모리. 서비스는 켜져 있지만 세션, 캐시 파일, 로그를 쓸 수 없으며, 일부 애플리케이션은 이 상태에서 503으로 응답합니다.
방문자인 경우
1분 기다린 후 새로 고침하세요. 503은 대개 짧게 끝납니다. 사이트가 몇 시간째 503이라면 소유자 쪽에서 점검 모드가 풀리지 않았거나 용량 문제가 있는 것이며, 소유자만 해결할 수 있습니다.
직접 운영하는 사이트라면: 먼저 확인할 것
웹사이트 다운 확인 도구를 실행해 외부에서 503을 확인하고, CDN이 보냈는지 내 서버가 보냈는지 확인하세요. 그런 다음 판단합니다. 최근 몇 분 안에 직접 또는 CMS가 업데이트를 시작했나요? 그렇다면 점검 모드입니다. 아니라면 용량 문제입니다.
직접 운영하는 서버에서:
# 웹 서버가 실행 중인가?
systemctl status nginx
systemctl status apache2
# 부하, 메모리, 디스크: 대부분의 503 뒤에 있는 세 가지 수치
uptime
free -m
df -h
# 지금 누가 사이트에 집중적으로 요청하고 있는가?
sudo tail -n 5000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
CPU 코어 수를 훨씬 넘는 로드 평균, 100 MB 미만의 여유 메모리, 최근 몇 분 동안 수천 건의 요청을 보낸 단일 IP는 각각 503을 설명할 수 있습니다.
직접 운영하는 서버에서의 해결 방법
1. 멈춰 있는 점검 모드 해제
WordPress: 사이트 루트의 .maintenance 파일을 삭제한 다음 사이트를 여세요. 이 파일을 만든 업데이트가 중단되었다면 플러그인이나 코어가 반쯤 설치된 상태일 수 있으니, 대시보드 또는 WP-CLI로 업데이트를 다시 실행하세요.
rm /var/www/example.com/.maintenance
wp core verify-checksums
wp plugin update --all
Laravel: php artisan up. Magento: bin/magento maintenance:disable. Drupal: $settings['maintenance_mode']를 false로 설정하거나 drush state:set system.maintenance_mode 0을 사용하세요.
2. 폭주 막기
문제의 IP나 네트워크를 차단한 다음, 다음에는 같은 일이 생기지 않도록 요청 속도 제한을 추가하세요.
# 주소 하나 차단 (ufw를 사용하는 Debian/Ubuntu)
sudo ufw deny from 203.0.113.45
# 또는 nftables
sudo nft add rule inet filter input ip saddr 203.0.113.45 drop
로그인 페이지에 대한 nginx 요청 속도 제한(http 블록에, 그다음 서버 블록에):
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /wp-login.php {
limit_req zone=login burst=5 nodelay;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
Apache: mod_evasive나 mod_qos가 같은 역할을 합니다. apache-badbots와 wordpress jail이 있는 fail2ban은 반복 위반자를 자동으로 차단합니다.
3. 서버에 용량 확보
부하가 악용이 아니라 실제 트래픽이라면 메모리가 허용하는 범위에서 워커 한도를 올리세요. Apache(mpm_event): MaxRequestWorkers. PHP-FPM: pm.max_children. 먼저 워커당 메모리를 확인하세요: ps -ylC php-fpm8.3 --sort:rss. 그런 다음 테스트하고 다시 불러옵니다.
sudo apachectl configtest && sudo systemctl reload apache2
sudo php-fpm8.3 -t && sudo systemctl reload php8.3-fpm
페이지 캐싱을 켜서(WordPress: 캐시 플러그인 또는 nginx의 FastCGI 캐시) 트래픽이 급증해도 모든 요청마다 PHP가 실행되지 않게 하세요. 캐시된 페이지는 1밀리초의 일부만 소요되지만, 캐시 없는 WordPress 페이지는 수백 밀리초가 소요됩니다.
4. 디스크 확보
sudo du -xh --max-depth=1 /var | sort -h | tail
sudo journalctl --vacuum-size=200M
sudo apt clean
오래된 로그 파일, 같은 디스크에 보관된 백업, 폭주하는 디버그 로그가 흔한 원인입니다.
5. 로드 밸런서 뒤에서
모든 백엔드가 동시에 상태 확인에 실패하는 것은 대개 모든 백엔드가 고장 났기 때문이 아니라 확인 URL 자체가 망가졌기 때문입니다(삭제된 상태 확인 페이지, 확인 도구가 따라가지 않는 HTTPS 리디렉션). 로드 밸런서에서 상태 확인 URL을 직접 요청해 보세요.
호스팅 업체의 문제인 경우
공유 호스팅에서는 한도를 올릴 수 없습니다. 호스팅 업체에 어떤 한도에 도달했는지, 내 트래픽 때문인지 같은 서버의 다른 계정 때문인지 문의하세요.
안녕하세요. 제 웹사이트 example.com이 약 09:10 UTC부터 “503 Service Unavailable”로 응답합니다. 업데이트를 시작한 적이 없고 사이트는 점검 모드가 아닙니다. 제 계정이 리소스 한도(CPU, 프로세스, 메모리)에 도달한 것인지, 서버가 과부하 상태인지, 그리고 수치가 어떻게 되는지 알려 주시겠습니까? 제 계정 때문이라면 어떤 한도에 언제부터 도달했는지도 알려 주시기 바랍니다.
“계정이 한도에 도달했다”는 답이 정기적으로 돌아온다면, 사이트에 캐시를 제대로 적용하거나 용량이 더 큰 요금제나 서버로 옮기세요.
다음번을 막으려면
503은 미리 예고합니다. 부하가 서서히 올라가고, 메모리가 바닥나고, 한 IP가 폭주하기 시작합니다. 웹사이트 확인은 503을 1분 안에 잡아내며, 서버 에이전트는 그 단계에 이르기 전에 부하, 메모리, 디스크를 보여 줍니다. 직접 운영하는 서버에서는 Quick Fix가 디스크 공간을 확보하고 멈춘 서비스를 고정 가격으로 재시작하며, Deep Fix가 요청 속도 제한과 캐시를 설정해 다음에는 서버가 계속 유지되도록 합니다.
다음 단계
다운되었나요? 당사가 대응합니다.
직접 운영하는 서버나 SSH 접근이 가능한 웹 공간에서: 흔한 원인은 고정 가격의 Quick Fix로, 나머지는 15분 단위로 청구되는 Deep Fix로 24시간 처리합니다. 주문 전에 가격을 확인할 수 있습니다.
복구 요청하기