我正在尝试使用 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);
});
});
Run Code Online (Sandbox Code Playgroud)
然后使用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);
});
}
});
Run Code Online (Sandbox Code Playgroud)
这也不起作用。
知道如何解决这个问题吗?
谢谢!
如果你还没有解决...
根据您提供的信息,我假设您正在 Windows 上运行它。
您的应用程序无法SIGINT在 Windows 上捕获 PM2 发送的消息。
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;
})
});
Run Code Online (Sandbox Code Playgroud)
修改监听消息的部分shutdown如下:
process.on('message', function(msg){
if(msg == 'shutdown' || msg.type == 'shutdown'){
// code to clean up
}
});
Run Code Online (Sandbox Code Playgroud)
node并使用要关闭的集群的 id作为参数运行第一个文件。
msg.type == 'shutdown'条件中额外的原因是pm2.sendDataToProcessId()要求参数是具有这些键的对象,并且不接受简单shutdown字符串。
在您的第一个示例中,捕获信号并优雅退出应该可行。
要实际停止服务器,请使用pm2 stop而不是pm2 sendSignal SIGINT ProcessName.
请参阅http://pm2.keymetrics.io/docs/usage/signals-clean-restart/
| 归档时间: |
|
| 查看次数: |
5842 次 |
| 最近记录: |