Node.js 从 pm2 获取 SIGINT

问题描述 投票:0回答:5

我正在尝试使用 pm2 将我的节点应用程序作为服务运行。

现在,可以启动和停止应用程序。但是,我想要优雅地关闭。

我的应用程序已经侦听 SIGINT,关闭服务器,然后退出进程。然而,尝试让 pm2 发送 SIGINT,只会导致应用程序重新启动,就像 pm2 杀死并再次启动它一样。

这就是我创建流程的方式:

pm2 启动 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 进程名称

再次重新启动应用程序。

阅读 pm2 文档,我发现 pm2 还会向应用程序发送

shutdown
事件,所以我添加了:

process.on('message', function(msg) {
    if (msg == 'shutdown') {
        server.end().then(() => {
            process.exit();
        }).catch((err) => {
            console.error(err);
        });
    }
});

这也不起作用。

知道如何解决这个问题吗?

谢谢!

node.js pm2
5个回答
5
投票

如果你还没有解决...

根据您提供的信息,我假设您在 Windows 上运行它。

您的应用无法捕获 Windows 上 PM2 发送的

SIGINT

shutdown
消息也适用于 Windows,但只能通过
gracefulReload
命令发送。


(更新)
这些不是完整的解决方案,但可能会有所帮助(希望......)

sendSignal
命令最终调用
process.kill()
,其中一些 信号 可能会起作用(尚未尝试)。

我还发现了以下方法。仅当 autorestart

选项打开
off时,这才可以正常关闭进程而无需重新启动
然后,如果发生意外,您的集群将不会重新加载,因此这可能不是您想要的...

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
  }
});

并使用

node
运行第一个文件,并将要关闭的集群的 id 作为参数。

条件中额外

msg.type == 'shutdown'
的原因是
pm2.sendDataToProcessId()
要求参数是具有这些键的对象,并且不接受简单的
shutdown
字符串。


1
投票

一般来说,

pm2 stop
是停止应用程序的正确方法。但是,如果您在 Docker 内部运行应用程序,则需要使用
pm2-runtime
而不是
pm2
,它是
pm2
npm 包的一部分,并将系统
SIGINT
传递给所有子进程。请参阅 http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs


0
投票

捕获信号并优雅退出应该可以在您的第一个示例中起作用。

要实际停止服务器,请使用

pm2 stop
而不是
pm2 sendSignal SIGINT ProcessName

参见 http://pm2.keymetrics.io/docs/usage/signals-clean-restart/


0
投票

对于 Windows 服务器,您可能还需要捕获

SIGBREAK
。请务必尝试使用该方法以及
SIGINT
SIGTERM
来正常关闭。


0
投票

使用 pm2 start app.js —shutdown-with-message 运行应用程序

使用 pm2 stop app.js 停止应用程序

© www.soinside.com 2019 - 2024. All rights reserved.