停止节点实例的最安全方法 [英] Safest way to stop a node instance

查看:133
本文介绍了停止节点实例的最安全方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a very busy web application:

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

该应用程序使用websocket(每个客户端打开一个套接字). 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;
        }
    }

我的想法是,当我想停止服务器时,请执行以下操作: 我发送SIGTERM,以便: *我让服务器停止接受连接 *我切断了现有的套接字(包括websocket) *我清除间隔和超时

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

此时,服务器应该退出自身,因为事件循环应该为空(一旦完成最后一次DB写操作等).

At that point, the server should quit itself, since the event loop should be empty (once the last DB writes etc. are done).

我是这样编码的:

        ...
        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之后,服务器将停止监听绑定端口.这意味着重启时停机时间最少.

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.

websocket被杀了.

The websockets are killed as they should be.

问题:

1)这是解决问题的明智方法吗?

1) Is this a sane way to go about this?

2)如果数据库调用中途进行,是否可以完成?

2) If a DB call is half way, will it be completed?

3)因为我使用快递,所以我真的不能轻易地

3) Since I use express, I cannot really easily use this technique -- can I?

我注意到事件循环包含5个套接字.即使Nginx未运行,这些套接字也存在 .我不确定为什么5,而且我不确定这是否是明智的选择...

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...

评论/想法?

推荐答案

SIGTERM和SIGKILL是为这些内容(即终止或终止进程)而创建的守护程序线程.

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.

不久前,我在AWS Elastic Beanstalk上做了类似的事情,在这里我必须杀死工作程序并重新启动它.好吧,我有类似

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
  • killTheEnvirornment

但是我对此进行了研究,发现.也许这会对您有所帮助.

but I did research on this and I found this. Maybe this will help you.

这篇关于停止节点实例的最安全方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆