我创建了一个最小的快递 POC,只有一个基本路由在 30 秒后使用 setTimeout 发送 hello world。
我发送了一个 HTTP 请求并开始等待。同时我跟踪了节点的PID并从终端杀死了它。
SIGTERM 事件被触发和处理如下:
process.on('SIGTERM', () => {
console.log(`[SIGTERM received]`)
console.log(`[closing http server]`)
server.close(() => {
console.log(`[Http server closed]`)
process.exit(0)
})
})
出现了前两个日志,如果我尝试设置另一个 http 请求,它就会失败。正是我想要的。但是,当第一个 http 请求最终完成并返回时,可能有 3-5 秒的间隙,我可以线程另一个 http 请求!然后它可以再等 30 秒并完成,然后我可以设置另一个等等。
如果有大量请求,例如 k8s,将完全不正常地关闭它,并且所有这些请求都将失败(达到超时)。
为什么会发生,它是 Nodejs v14 中的错误吗?当最后一个 http 请求结束时,该进程应该立即停止并且永远不会收到任何类型的其他请求。然后告诉像 k8s 这样的管理器,容器现在已停止,并且允许终止 pod。
完整的行为应该是这样的:
假设我们只有一个 pod。
然后我们升级版本。
K8S 开始创建一个新的 pod,当新的 pod 被创建时,它会停止将任何新请求路由到旧的。
它不会也不应该终止旧的 pod,除非它清楚地表明他已经完成了最后一个 http 请求的服务。
然后应该终止旧的 pod,我们的停机时间为零——这是使用 K8S 的核心原因之一。