Safest way to stop a node instance

淺唱寂寞╮ 提交于 2019-12-12 01:48:28

问题


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

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