问题
I have a very busy web application:
- Nginx as the "front", acting as a reverse proxy
- Node server running on unprivileged ports, queried by Nginx
The application uses websockets (one socket open for each client). Nginx is configured in a very typical fashion:
server {
listen X.Y.255.3:443 ssl http2;
server_name example.com;
client_max_body_size 0;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
location / {
proxy_pass http://localhost:8082;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
My idea is that when I want to stop the server I do the following: I send a SIGTERM, so that: * I get the server to stop accepting connections * I cut off existing sockets (including websockets) * I clear up intervals and timeouts
At that point, the server should quit itself, since the event loop should be empty (once the last DB writes etc. are done).
I coded it this way:
...
var server = http.createServer(app);
process.on('SIGTERM', function(){
server.close();
console.log("TERMINATING THIS INSTANCE!");
// This will make sure hotplate modules will get dir
// of intervals and lose ends
process.emit( 'hotplateShutdown');
var handles = Array.prototype.slice.call(process._getActiveHandles())
console.log( "Event loop has: ", handles.length );
handles.forEach( (o ) => { console.log( "Dealing with:", o.readyState ); o.unref && o.unref(); } );
});
server.listen(app.get('port'), app.get('ipAddress'), function () {
console.log("Express server listening on port " + app.get('port'));
});
If after 10 seconds the process is still going, I send a SIGKILL (something is wrong at that point). However, note that I can re-run the server pretty much immediately, as after SIGTERM the server stops listening to the binding port. This means minimal downtime on restarts.
The websockets are killed as they should be.
Questions:
1) Is this a sane way to go about this?
2) If a DB call is half way, will it be completed?
3) Since I use express, I cannot really easily use this technique -- can I?
I noticed that the event loop contains 5 sockets. Those sockets are there even when Nginx is not running. I am not sure why 5, and I am not sure this is a sane way to go...
Comments/ideas?
回答1:
SIGTERM and SIGKILL are daemon-threads which are made for exactly this stuff, i.e, terminating or killing the processes.
Is this a sane way to go about this?
If nothing is going wrong then yes it's sane.
If a DB call is a half way, will it be completed?
Yes, I can assure you that if some db call is on-going, then it will be completed before killing the process.
Since I use express, I cannot really easily use this technique -- can I?
I don't think you can and I still think killing the process is a better solution.
A Little while ago I did something like this on AWS Elastic Beanstalk where I have to kill the worker and restart it again. Well, there I have AWS SDK's methods like
- restartAppServer
- killTheEnviornment
but I did research on this and I found this. Maybe this will help you.
来源:https://stackoverflow.com/questions/43294764/safest-way-to-stop-a-node-instance