当前位置: 首页 > 知识库问答 >
问题:

node.js从pm2获取SIGINT

洪捷
2023-03-14

我正在尝试使用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个答案

凌修伟
2023-03-14

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

庾和昶
2023-03-14

如果你还没解决...

根据您提供的信息,我假设您是在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字符串。

 类似资料:
  • 问题内容: 我有一个名为“ localhost:3000 / returnStat”的服务,该服务应将文件路径作为参数。例如“ /BackupFolder/toto/tata/titi/myfile.txt”。 如何在浏览器上测试此服务?例如,如何使用Express格式化此请求? 问题答案: 我尚未测试您的代码,但其他方法可行 如果您想从请求网址获取路径信息 1.如果您获取的URL参数仍然无法读取

  • 本文向大家介绍node.js从数据库获取数据,包括了node.js从数据库获取数据的使用技巧和注意事项,需要的朋友参考一下 本文需要用node.js做一个从Sqlserver获取数据并显示到页面上的小功能,下面就为大家分享: app.js: 接下来就直接在页面中使用get方式请求即可,当然post方式也是类似原理。 还有我发现textarea控件在改变其text和html属性的时候,value还保

  • 我想通过“id”从我的mongodb获取数据。如果我的id与mongodb中id的值匹配,则它将获取该对象,但其抛出错误为: {“message”:“对于模型“PostMessage”“”的路径“\u id”处的值“s-CoAhDKd”,转换为ObjectId失败}

  • 问题内容: 我正在尝试让我的函数返回http get请求,但是,无论如何,它似乎在?scope中丢失了。我对Node.js不熟悉,因此不胜感激 问题答案: 当然,您的日志会返回:您在完成请求之前先进行日志。问题不是范围,而是 异步性 。 是异步的,这就是为什么它将回调作为参数的原因。做您在回调中要做的事情(传递给的):

  • 问题内容: 如何从节点外壳访问操作系统? 上下文:我正在节点中编写脚本,该脚本要使用默认程序打开文件,并且执行此操作的命令因操作系统而异。 我已经尝试过使用标准javascript方式来获取操作系统,但是它们没有起作用(出于明显的原因,节点中没有)。 是否可以在不安装非标准模块的情况下执行此操作? 问题答案: 警告 :这可能已过时 node.js中没有对象,因为它没有在浏览器中运行。它在系统中运行

  • 问题内容: 我正在使用带有Node.js的Redis数据库。使用 我存储JSON字符串化作业。 现在,我要遍历所有作业,并同时检索作业ID和字符串化的作业。 我试过了, 但是只检索了键。 我试过了, 但我不知道如何从obj检索键和值。 任何帮助都将不胜感激,因为我被困住了。 问题答案: 这就是它的工作方式。以下代码中的id是记录ID。