Node.js getting SIGINT from pm2

删除回忆录丶 提交于 2020-01-14 13:59:28

问题


I'm trying to use pm2 to run my node app as a service.

Right now, starting and stopping the app works. However, I want to do a graceful shutdown.

My app already listens for SIGINT, shutdowns the server and then exits the process. However, trying to put pm2 to send the SIGINT, just causes the app to restart, like if pm2 was killing and starting it again.

This is how I create the process:

pm2 start server.js --name ProcessName --silent --kill-timeout 3000

Here's my app's code for listening the SIGINT:

process.on("SIGINT", function () {
    //graceful shutdown
    server.end().then(() => {
        process.exit();
    }).catch((err) => {
        console.error(err);
    });

});

Then to shutdown the app using pm2, I'm running:

pm2 sendSignal SIGINT ProcessName

Which, again, restarts the app.

Reading over pm2 docs, I found that pm2 will also send a shutdown event to the app, so I added:

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

Which isn't working either.

Any idea how to solve this?

Thanks!


回答1:


If you haven't solved it yet...

Based on the information you provided, I assume you are running it on Windows.

Your app cannot catch SIGINT sent by PM2 on Windows.
shutdown message works on windows too, but it is sent only by gracefulReload command.


(update)
These are not complete solutions, but might be helpful (hopefully...)

sendSignal command calls process.kill() eventually, and some of these signals might work (haven't tried).

I also found the below method. This can gracefully shutdown a process without restarting only if autorestart option is turned off.
And then your clusters will not reload in case of an accident, so it might not be what you want though...

pm2 lets you send a custom message (reference).
Put the code below in a new file:

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

Modify the part that listens the shutdown message like below:

process.on('message', function(msg){
  if(msg == 'shutdown' || msg.type == 'shutdown'){
    // code to clean up
  }
});

And run the first file with node with id of the cluster you want to shutdown as an argument.

The reason for extra msg.type == 'shutdown' in the condition is that pm2.sendDataToProcessId() requires the argument to be an object with those keys, and does not accept simple shutdown string.




回答2:


In general pm2 stop is the right way to stop your application. However if you run appliation inside of the Docker you need to use pm2-runtime instead of pm2 which is a part of pm2 npm package and passes system SIGINT to all child processes. See http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs




回答3:


Catching the sigint and exiting gracefully should work in your first example.

To actually stop the server, use pm2 stop instead of pm2 sendSignal SIGINT ProcessName.

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



来源:https://stackoverflow.com/questions/50607260/node-js-getting-sigint-from-pm2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!