【发布时间】:2017-09-03 19:41:44
【问题描述】:
我有一个非常繁忙的网络应用程序:
- 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,以便: * 我让服务器停止接受连接 * 我切断了现有的套接字(包括 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) 如果DB调用中途,会完成吗?
3) 由于我使用的是 express,所以我真的不能轻易use this technique -- 可以吗?
我注意到事件循环包含 5 个套接字。这些套接字存在即使 Nginx 没有运行。我不确定为什么是 5,我不确定这是一个理智的方法......
意见/想法?
【问题讨论】:
标签: node.js sockets nginx keep-alive