503 Service Unavailable: перевантаження, обслуговування і Retry-After
503 Service Unavailable означає, що сервер живий і навмисно відмовляється виконувати роботу, бо він перевантажений чи на обслуговуванні. На відміну від краху, 503 - це рішення, і RFC 9110 описує цей стан як тимчасовий і такий, що, ймовірно, мине через деякий час.
Живий, але відмовляє в роботі
Щоб узагалі повернути 503, щось має працювати: воно прийняло TCP-з'єднання, розібрало запит і згенерувало відповідь. Сам цей факт виключає цілий клас проблем. Хост працює, мережевий шлях справний, TLS завершився, а вебсервер чи проксі функціонує. Чого бракує - це ємності чи бажання.
RFC 9110 додає застереження: сервер не зобов'язаний використовувати 503 при перевантаженні. Деякі просто відмовляють у з'єднанні натомість. Тож 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.
- Деплої й перезапуски. Вікно між зупиненням старого процесу і готовністю нового.
- Навмисне скидання навантаження. Запобіжники (circuit breakers) і контроль допуску навмисно повертають 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 генерувати сповіщення.