应用和云服务排障:可观测能力应该提前设计
不少团队都有这样的经历:Demo 跑得飞起,一上线就各种翻车。技术方案从原型进入生产环境后,真正拉开差距的往往不是某个单点能力,而是稳定性、成本、可观测和治理边界。这几个方面,任何一个没兜住,都可能让前面的努力付诸东流。本文围绕近期开发者关注度较高的技术问题,整理了一套可以直接落到工程实践里的分析框架,核心就一件事:如何把零散的能力,做成一个可持续运行的系统。

一、可观测不是出了故障才需要
把可观测留到线上出问题再补,就像房子着火了才去买灭火器,不仅被动,成本也高。对于 AI 应用这类复杂度高的系统,可观测应该在设计阶段就进入架构。原因很简单:链路比传统单体应用长得多,依赖也多得多。
一次看似普通的用户请求,可能经历前端、后端、检索、缓存、模型、函数计算、数据库和消息队列。任何一个环节变慢或失败,最终都表现为“用户觉得不好用”。如果没有链路级日志和指标,很难判断问题到底发生在哪里。
具体到工程化落地,需要把几个关键能力拆成独立模块来处理:
- AI 应用工程化:把模型路由、上下文裁剪、工具调用、失败降级和效果评测拆成独立模块。
- 安全治理:把鉴权、参数校验、最小权限、审计和敏感数据脱敏放进同一条调用链。
- 性能与成本优化:同时观察 P95 延迟、token 消耗、缓存命中率和重试放大倍数。
- 部署落地:明确运行环境、网络边界、健康检查、扩缩容阈值和回滚路径。
技术实现参考:建立统一的日志事件和 SLO
可观测的第一步,是统一日志字段。下面的示例把请求 ID、模型、token、重试和降级信息放进同一个结构化事件,这样排查问题时,所有关键信息都在一个地方,一目了然:
def build_trace_event(ctx, result): return {
"request_id": ctx.request_id,
"scene": ctx.scene,
"model": result.model,
"status": result.status,
"latency_ms": result.latency_ms,
"input_tokens": result.usage.input_tokens,
"output_tokens": result.usage.output_tokens,
"retry_count": result.retry_count,
"fallback_used": result.fallback_used,
"cache_hit": result.cache_hit, }
指标层,建议至少定义三条 SLO:成功率不低于 99.5%,P95 端到端延迟低于业务阈值,降级比例低于 1%。告警必须使用时间窗口,避免单次尖峰触发噪声。例如连续 5 分钟成功率低于目标,或 P95 延迟连续 10 分钟恶化 30%,再触发人工介入。
a vailability = successful_requests / total_requests
retry_amplification = upstream_calls / business_requests
fallback_ratio = fallback_requests / successful_requests
很多团队第一次重视可观测,往往是在故障发生之后。这个教训,代价通常不低。
二、AI 应用尤其需要细粒度日志
AI 应用的排障难点在于结果具有不确定性。同样的代码,可能因为模型版本、上下文、检索结果或工具返回不同而表现不同。所以日志不能只记录接口状态,还要记录影响结果的关键变量。
| 日志字段 | 为什么重要 |
|---|---|
| 请求 ID | 串联完整链路 |
| 用户场景 | 区分客服、摘要、代码、分析等任务 |
| 模型名称 | 判断效果和成本差异 |
| 输入输出 token | 评估成本和上下文长度 |
| 检索命中 | 判断 RAG 质量 |
| 工具调用 | 定位外部依赖失败 |
| 重试次数 | 发现隐藏的不稳定 |
| 降级路径 | 判断用户体验是否可控 |
这些字段不一定一开始全部上齐,但请求 ID、模型、耗时、状态码和场景最好从第一天就记录。这是最基础的“排障底牌”。
三、指标要服务决策
指标不是越多越好。真正有用的指标应该能帮助你做决策。比如:
- 失败率上升,是不是某个模型或区域的问题。
- 平均耗时上涨,是不是检索结果过多或上下文变长。
- token 消耗上涨,是不是某个场景的 Prompt 失控。
- 重试次数增加,是不是上游服务开始不稳定。
- 缓存命中率下降,是不是业务输入发生变化。
如果一个指标不会触发任何行动,它就只是装饰。指标体系应该围绕排障、成本、体验和容量规划来设计,每一个指标都要有明确的目的,而不是为了“看起来全面”。
四、追踪链路要覆盖外部依赖
AI 和云服务项目里,外部依赖经常是故障来源。模型接口、数据库、搜索服务、对象存储、函数计算、第三方 API 都可能出现波动。只看应用自身日志是不够的,很容易陷入“自己没问题,但用户就是体验差”的困境。
更好的方式是给每次请求生成统一请求 ID,并把它带到每个下游调用里。即使下游无法完整支持分布式追踪,也至少要在本地日志中记录请求 ID、下游服务名、耗时、状态码和错误摘要。这样排查问题时,可以从用户请求一路追到具体依赖,有效缩小排查范围。
五、降级也要被观测
很多系统做了降级,但没有观察降级发生的频率。结果是用户已经长期拿到低质量回复,团队却以为系统运行正常,这才是最危险的情况。
降级策略应该至少记录三件事:为什么降级、降级到了哪里、用户是否最终成功完成任务。比如模型超时后切到备用模型,应该记录原模型、备用模型、切换原因和最终耗时。这样团队才能判断降级是偶发保护,还是已经变成常态,需要从架构层面进行优化。
六、结论
可观测性的目的,并不是为了让仪表盘更好看,也不是为了在老板巡检时显得很专业。它的核心价值在于:当系统出问题时,能快速回答三个问题——哪里坏了,影响多大,下一步该怎么处理。开发者面对的系统正在变得更长、更动态、更依赖外部服务。越是这种系统,越不能把日志、指标和追踪留到最后。把可观测提前设计进去,才是高质量工程化的起点,也是让系统从“能跑”走向“好管”的关键一步。