我正在尝试使用pm2来运行我的节点应用程序作为服务。
现在,启动和停止应用程序正常工作。但是,我想做一个优雅的关机。
我的应用程序已经监听SIGINT,关闭服务器,然后退出进程。然而,试图把pm2发送信号,只会导致应用程序重新启动,就像如果pm2杀死并重新启动它一样。
这就是我创建流程的方式:
pm2 start server.js--name ProcessName-silent-kill-timeout 3000
下面是我的应用程序监听信号的代码:
process.on("SIGINT", function () {
//graceful shutdown
server.end().then(() => {
process.exit();
}).catch((err) => {
console.error(err);
});
});
然后要关闭使用pm2的app,我正在运行:
pm2发送信号SIGINT进程名
这再次会重新启动应用程序。
通过阅读pm2文档,我发现pm2也会发送shutdown
事件到应用程序,所以我添加了:
process.on('message', function(msg) {
if (msg == 'shutdown') {
server.end().then(() => {
process.exit();
}).catch((err) => {
console.error(err);
});
}
});
这也不起作用。
有办法解决吗?
谢谢!
如果你还没解决...
根据您提供的信息,我假设您是在Windows上运行的。
您的应用程序无法在windows上捕获PM2发送的sigint
。shutdown
消息也可以在windows上使用,但它只能通过gracefulreload
命令发送。
(更新)
这些不是完整的解决方案,但可能会有帮助(希望...)
sendsignal
命令最终调用process.kill()
,其中一些信号可能起作用(尚未尝试)。
我还找到了下面的方法。只有在autorestart
选项关闭时,这才能优雅地关闭进程而不重新启动。
这样,群集在发生意外时不会重新加载,因此可能不是您想要的...
pm2允许您发送自定义消息(引用)。
将下面的代码放入新文件:
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
}
});
并以要关闭的集群的id作为参数运行第一个带有node
的文件。
条件中出现额外的msg.type=='shutdown'
的原因是pm2.sendDataProcessId()
要求参数是具有这些键的对象,并且不接受简单的shutdown
字符串。
通常,pm2 stop
是停止应用程序的正确方法。但是,如果您在Docker内部运行应用程序,则需要使用pm2-runtime
而不是pm2
,后者是pm2
npm包的一部分,并将systemsigint
传递给所有子进程。参见http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs