Введение в проблему
При получении сигнала завершения работы (SIGTERM) ваш сервер может сразу же прекратить свою работу, что приводит к потере запросов, находящихся в обработке, и возвращению ошибок 502. Чтобы избежать этой проблемы, необходимо реализовать благоприятное завершение работы, которое позволит серверу правильно обработать все текущие запросы и затем завершить свою работу.
Основной шаблон
Для реализации благоприятного завершения работы в Node.js можно использовать следующий шаблон:
import http from "http";
let isShuttingDown = false;
const server = http.createServer(app);
async function gracefulShutdown(signal) {
isShuttingDown = true;
server.close();
const timeout = setTimeout(() => process.exit(1), 30000);
await Promise.all([closeDatabase(), closeRedis(), flushLogs()]);
clearTimeout(timeout);
process.exit(0);
}
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
process.on("SIGINT", () => gracefulShutdown("SIGINT"));
В этом примере мы используем переменную isShuttingDown для отслеживания состояния сервера. Когда сервер получает сигнал завершения работы, мы устанавливаем эту переменную в true и начинаем процесс завершения работы. Мы также устанавливаем таймаут на 30 секунд, после которого сервер будет принудительно завершен, если процесс завершения работы не будет завершен.
Проверка состояния сервера во время завершения работы
Для того чтобы.load balancer мог определить, что сервер находится в процессе завершения работы и не отправлять ему новые запросы, мы можем реализовать проверку состояния сервера:
app.get("/health", (req, res) => {
if (isShuttingDown) return res.status(503).json({ status: "shutting_down" });
res.json({ status: "healthy" });
});
В этом примере мы возвращаем код состояния 503, если сервер находится в процессе завершения работы, что указывает load balancer на то, что сервер не доступен для новых запросов.
Что необходимо очистить
Для того чтобы сервер мог правильно завершить свою работу, необходимо выполнить следующие действия:
- Остановить прием новых запросов
- Завершить обработку текущих запросов (с установкой таймаута)
- Закрыть соединения с базой данных
- Отключиться от Redis и других сообществ
- Очистить буферы журналов
- Отменить регистрацию в системе обнаружения служб
Реализация благоприятного завершения работы в Node.js позволяет серверу правильно обработать все текущие запросы и затем завершить свою работу, что предотвращает потерю запросов и ошибки 502. Это является важным аспектом разработки надежных и масштабируемых серверных приложений.