5.2 故障推演模板与架构演进展望 容量规划解决了"平时怎么配",但生产系统总会遇到故障——GPU 节点掉线、缓存命中率突降、某个网关实例 OOM。这些故障如果在发生时才想对策,多半已经造成了损失。这一节给一套故障推演模板,让你在故障发生前就演练好应对;同时展望推理成本持续下探、多模态与 Agent 化时代的架构演进方向,帮你提前布局。 我强烈建议每个团队都做定期的故障演练(混沌工程)。我自己在每个负责过的项目里都推行过——主动注入故障(杀掉一个节点、模拟网络分区、注入延迟),验证检测和止血是否真的生效。几乎每次演练都能发现预案的漏洞——比如某个熔断器阈值设得太松、某个告警通知到了已经离职的人。纸上的预案不演练过,真故障时往往用不上,这是无数次事故换来的教训。
容量规划解决了"平时怎么配",但生产系统总会遇到故障——GPU 节点掉线、缓存命中率突降、某个网关实例 OOM。这些故障如果在发生时才想对策,多半已经造成了损失。这一节给一套故障推演模板,让你在故障发生前就演练好应对;同时展望推理成本持续下探、多模态与 Agent 化时代的架构演进方向,帮你提前布局。
我强烈建议每个团队都做定期的故障演练(混沌工程)。我自己在每个负责过的项目里都推行过——主动注入故障(杀掉一个节点、模拟网络分区、注入延迟),验证检测和止血是否真的生效。几乎每次演练都能发现预案的漏洞——比如某个熔断器阈值设得太松、某个告警通知到了已经离职的人。纸上的预案不演练过,真故障时往往用不上,这是无数次事故换来的教训。
对每类常见故障,预先回答四个问题:检测信号是什么(怎么知道故障发生了)、止血动作是什么(第一时间做什么止损)、根因和预防是什么(事后怎么彻底解决)。我把高并发对话平台最常见的几类故障整理成模板。
推理集群 OOM:检测信号是 KV 占用率持续攀升、请求失败率上升、特定节点 5xx 增多;止血动作是降低该节点的 max-num-seqs、限流减少流入、必要时切小模型分流;根因通常是容量不足或调度不当,预防是更精细的显存预算和监控告警。
我展开讲讲这里的排查细节。OOM 不是瞬间发生的,通常有一个爬坡过程——KV 占用率从 80% 慢慢爬到 95%,再过几分钟就 OOM。关键是要在爬坡阶段就发现。我们用 vLLM 时,会在 Prometheus 里抓 vllm:gpu_cache_usage_perc 这个指标,配两条告警:超过 85% 持续 2 分钟是 P2(值班关注),超过 92% 持续 1 分钟是 P1(自动触发止血)。止血脚本会调 vLLM 的 admin API 把那个节点的 --max-num-seqs 从 256 降到 128,给显存喘息空间。如果还不行,就临时把该节点从路由权重里摘掉(weight 设为 0),让新请求走别的节点。真正查根因时,最常见的是长上下文请求集中涌入——某个用户一次塞了 30k token 的上下文,几个这样的请求就把一个节点吃满。所以预防上我们会对单请求上下文长度做配额(超过 16k 的请求单独走"长上下文专用池"),避免长请求把通用节点打爆。
网关连接打满:检测信号是并发连接数接近上限、新连接建立失败率上升;止血动作是水平扩容网关、限流减少流入;根因可能是容量不足或连接泄漏(某个服务的连接没释放)。
连接打满有个很隐蔽的变体:连接数没到上限,但 TIME_WAIT 堆积。客户端短连接大量建立又释放,Linux 内核里 TIME_WAIT 状态的连接几万个几万个地堆,最后端口耗尽,新连接建不起来。排查时 ss -s 看连接状态分布,如果 TIME_WAIT 占了绝大多数,就是这个问题。止血是临时调内核参数 net.ipv4.tcp_tw_reuse=1、扩大端口范围 net.ipv4.ip_local_port_range = 10000 65535,根治是让客户端用长连接(连接池)。连接泄漏则反过来查——用 lsof -p <pid> | wc -l 看进程的 fd 数,如果单调增长不回落,就是泄漏,再配合 pprof 抓 goroutine/thread 看哪里没 close。
缓存命中率突降:检测信号是缓存命中率指标突然下降、推理负载异常上升;止血动作是排查最近的失效条件(是否换了模型或 prompt)、临时扩推理容量承接;根因通常是模型或 prompt 变更导致缓存大面积失效,预防是变更时要有缓存预热机制。
这里有个我亲身经历的坑:有一次发版,开发同学把 system prompt 里"你是 AI 助手"改成了"你是一个 AI 助手",就多了一个"个"字,语义缓存(基于 prompt embedding 相似度)的命中率从 28% 掉到 3%——因为缓存 key 算的是整个 prompt 的 hash,改一个字所有 key 都失效。所以预防上,prompt 变更要走灰度(先发 5% 流量,观察命中率指标),并且发布工具里要有"变更 diff 提示",让发布者意识到这次改动会影响缓存。另外缓存预热的具体做法是:发版前用一批线上高频请求的样本,跑一遍新 prompt 把缓存填满,再切流量。
恢复风暴:检测信号是系统扩容后延迟仍然高、错误率震荡不降;止血动作是开启退避抖动、逐步放量;根因是客户端重试未受控。这个故障最隐蔽,因为它的表象是"容量够了但不稳",容易误判为容量问题。
我加一个判断技巧:如果扩容后 GPU 利用率曲线呈现明显的周期性尖峰(每隔固定时间,比如 8 秒、16 秒,来一波高峰),基本可以确认是恢复风暴——因为客户端的指数退避是 1s, 2s, 4s, 8s 这种节奏,重试洪流也会按这个节奏涌来。这时去扩容是没用的,要立刻在网关层开退避抖动(给 429 响应加 Retry-After: <带抖动的退避时间>),同时把接纳速率限制到当前容量的 70% 逐步放量。
Agent 资源池耗尽:检测信号是 Agent 池并发触顶、Agent 请求排队;止血动作是 Agent 限流、降级;根因可能是 Agent 洪流或死循环,预防是单任务上限和死循环检测。
Agent 池耗尽有个典型场景:一个用户写了个脚本批量触发 Agent 任务,把 Agent 池占满,其他用户的 Agent 全排队。所以 Agent 池要按"每用户并发上限"做隔离——比如单用户最多 3 个并发 Agent 任务,超出的直接拒绝或排队,这样一个人再怎么刷也只占 3 个槽。死循环检测我推荐用"工具调用序列指纹"——把 Agent 的工具调用历史算个 hash,如果最近 5 步的 hash 重复了(说明在原地打转),直接中断。
这份模板要结合监控(见本系列监控教程)来用——所有检测信号都必须有对应的监控指标和告警,否则故障发生了你都不知道。
所有故障推演都依赖先有监控。没有监控的故障推演是空中楼阁——你甚至不知道故障发生了,谈何应对。本系列《Prometheus+Grafana 大模型推理体系》详细讲了怎么搭监控,这里只强调几个和故障推演直接相关的点:黄金信号(TTFT、错误率、吞吐)要实时可观测;错误预算告警让你在 SLO 被打破前就收到预警;三层下钻看板(概览→服务→实例)让你在故障时快速定位是哪一层、哪个节点出了问题。
我补充几个实战中好用的具体做法。第一,黄金信号要配"多分位"而不仅是均值——TTFT 的 p50 可能是 300ms 看着很健康,但 p99 已经飙到 5 秒了,10% 的用户在受罪。所以告警要基于 p95/p99 而不是均值。第二,错误预算告警的阈值我们设成"30 分钟内烧掉 20% 的月度错误预算就告警",这样能在月度 SLO 真正被打破前几天就预警。第三,三层下钻看板要支持"一键跳转"——概览看到错误率升高的服务,点一下跳到该服务的实例列表,再点实例跳到该实例的日志,整个定位过程控制在 30 秒内。这套交互我在团队里推行后,平均故障定位时间(MTTI)从十几分钟降到两三分钟。
监控和故障推演是配套的——监控负责"发现问题",故障推演负责"知道怎么应对"。两者结合,才能把故障的平均恢复时间(MTTR)压到最低。
最后向前看一步,讲讲推理架构的几个演进趋势,以及哪些能力今天就该开始布局。
趋势一是推理成本持续下探。模型量化(INT4/INT8)、推测解码、KV Cache 复用、专用推理芯片,让单 token 成本持续下降。架构要为"成本不断优化"预留弹性——能快速接入新的优化手段,而不是绑死某一种。比如推理框架要能平滑切换(从 vLLM 换到 TensorRT-LLM),缓存层要能适配不同的 embedding 模型。
这里我展开几个具体的技术判断。量化方面,INT4/INT8 量化对推理成本的降低非常显著(INT4 相比 FP16 通常省 3-4 倍显存、提 2-3 倍吞吐),但要看量化方式——AWQ/GPTQ 这类训练后量化对质量损失可控,而激进的 RTN 量化会让复杂推理任务质量明显下降。我们的做法是:每个新模型上线前都跑一轮质量评测(用业务自己的评测集,覆盖简单问答、复杂推理、代码生成),只有量化后质量下降不超过 2% 才允许上。推测解码(Speculative Decoding)用一个小模型先猜几个 token,大模型批量验证,命中就省时间——它对"输出可预测"的任务(代码、列表)加速明显(1.5-2 倍),但对创意写作效果一般。专用推理芯片(如各类 LLM 推理卡)要关注生态成熟度,我会等它的软件栈(对标 CUDA/Triton)稳定一年以上才大规模引入,否则踩坑成本太高。
趋势二是多模态与长上下文。从纯文本走向多模态(图、音、视频),从几千 token 走向百万 token。这会影响上下文管理(多模态的上下文比文本大得多)、缓存策略(多模态的 embedding 更复杂)、带宽规划(图像视频带宽消耗远超文本)。
多模态这里有一个容量规划的新挑战:一张 1080p 图片编码后大约是 1-2k token,一段 30 秒视频可能上万 token,单请求的 prefill 负载是纯文本的几十倍。所以多模态平台必须做"模态路由"——图片请求走带视觉编码器的专用池,纯文本走普通池,避免视觉请求把通用池打爆。带宽上,多模态请求的入站流量也大得多,接入层的 LB 和网关要重新估算带宽预算(图片上传是 KB 级,视频是 MB 级,和纯文本的几百字节差几个数量级)。
趋势三是 Agent 化与自治。从单轮对话走向多步 Agent,再走向自治工作流。资源池隔离、链路追踪、长任务编排成为架构新重点。Agent 时代的监控也要升级——单次推理的监控不够了,要把 Agent 的多步调用串成一条 trace(见安全与监控教程)。
Agent 化对架构最大的新要求是"长任务的状态持久化与可恢复"。一个跑 5 分钟的 Agent 任务,中间任何一步崩了(节点重启、网络抖动),不能让用户从头再来。所以 Agent 引擎要内建 checkpoint 机制——每完成一个工具调用就把中间状态(已调用的工具、已收集的结果、当前的规划)写到一个持久化存储(Redis 或对象存储),崩溃后从最近的 checkpoint 恢复。这个能力今天就该布局,因为 retrofit 到已有系统成本很高。
趋势四是边缘推理。部分推理下沉到边缘节点甚至设备,中心做编排与协同。这带来监控(海量边缘节点如何集中监控)、同步(弱网络下数据一致性)、异构适配(边缘设备算力差异大)的新挑战。
边缘推理我目前看到落地比较多的是"端侧小模型 + 云端大模型"的协同——简单请求端侧处理(延迟低、省带宽、隐私好),复杂请求才上云。架构上要支持"端云路由",编排层能感知请求来源(端/云)和设备能力,做差异化路由。监控上海量边缘节点不能每个都拉指标,要用"采样 + 异常上报"——正常状态不上报(省带宽),只有检测到异常才上报,中心做聚合分析。
无论架构怎么演进,回到本书建立的统一判断标准,面对任何新的推理框架或中间件提案,问三个问题:它改善了哪个口径(量、快、稳、省)?它强化了哪一层(接入、编排、推理、状态)?它守住了哪道关口(连接、计算、状态)?
能清晰回答这三个问题的方案,才值得引入;说不清的,多半是花架子。这就是本书坚持"先把分层和口径讲透"的最终价值——给你一个长期有效、不绑定单一厂商的架构判断力。具体的框架和工具会迭代,但"分层清晰、口径准确、关口守住"这套内功,十年后依然管用。
我再用一个具体例子说明这个框架怎么用。假设有人向你推销一个"AI 推理加速中间件",号称能让推理快 3 倍。套用三问:它改善了哪个口径?答"快"(降低延迟)。它强化了哪一层?如果答得出(比如"推理层,用了推测解码"),那它定位清晰;如果支支吾吾说不上来,那多半是个黑盒包装。它守住了哪道关口?如果它为了加速而绕过了限流(计算关口),那就是隐患——加速到 3 倍意味着下游压力也涨 3 倍,没有限流兜底会把推理集群打爆。三问一过,这个"加速中间件"的真实价值就清楚了。
从 1.1 的口径校准,到 5.2 的演进展望,我们把一座高并发大模型服务从地基盖到了封顶,并给了一套可复用的方法论。
记住全书的一句话:绝大多数生产事故,根子都出在口径混乱和分层错位,而不是技术选型不够新。 把分层理清、把口径校准、把关口守住——这就是高并发大模型服务的工程内功。
本系列其他教程与本卷的关系:《vLLM 高并发部署》提供推理层深水区的实现细节,《请求缓存与智能路由》细化状态层,《Prometheus+Grafana 监控》保障可观测,《输入输出过滤》守护安全边界。它们共同构成一套完整的大模型工程体系,本书是这个体系的"架构总论"。