问题
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