服务启动、六类冒烟与回滚
一句话收获:健康检查不能止于 HTTP 200,回滚后也要重新证明业务能力。
这个场景在解决什么问题
目标(goal)是验证进程、依赖、能力、Loop、业务和回退——不是只看服务起没起来,而是把这六个维度都验一遍,并且在出问题后能正确回滚。
观察方式(observation)是:候选版本启动后,逐层运行冒烟测试。冒烟测试(smoke test)的意思是先做一轮快速的基础检查,确认系统"点得着、不冒黑烟",再往下走。
这个场景值得单独学,是因为绝大多数"部署成功"的判断都停在"端口能通、返回 200",但那只是进程活着,离业务能用还差很远。而且回滚这件事,很多人以为"换回旧镜像"就结束了,其实回滚之后还要重新证明业务能力是真的恢复了。
先理清这条判断链(文字版)
整个过程是一条"启动 → 分层验证 → 发现问题 → 回滚重验"的闭环:
- 先启动与就绪:让数据库、队列、模型、知识、Runtime、API 按依赖顺序起来,确认进程健康、依赖可达、迁移完成;
- 再六类冒烟:依次检查启动、模型、知识、工具、Loop、业务结果这六类,每一类留独立证据;
- 遇到候选版本失败:比如工具状态处理错误触发红线,部署流程就停止放行;
- 最后回滚并重验:恢复镜像、配置、数据库、索引、模型路由,再跑关键冒烟,确认业务能力真的恢复。
一句话:先确认真就绪 → 六类分别冒烟 → 失败就停 → 回滚后再验业务。每一步都不能用"整体看起来正常"糊弄过去。
逐层详解
第 1 步:启动与就绪
原文:数据库、队列、模型、知识、Runtime 和 API 按依赖启动。
白话:服务不是"点一个启动按钮"就完事,它内部有一串组件,得按依赖关系一个一个起来:先数据库、队列,再加载模型、知识库,再起 Runtime,最后对外暴露 API。顺序错了,后面的组件会找不到前面的依赖。
类比:像开机启动一台电脑——先通电、加载 BIOS、再启动操作系统、最后才轮到桌面软件。你不能先开软件再开系统,顺序和依赖是死的。
举例:你的 Agent 系统依赖 PostgreSQL(存对话)、Redis(队列)、一个向量库(知识检索)、一个模型推理服务(Runtime)。启动时要先确认数据库和队列起来了,再加载模型和知识库,最后才把 API 挂出去。中间任何一环没就绪,API 即使能返回 200 也是假的。
为什么重要:进程存活与服务就绪是两种状态。进程活着(能 ping 通、返回 200)不等于服务真正就绪,它可能数据库还没连上、模型还没加载完,这时候来的请求都会失败。
怎么验证(证据点):
- 进程健康:进程本身是活的;
- 依赖可达:数据库、队列等依赖都能连上;
- 迁移完成:数据库 schema 迁移跑完、没报错。
别踩的坑(边界):端口可达不证明业务能力可用。端口能通、HTTP 能返回 200,只说明网络和进程没死,不代表它真能干活。
落地检查:继续运行真实能力检查。别停在"端口通了",接着去做真实的业务能力验证。
第 2 步:六类冒烟
原文:依次检查启动、模型、知识、工具、Loop 和业务结果。
白话:把"系统是否正常"拆成六个独立的检查项,一项一项过:启动是否成功、模型输出是否正常、知识检索是否引用正确、工具调用是否拿到回执、Loop(Agent 的多轮决策循环)是否能转起来、最终业务结果是否对。每类都单独出证据。
类比:像体检分科——不是"我觉得我挺健康",而是血常规、心电图、CT 一项一项查,哪项有问题就精确定位到哪个器官。
举例:你部署完 Agent 后做冒烟:第 1 项看服务启动日志没报错;第 2 项发个问题看模型能不能输出结构化结果;第 3 项看它检索知识库时引用是否准确;第 4 项看它调一个工具能不能拿到正确回执;第 5 项看它多轮决策 Loop 能不能走通;第 6 项看最终业务结果(比如生成的报告)对不对。
为什么重要:分层结果能定位故障位置。如果把六类混在一起只看一个"总结果",出问题时你不知道是模型坏了、工具坏了还是知识检索坏了;分开验,才能一眼定位到具体那一层。
怎么验证(证据点):
- 模型结构输出:模型能输出符合预期结构的结果;
- 知识引用:知识检索引用准确;
- 工具回执:工具调用能拿到正确回执。
别踩的坑(边界):一个总的系统正常会掩盖局部失败。整体看起来"跑通了",可能某一类(比如工具调用)其实已经失败,只是被其他正常的环节盖住了。
落地检查:每类测试有独立证据。六类冒烟每一类都要留一份独立的证据记录,不能只留一个"整体 OK"的结论。
第 3 步:候选版本失败
原文:工具状态处理错误触发红线,部署流程停止放行。
白话:冒烟测到某一类出问题——比如工具状态处理错误——就触发了上线"红线",这个候选版本不能被放行到生产,部署流程在这里直接停下。
类比:像机场安检——行李箱里扫出违禁品(红线触发),不管其他东西多正常,这一箱都必须扣下,不能放行登机。
举例:新版本部署后,冒烟发现 Agent 调用某个工具时,对工具返回的"错误状态"处理不对,导致任务失败。这个缺陷属于已知高风险,于是上线 Gate(质量闸门)判定不通过,停止把这个版本继续推给用户。
为什么重要:上线 Gate 应阻止已知高风险缺陷。Gate 的作用就是在问题还没到用户手上之前拦住它,明知道有高风险缺陷还放行,等于把风险转嫁给生产。
怎么验证(证据点):
- 失败任务:哪个任务、哪一步失败了;
- 影响范围:这个失败影响多大范围;
- 回滚点可用:有可用的回滚点能退回去。
别踩的坑(边界):容器仍运行不代表候选可继续使用。容器没崩、进程还在,不代表这个版本能用——它可能已经带着致命缺陷,必须回滚而不是"先凑合用"。
落地检查:执行版本回滚。一旦判定候选版本失败,就执行回滚,不要抱着"容器还活着"的侥幸。
第 4 步:回滚并重验
原文:恢复镜像、配置、数据库、索引和模型路由,再运行关键冒烟。
白话:回滚不是只换镜像,要恢复一整组东西:镜像换回旧版、配置切回旧值、数据库数据/索引恢复到一致状态、模型路由指回旧版模型。做完这些,再跑一遍关键冒烟,确认业务能力真的回来了。
类比:像系统恢复到上一个还原点——不是只换一个软件,而是把系统状态整体回退到某个一致的快照,然后再验证一切正常。
举例:新版本有缺陷,你执行回滚:把镜像回退到上一个稳定版 tag,配置改回旧环境变量,数据库里新版本写入的脏数据/索引回退或清理,模型路由指回旧版模型服务,然后重跑"工具调用 + 业务结果"这两个关键冒烟,确认业务恢复。
为什么重要:回滚的目标是恢复一致业务能力。回滚的目的不是"把旧版本装回去"这个动作,而是"让业务能力恢复到一致可用"这个结果,两者不是一回事。
怎么验证(证据点):
- 版本一致:镜像、配置、模型路由都回到一致的旧版本;
- 关键任务通过:关键冒烟任务重新通过;
- 残留副作用已处理:新版本留下的脏数据、错误状态等副作用已清理。
别踩的坑(边界):换回旧镜像不等于回滚闭环。只把镜像换回旧版,但配置没切、数据库没回、模型路由没改,业务照样是坏的,这不叫回滚完成。
落地检查:技术状态和业务影响分别验收。回滚后要分两头验收:技术上是否回到一致状态、业务上是否真的恢复可用,两头都要确认。
落地可行性小结
这个场景涉及的技术栈和真实落地要点:
- 启动与就绪:数据库、消息队列、向量库、模型推理 Runtime、API 网关按依赖编排启动(可用 docker-compose / Kubernetes 的启动顺序、健康探针、就绪探针),进程健康(存活探针)和服务就绪(就绪探针)是两种不同检查。
- 六类冒烟:把"启动、模型、知识、工具、Loop、业务结果"写成独立的冒烟测试脚本,每类产出独立证据,而不是只留一个总开关。
- 上线 Gate:在 CI/CD 流水线里加质量闸门,冒烟红线失败即停止放行,不让已知高风险缺陷流到生产。
- 回滚:回滚要覆盖镜像、配置、数据库/索引、模型路由,常见坑是"只回镜像、不回配置和数据库"导致业务仍坏。
- 常见坑:用 HTTP 200 当健康标准;把六类混成一个总结果;回滚只换镜像就宣布完成。
- 落地动作:健康检查分存活/就绪两层;冒烟分六类留独立证据;失败即停;回滚后分"技术状态"和"业务影响"两头验收。
回顾
- 健康检查不能止于 HTTP 200,进程存活不等于服务就绪,更不等于业务可用。
- 冒烟要分六类(启动、模型、知识、工具、Loop、业务结果)独立验证,才能定位故障。
- 候选版本触发红线就要停止放行,容器还活着不代表版本能用。
- 回滚要覆盖镜像、配置、数据库、索引、模型路由,并在回滚后重新证明业务能力。