我有一个非常繁忙的Web应用程序:
应用程序使用websockets(每个客户端打开一个套接字)。 Nginx以非常典型的方式configuration:
server { listen XY255.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,以便:*让服务器停止接受连接*切断现有套接字(包括websockets)*清除间隔和超时
此时,服务器应该自行退出,因为事件循环应该是空的(一旦最后一次数据库写入完成)。
我这样编码:
... 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)如果数据库调用中途中断,是否完成?
3)由于我使用快递,我不能很容易地使用这种技术 – 我可以吗?
我注意到事件循环包含5个套接字。 即使Nginx没有运行,那些套接字也在那里。 我不知道为什么5,我不知道这是一个理智的方式去…
评论/想法?
SIGTERM和SIGKILL是守护线程,正是为了这个东西,即终止或杀死进程。
这是一个理智的方式去做这个?
如果没有什么问题,那么是的,这是理智的。
如果一个数据库调用是一半的话,它会被完成吗?
是的,我可以向你保证,如果一些数据库调用正在进行,那么在杀死进程之前就会完成。
由于我使用快递,我不能很容易地使用这种技术 – 我可以吗?
我不认为你可以,我仍然认为杀死这个过程是一个更好的解决方案。
前一段时间,我在AWS Elastic Beanstalk上做了这样的事情,我必须杀掉worker并重新启动它。 那么,我有AWS SDK的方法
但是我研究了这个,我发现了这个 。 也许这会帮助你。