awesome-everything EN
↑ Обратно к восхождению

Архитектура бэкенда

Graceful shutdown: ноль потерянных запросов на деплое

Суть Практический проект — построй сервис, теряющий запросы на деплое, затем заставь его завершаться gracefully и докажи нулевую потерю запросов на rolling-деплое числами до/после.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 240 min

Читать про гонку deregistration — не то же самое, что смотреть, как твой собственный деплой сбрасывает 502, а потом заставить их исчезнуть. Построй маленький сервис, теряющий запросы на каждом rollout, прогони под нагрузкой и примени дисциплину юнита — сигнал, deregister, drain, disposition, координация — пока rolling-деплой не станет невидим клиенту, с доказательством на каждом шаге.

Цель

Преврати ментальную модель юнита в воспроизводимый инженерный цикл: воспроизведи потерю запросов на деплое под нагрузкой, затем добавь корректный путь shutdown и координацию флота, и докажи нулевую (или почти нулевую) потерю на rolling-деплое метриками до/после.

Проект
0 из 7
Цель

Возьми маленький HTTP-сервис с одним медленным эндпоинтом и одним воркером очереди, задеплой его на Kubernetes (kind/minikube подойдут) и сведи потерю запросов на деплое к нулю — или к задокументированному ограниченному минимуму — доказывая каждый шаг измерениями, а не утверждениями.

Требования
Критерии приёмки
  • Таблица до/после: error rate в окне деплоя, счётчики 502/reset/refused, p99 latency запросов во время roll и задвоенные/потерянные side effects задач — измеренные под идентичной нагрузкой, не оценочно.
  • Логи, доказывающие, что SIGTERM-обработчик срабатывает, readiness переключается до закрытия листенера, и ресурсы закрываются в reverse dependency order; путь guardian timeout прогнан хотя бы раз и делает чистый force-exit.
  • Демонстрация kill-посреди-задачи, показывающая, что side effect применяется ровно один раз после передоставки, доказывая идемпотентность consumer.
  • Числа после показывают нулевую (или задокументированную ограниченную почти-нулевую) потерю запросов на rolling-деплое, при этом всплеск connection-refused и проседание capacity оба исчезли.
  • Параграф разбора, называющий, какой рычаг починил каждый failure mode (PID 1, readiness+preStop, drain в reverse-order, requeue+идемпотентность, surge+jitter) и почему порядок имел значение.
Senior-стретч
  • Добавь on-call runbook: как читать всплеск ошибок в окне деплоя, пять failure mode и их исправления, и чеклист проверки перед деплоем.
  • Измерь и подстрой реальный deregistration delay: инструментируй время от провала readiness до последнего отмаршрутизированного запроса и размерь preStop sleep и окно drain под ≈3× наблюдаемого p99 вместо угаданной константы.
  • Воспроизведи и затем почини thundering reconnect явно: прогони тысячи keep-alive клиентов, покажи, как неджиттерный синхронный close опрокидывает холодные поды, затем покажи, как jitter сглаживает кривую reconnect.
  • Повтори эксперимент с долгоживущими соединениями (WebSocket/SSE или большие загрузки): подними deregistration delay до 600s+ и покажи чистое отклонение через 503 + Retry-After для операций, не влезающих в бюджет.
Итог

Это цикл, который ты прогонишь для каждого реального сервиса, прежде чем доверять ему под churn: сначала воспроизведи потерю на деплое, затем чини по порядку — заставь SIGTERM дойти до обработчика в PID 1, провали readiness и выжди deregistration до того, как перестанешь принимать, сдрейнируй keep-alive и сделай teardown в reverse dependency order под guardian timeout, отклони или идемпотентно поставь в requeue работу, не влезающую в бюджет, и подними это до флота с surge-перед-drain и jittered closes. Докажи каждый шаг числами до/после под идентичной нагрузкой. Сделав это раз на игрушечном сервисе, ты доводишь продакшн-версию до мышечной памяти — и превращаешь «мы теряем пару запросов на каждом деплое» в деплой, которого никто не замечает.

Продолжить восхождение ↑Собираем воедино: бэкенд — это система, а не стопка
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.