推理服务滚动升级,新 Pod 就绪后旧 Pod 仍在处理请求,持续约 90 秒,期间两版模型同时对外服务,同一用户连续两次请求拿到格式不同的答案。

真正麻烦的地方在于,几个原因的现象几乎一样。就绪探针通过太早,模型还没预热完;优雅退出时间短于最长请求耗时;Service 端点摘除有延迟,连接仍在旧 Pod;客户端复用了长连接,没有重连。

先记录升级窗口内两版各自的请求量

python -c "import json,collections;rs=[json.loads(l) for l in open('access.jsonl')];print(collections.Counter(r['pod'] for r in rs))"

接着把就绪探针改成真实推理一次再返回

curl -s http://127.0.0.1:8000/readyz?probe=1

优雅退出时间放到大于 P99 请求耗时

python -c "print({'terminationGracePeriodSeconds':120})"

升级期间暂停新流量并等旧连接排空

python rollout.py --drain-seconds 120 --check-inflight

别只看报错消失,验证要多做一步。升级窗口内旧 Pod 请求量归零后才下线,同一用户不会跨版本拿到两种格式,回滚也能在窗口内完成。

提醒一点。模型服务的启动时间远大于普通 Web 服务,就绪探针要探真实推理,优雅退出时间也要按 P99 来给。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189