停服演练删掉一个副本,网关侧 40 个正在处理的请求全部变成 502,应用日志里 shutdown 只打了一行。进程从收到信号到消失不到 1 秒。日志里能对上时间点,这种反而好排。
进程收到 SIGTERM 后没有停止接收新连接,也没有等在途请求结束,直接走退出流程。容器宽限期虽然写着 30 秒,preStop 没配时信号一到就开始倒计时,进程自己先走了。这一点先确认清楚,后面就不用反复试。
kubectl delete pod api-6f8c --grace-period=30
kubectl get pod api-6f8c -o jsonpath='{.spec.terminationGracePeriodSeconds}'
curl -s localhost:8080/actuator/health
「优雅停机 在途请求」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
处理上按这个顺序:在 preStop 里先 sleep 5 到 10 秒 等负载均衡把地址摘干净再发信号;应用侧收到 SIGTERM 后先关监听 再等在途请求跑完 最后才退出;把 terminationGracePeriodSeconds 调到大于最长请求耗时 留出余量;用压测流量重放一次删除动作 统计 5xx 数量。
结果对不对很好判断,重复删 Pod 十次,网关侧 5xx 为 0,日志里能看到等待在途请求的记录。
