Operations note · lifecycle
Как правильно остановить Node.js сервер?
Короткий ответ
Сначала перестаньте принимать новую работу, затем дождитесь активных запросов и соединений до явного deadline, после чего закройте transport и внешние ресурсы. Не смешивайте graceful path с аварийным close: у swm-core shutdown(timeout) ждёт активную работу, а close() завершает сервер немедленно.
- drain
- активная работа
- deadline
- явный timeout
- close()
- аварийный путь
Границы ответа
Последовательность описывает server lifecycle @swarmmachina/swm-core 5.1.2 для Node.js 22/24. Реальный deadline должен учитывать orchestration grace period, reverse proxy и длительность вашего background work.
Порядок graceful shutdown
| Этап | Действие | Проверка |
|---|---|---|
| 1. Сигнал | Получите stop signal и зафиксируйте абсолютный deadline, а не бесконечное ожидание. | Тест процесса подтверждает, что второй signal не запускает повторный shutdown race. |
| 2. Приём | Снимите instance из discovery или перестаньте принимать новые requests и upgrades. | Новый HTTP request и WebSocket upgrade получают ожидаемый отказ во время drain. |
| 3. Drain | Дайте существующим обработчикам завершиться в пределах shutdown timeout. | Долгий request либо завершается штатно, либо контролируемо достигает deadline. |
| 4. Соединения | Для WebSocket определите close code, срок уведомления и судьбу недоставленных сообщений. | Клиентский тест фиксирует close event и reconnect path. |
| 5. Ресурсы | После прекращения входящей работы закройте logger, client pools и фоновые workers. | Последнее лог-событие и завершение ресурсов проверяются интеграционным тестом. |
| 6. Fallback | После deadline используйте немедленный close и ненулевой operational signal, если это требуется платформой. | Тест не оставляет process или listen socket жить после превышения лимита. |
Правила, которые предотвращают зависание
- 01
Orchestrator даёт короткое окно остановки
Согласуйте один бюджет времениApplication timeout должен оставлять запас на отключение proxy, завершение process и fallback.
- 02
Есть long-lived WebSocket
Определите политику подключенияБез close reason и reconnect поведения «graceful» остаётся только названием.
- 03
Нужна немедленная остановка
Вызывайте отдельный close pathОн должен быть явным, чтобы аварийное завершение нельзя было спутать с успешным drain.
Что graceful shutdown не делает сам
- Он не превращает незавершённый request в идемпотентную операцию и не отменяет необходимость retry protocol.
- Он не гарантирует доставку WebSocket-сообщений после close без внешнего durable слоя.
- Он не заменяет readiness, liveness и timeout политику окружения.
Первичные источники
Server API и связанную logging-последовательность можно проверить по зафиксированным исходникам релизов.