503 Service Unavailable: перегрузка, техработы и Retry-After
Ответ 503 Service Unavailable означает, что сервер жив и намеренно отказывается делать работу, потому что перегружен или находится на техработах. В отличие от падения, 503 это решение, и RFC 9110 описывает это состояние как временное и, скорее всего, проходящее через некоторое время.
Жив и отказывается работать
Чтобы вообще вернуть 503, что-то должно работать: соединение TCP принято, запрос разобран, ответ сформирован. Один этот факт исключает целый класс проблем. Хост поднят, сетевой путь работает, TLS согласован, веб-сервер или прокси функционируют. Не хватает емкости или готовности.
RFC 9110 делает оговорку: сервер не обязан отвечать 503 при перегрузке. Некоторые просто отклоняют соединение. То есть 503 это вежливая форма перегрузки. Если вместо него вы получаете отказ в соединении или таймаут, перед вами другой и обычно более тяжелый отказ.
Двух соседей легко перепутать. 504 Gateway Timeout означает, что бэкенд принял запрос и потом не ответил вовремя: попытка была. Код 503 означает, что запрос отклонили до того, как началась настоящая работа. Все семейство сравнивается в обзоре 5xx.
Retry-After и почему его стоит отправлять всегда
RFC 9110 разрешает ответу 503 нести заголовок Retry-After в одной из двух форм: число секунд ожидания или абсолютная дата в формате HTTP.
HTTP/1.1 503 Service Unavailable
Retry-After: 300
Content-Type: text/html
Он ничего не стоит. Корректные клиенты и библиотеки выдерживают указанный интервал вместо того, чтобы долбить и без того тяжело дышащий сервер. Поисковые роботы считают URL временно недоступным и возвращаются позже, а не принимают сбой за удаление контента. Ваш собственный мониторинг и страница статуса получают явное ожидаемое время восстановления, которое можно показать.
Ответ 503 по умолчанию не кэшируется, поэтому промежуточные узлы не будут отдавать его после восстановления сервиса.
Что вызывает 503
- Перегрузка. Все рабочие потоки, процессы или слоты соединений заняты, и новые запросы отклоняются, а не встают в бесконечную очередь. Обычно начинается эпизодически на пике и становится постоянной по мере роста нагрузки.
- Режим техработ. Намеренный переключатель: флаг фреймворка, файл-маркер или правило на прокси. Здесь 503 делает ровно то, для чего он есть.
- Отказала зависимость. Хорошо написанное приложение, которое не может достучаться до базы, кэша или очереди, должно вернуть 503, а не трассировку стека, потому что состояние временное и вины запроса в нем нет.
- Нет живых бэкендов. Балансировщику, у которого все участники не проходят проверку здоровья, некуда направлять трафик, и многие в таком состоянии отвечают 503.
- Выкладки и перезапуски. Окно между сливом старого процесса и готовностью нового.
- Намеренный сброс нагрузки. Предохранители и контроль допуска возвращают 503 специально, чтобы защитить работающие части системы.
- Исчерпание ресурсов на уровне хоста. Кончилась память, кончились файловые дескрипторы или переполнился диск, и новая работа не может начаться.
Ошибка 503 во время выкладки
Это самый частый 503, который не является настоящим инцидентом, и у него узнаваемая форма: короткая пачка ошибок 503 длиной от секунд до пары минут, начинающаяся ровно на релизе и заканчивающаяся сама. Прежде чем что-то расследовать, сопоставьте отметки времени с историей выкладок.
Правильно сделанный 503 на техработах должен:
- Возвращать настоящий код состояния. Страница техработ, отданная с кодом 200, сообщает поисковым роботам, что ваш контент теперь и есть объявление о техработах, а это худший исход планового окна.
- Нести
Retry-Afterс реалистичной оценкой длительности окна. - Оставаться статичным и дешевым. Страница техработ не должна зависеть от базы или приложения, которые вы только что выключили.
- Пропускать ваши собственные адреса, чтобы команда могла проверить новый релиз до открытия.
- Быть заведенным в мониторинге как окно техработ, чтобы плановая остановка не поднимала дежурного.
Внеплановые 503 на выкладке лечит плавное обновление с контролем готовности: запустить новый процесс, дождаться, пока он пройдет проверку готовности, и только потом слить и остановить старый. Сделанное как надо, оно не оставляет окна, в котором отвечать некому.
Как починить внеплановый 503
- Подтвердите код и прочитайте заголовки, в том числе был ли отправлен
Retry-Afterи какой компонент подписал ответ:curl -sS -o /dev/null -D - https://example.com/ - Первым делом исключите режим техработ. Проверьте, не остался ли флаг или файл после релиза. Это случается чаще, чем принято признавать.
- Проверьте здоровье бэкендов. На балансировщике посмотрите, сколько участников проходит проверки. Ноль живых участников это готовый ответ.
- Посмотрите на насыщение. Занятость воркеров и пулов соединений, память, соединения с базой, глубина очередей. Ошибка 503 под нагрузкой, когда все упирается в потолок, это емкость, а не баг.
- Проверьте зависимости. Если лежит база, кэш или критичный API, чинить надо их, а не веб-слой.
- Снимите нагрузку, потом ищите причину. Масштабирование или поднятие лимитов вернет сервис, но 503, появившийся без роста трафика, обычно прячет медленный запрос или утечку, и они вернутся.
Ошибки 503 на пике и плановые окна техработ
Перегрузочные 503 задолго до того, как стать постоянными, ведут себя эпизодически: появляются в часы пика и уходят сами. Эту раннюю фазу трудно поймать из браузера и легко увидеть в непрерывной записи. Проверка HTTP по расписанию, которая сверяет ожидаемый код состояния, превращает разрозненные отказы в видимый тренд с привязкой ко времени, и вы успеваете действовать до того, как эпизодическая фаза станет простоем. Заведенные в том же инструменте окна техработ не дают плановым 503 порождать оповещения.