提问者:小点点

node.js从pm2获取SIGINT


我正在尝试使用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);
        });
    }
});

这也不起作用。

有办法解决吗?

谢谢!


共2个答案

匿名用户

如果你还没解决...

根据您提供的信息,我假设您是在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,后者是pm2npm包的一部分,并将systemsigint传递给所有子进程。参见http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs