Сегодня поговорим о деплое с нулевым даунтаймом в NodeJs приложении.
Для того что бы это было возможным, ваше приложение должно быть запущено в child process. Например используйте PM2 / ts-node-dev
Итак:
Первое что нам нужно сделать, это сообщить о том, что новый (задеплоенный) процесс готов принимать на себя работу передеплоемого приложения. Для этого необходимо вызвать
process.send(“ready”)
В вашем приложении, после того как все необходимые зависимости перейдут в состояние готовности. Например коннект с базой установится и т.п.
Так же в нашем приложении нужно добавить логику, по завершению всех текущих операций при получении сигнала терминации (SIGINT)
process.on(“SIGINT”, () => {
this.connection.close(); // Например закроем текущие соединение с AMQP и перестанем принимать новые сообщения
setTimeout(() => {
process.exit()
}, 5000) // Подождем 5 сек пока завершаться текущие процессы
})
Запуская такое приложение, например при помощи ts-node-dev, вы можете заметить что после control+c приложение завершается не сразу, а через 5 минут.
Что произойдет:
- Новое приложение, запущенное в child process запускается и сообщает ready, после чего начинает бизнес логику
- одновременно с этим старому процессу посылается SIGINT и оно переходит в режим завершения работы и финализазции, после чего уничтожается.
Пример
class App {
private isOnline = true
public start() {
console.log(“Started”)
this.restartListener()
this.loop()
}
private loop() {
if (!this.isOnline) return
console.log(“Some business logic like redis/sql/amqp and others operation”)
this.loop()
}
private restartListener() {
if (typeof process.send !== “function”) return
process.send(“ready”)
process.on(“SIGINT”, () => {
this.isOnline = false
setTimeout(() => {
process.exit()
}, 3000)
})
}
}