我尝试使用pm2将节点应用作为服务运行。
现在,启动和停止应用有效。但是,我想要优雅地关闭。
我的应用已经侦听了SIGINT,关闭了服务器,然后退出了进程。但是,尝试将pm2发送到SIGINT,只会导致应用程序重新启动,就像pm2正在杀死并再次启动它一样。
这是我创建流程的方式:
pm2 start server.js --name ProcessName --silent --kill-timeout 3000
这是我的应用程序用于收听SIGINT的代码:
process.on("SIGINT", function () {
//graceful shutdown
server.end().then(() => {
process.exit();
}).catch((err) => {
console.error(err);
});
});
然后使用pm2关闭应用程序,我正在运行:
pm2 sendSignal SIGINT ProcessName
再次重启应用程序。
阅读pm2文档,我发现pm2还会向应用发送shutdown
个事件,所以我补充道:
process.on('message', function(msg) {
if (msg == 'shutdown') {
server.end().then(() => {
process.exit();
}).catch((err) => {
console.error(err);
});
}
});
哪个也没有。
知道如何解决这个问题吗?
谢谢!
答案 0 :(得分:1)
如果你还没有解决它......
根据您提供的信息,我假设您在Windows上运行它。
您的应用无法捕获PM2在Windows上发送的SIGINT
shutdown
消息也适用于Windows,但它仅由gracefulReload
命令发送。
(更新)
这些不是完整的解决方案,但可能会有所帮助(希望......)
sendSignal
命令最终调用process.kill()
,其中一些signals可能有效(未尝试过)。
我也找到了以下方法。只有当 autorestart
选项关闭时,才能正常关闭流程而无需重新启动。
然后你的集群在发生事故时不会重新加载,所以它可能不是你想要的......
pm2可让您发送自定义消息(reference) 将下面的代码放在一个新文件中:
var pm2 = require('pm2');
var id = process.argv[2];
pm2.connect(() => {
pm2.sendDataToProcessId({
type: 'shutdown',
data:{some: 'data'},
id: id,
topic: 'some topic'
}, (err, res) => {
console.log('message sent');
pm2.disconnect();
if(err) throw err;
})
});
修改侦听shutdown
消息的部分,如下所示:
process.on('message', function(msg){
if(msg == 'shutdown' || msg.type == 'shutdown'){
// code to clean up
}
});
运行带有node
的第一个文件,并将要关闭的群集的 id 作为参数。
条件中额外msg.type == 'shutdown'
的原因是pm2.sendDataToProcessId()
要求参数是具有这些键的对象,并且不接受简单的shutdown
字符串。
答案 1 :(得分:1)
通常,pm2 stop
是停止应用程序的正确方法。但是,如果您在Docker内部运行应用程序,则需要使用pm2-runtime
而不是pm2
,后者是pm2
npm软件包的一部分,并将系统SIGINT
传递给所有子进程。参见http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs
答案 2 :(得分:0)
抓住sigint并优雅地退出应该适用于你的第一个例子。
要实际停止服务器,请使用pm2 stop
代替pm2 sendSignal SIGINT ProcessName
。
请参阅http://pm2.keymetrics.io/docs/usage/signals-clean-restart/