把一个大模型推理服务从线上摘下来,最怕的操作是直接杀进程:用户请求发到一半突然断开,队列里排着的任务凭空蒸发,日志里只剩一串连接中断的记录。优雅停机走的是另一条路——先把门关上,把手头的活干完,再熄灯走人。这背后的门道,比「温柔地关服务」六个字要多得多。
打个比方:餐厅打烊前,服务员先在门口立一块「最后点单」的牌子,新来的客人被礼貌劝回,已经落座的客人照常上菜,等最后一桌结账离开才真正锁门。类比失效的地方也得说清:餐厅客人看得见牌子,推理服务的调用方却只看得到接口,你不主动通知,对方根本不知道服务正在退场。所以真实系统里,「立牌子」要靠公告、接口返回码和文档三件套一起补齐。
还有一层容易忽略:优雅停机不只发生在计划内更新里。机房迁移、硬件替换、弹性缩容,都会触发下线动作,把这套机制做成所有退场路径的默认行为,才算真正掌握。
直接掐断进程会出什么乱子
强杀进程的第一层损失在用户侧:正在生成的回答停在半截,客户端拿到的是网络错误而不是明确的「服务不可用」,重试逻辑可能立刻把流量砸向别的实例,引发连锁雪崩。第二层损失在数据侧:队列里未处理的请求、写到一半的缓存、还没落盘的日志,都可能丢失。更麻烦的是,排查这类问题时往往只能看到「连接被重置」这类模糊线索,定位成本很高。
优雅停机的完整流程
标准流程分四步。第一步,向服务进程发送停止信号,通知它准备退场。第二步,服务把自己从注册中心摘除,负载均衡器不再把新请求分过来,这一步相当于「停止接客」。第三步,给存量请求留一个宽限期,比如三十秒,让正在生成的回答完整吐完;宽限期到了还没结束的请求,才会被强制断开。第四步,释放显存、关闭连接、退出进程。四步走完,下线才算干净。
四步各自的动作,以及漏做之后会出什么乱子:
| 步骤 | 服务侧动作 | 漏做的后果 |
|---|---|---|
| 第一步 | 收到停止信号,通知进程准备退场 | 只能强杀,队列里未处理的请求、写到一半的缓存跟着丢 |
| 第二步 | 从注册中心摘除,负载均衡不再分新请求 | 新请求继续涌入,宽限期被白白消耗 |
| 第三步 | 留宽限期,比如三十秒,让存量回答吐完 | 正在生成的回答停在半截,客户端只拿到网络错误 |
| 第四步 | 释放显存、关闭连接、退出进程 | 日志里只剩一串连接中断,排查只能看到「连接被重置」 |
像 DeepSeek、通义千问这类托管大模型服务在版本更新时,调用方通常只感觉响应略有波动,正是这套流程在背后兜底的体现。
健康检查在停机时怎么配合
健康检查是「立牌子」的技术载体。停机一开始,服务应立刻把健康状态改成不可用,让上游探活失败、自动分流;如果健康检查还报正常,上游就会继续送新请求进来,宽限期被白白消耗。这里有个常被忽略的细节:探活周期和结果缓存可能带来几十秒的延迟,所以健康状态要尽早翻转,宽限期要覆盖探活的最大延迟。
优雅停机速查表
- 先摘流量,再停进程,顺序不能反
- 宽限期覆盖最长单次响应时间加探活延迟
- 通知调用方:公告、返回码、文档三件套
- 下线后回看日志,确认无半截请求
想把这个流程跑稳,还要配上压力验证。上线前先看容量压力测试是怎么做的?每一步都讲透,确认宽限期设多长合理;发布当天对照上线前的检查清单有哪些?机制细节全梳理逐项打钩;如果是多机房架构,多地域部署是怎么降延迟的?过程拆开看里的分流思路能让停机期间流量迁移更平滑;新实例顶上来时的首请求变慢问题,则交给冷启动是怎么消除的?预热,关键步骤一次讲清来处理。
聊聊优雅停机的常见疑问
- 宽限期设多长合适?:它取决于最长的一次响应时间,一般取峰值响应加几秒余量,宁可稍长也不要掐断正在生成的回答。
- 滚动更新和它有什么关系?:滚动更新就是把优雅停机重复执行——每次只下线一小部分实例,等替补实例就绪再继续,服务全程不中断。
- 什么情况下只能硬停?:进程已经僵死、无法响应停止信号时,只能强制终止,这也是平时要演练兜底预案的原因。


