Как корректно остановить Node.js-сервер (graceful shutdown)?
HTTP и API
Graceful shutdown — остановка, при которой сервер перестаёт принимать новые запросы, дожидается текущих и закрывает ресурсы, а не обрывает соединения.
Зачем
При деплое оркестратор шлёт процессу SIGTERM. Если просто упасть, пользователи получат обрыв запросов, а база и очереди окажутся в неопределённом состоянии.
Шаги
- Поймать
SIGTERMиSIGINT. - Закрыть приём новых соединений:
server.close(). - Дождаться завершения активных запросов.
- Закрыть соединения с БД, Redis, очередями.
- Выйти с кодом 0; по таймауту выйти принудительно.
const server = app.listen(3000);
async function shutdown(signal) {
console.log(`${signal} received`);
server.close(async () => {
await db.end();
process.exit(0);
});
setTimeout(() => process.exit(1), 10_000).unref(); // страховка
}
process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));Подвох
Keep-alive соединения удерживают server.close(). В новых версиях есть server.closeIdleConnections(), а перед остановкой сервис помечают как «не готов» в health-проверке.
Коротко для собеседования
Ловим SIGTERM, перестаём принимать запросы, ждём текущие, закрываем ресурсы и выходим, не забыв про таймаут.