最安全的方法来停止节点实例

时间:2017-04-08 13:32:34

标签: node.js sockets nginx keep-alive

我有一个非常繁忙的网络应用程序:

  • Nginx作为“前线”,充当反向代理
  • 在非特权端口上运行的节点服务器,由Nginx查询

应用程序使用websockets(每个客户端打开一个套接字)。 Nginx以非常典型的方式配置:

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

我的想法是,当我想停止服务器时,我会执行以下操作: 我发送SIGTERM,以便:  *我让服务器停止接受连接  *我切断了现有的插座(包括腹板)  *我清理间隔和超时

此时,服务器退出,因为事件循环应为空(一旦完成最后一次数据库写操作等)。

我用这种方式编码:

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

如果10秒后该过程仍在继续,我发送一个SIGKILL(此时出现问题)。但请注意,我可以立即重新运行服务器,因为在SIGTERM之后服务器停止侦听绑定端口。这意味着重启时停机时间最短。

websockets应该被杀死。

问题:

1)这是一种理智的方式吗?

2)如果DB呼叫是中途,是否会完成?

3)因为我使用快递,所以我不能轻易use this technique - 我可以吗?

我注意到事件循环包含5个套接字。即使Nginx没有运行,那些套接字也在那里。我不确定为什么5,我不确定这是一个理智的方式......

评论/想法?

1 个答案:

答案 0 :(得分:0)

SIGTERM和SIGKILL是守护程序线程,它们是针对这些内容而制作的,即终止或终止进程。

  

这是一个理智的方式吗?

如果没有出错,那么是的,这是理智的。

  

如果DB呼叫是中途,那么它会完成吗?

是的,我可以向您保证,如果某个数据库调用正在进行,那么它将在终止进程之前完成。

  

由于我使用快递,我不能轻易使用这种技术 - 我可以吗?

我认为你不能,我仍然认为杀死这个过程是一个更好的解决方案。

不久之前,我在AWS Elastic Beanstalk上做了类似的事情,我必须杀死工作人员并重新启动它。好吧,我有AWS SDK的方法,比如

  • restartAppServer
  • killTheEnviornment

但我对此进行了研究,我找到了this。也许这会对你有帮助。