场景:使用http.createServer()
目标:当SIGNINT
出现时(以我的情况为PM2重新加载),请正常关闭服务器,然后关闭数据库连接,然后和平退出。
代码:
// index.js
server.keepAliveTimeout = 10
process.on('SIGINT', () => {
server.close(err => {
// close the DB
...
process.exit(0)
})
})
// the code related to any API response
const headers = {
...
'Connection': 'close'
}
response.writeHead(statusCode, headers)
return response.end(JSON.stringify(data))
问题:永远不会触发server.close
回调。 PM2进程在20秒后达到超时(以我为例),因此关机不再正常。
调查原因:如果没有打开浏览器连接(例如,如果没有人调用API)或使用Firefox进行API调用,则可以很好地触发回调。取而代之,使用Chrome浏览器,我在触发请求后可以在chrome://net-internals/#sockets
中看到1个空闲的transport_socket_pool。在这种情况下,close
回调不会触发。一旦清除Chrome中的空闲套接字,回调就会正确触发。请注意,在Chrome的隐身模式下,套接字不会保持空闲状态,而是正确关闭,因此会触发回调。
问题:
Connection: close
和短keepAliveTimeout
是否足以通知任何客户端它们不应该长时间打开任何套接字?server.close
完成?