【从零开始学架构】服务治理思想:从失败场景倒推系统设计

很多人理解服务治理,第一反应是工具:注册中心、配置中心、网关、限流、熔断、监控、链路追踪。

这些当然重要,但如果只从工具理解服务治理,很容易把它做成一堆技术组件的堆叠------装了一柜子工具,系统该崩还是崩。

服务治理真正要解决的问题不是"系统用了哪些治理工具",而是:系统上线以后,面对失败、压力和变化时,能不能继续保持可控。

这里有一个常被忽略的前提:好的架构设计,不是从正常路径出发,而是从失败场景倒推。 一个系统在开发环境里跑通,不代表它在生产环境里可靠。真实的生产里,下游会变慢,流量会突增,数据库会抖动,消息会堆积,缓存会击穿,版本会发布失败,数据会出现异常,第三方服务也会不可用。如果一份架构方案只写了"请求正常时怎么走",却没写"异常发生时系统怎么活下来",那它还只是功能设计,不是成熟的架构设计。

所以"从失败倒推",就是本文唯一的题眼。围绕它,服务治理要回答五个问题:

  1. 系统能不能发现问题?
  2. 故障能不能被限制住?
  3. 核心业务能不能保住
  4. 失败以后能不能恢复
  5. 问题能不能被定位和复盘

为了不让这五个问题停留在抽象层面,下面我用同一个真实场景贯穿全文:

一个 ChatBI 系统。 用户用自然语言提问,系统做意图识别、实体链指、生成 SQL、查询数据,再把结果解释给用户。某天上午,大模型推理服务开始变慢------这是故事的起点。我们就跟着这一次故障,一层一层往下走。

第一层:发现问题------系统能不能知道自己不健康

那天上午,大模型服务变慢,但监控大盘一片绿色。直到一个小时后,业务同事在群里问"为什么查询都转圈圈",团队才意识到出事了。

这就是第一层要解决的问题:系统不能靠用户投诉才发现故障。 等用户来反馈,通常说明问题已经发生了一段时间,甚至已经造成了业务损失。

要做到提前发现,架构师首先要定义:什么叫"系统正常"。 健康指标因系统而异------交易系统看下单/支付成功率,消息系统看消费延迟和堆积量。对我们这个 ChatBI 来说,健康意味着:意图识别成功率、SQL 生成失败率、查询超时率、空结果率、用户追问率。

关键在于:这些指标必须能反映用户是否真的受到影响。这就是 SLI 的意义------SLI 不是一堆技术指标,而是系统健康状态的可观测表达。回到那次故障,如果大盘里有"查询超时率"这条曲线,它在故障发生的第一分钟就会拉起来,根本等不到业务来问。

有了指标还要有告警,但告警不是越多越好:太少,故障发现晚;太多,团队会麻木到直接忽略。真正有效的告警绑定的是用户影响------查询超时率持续超阈值,说明体验已经变差,这才值得把人从会议里叫出来。

这一层最该问清楚的是:

  • 哪些指标代表用户是否真的受影响?
  • 哪些告警是噪声,应该被收敛掉?

如果系统不能及时发现自己不健康,后面四层都无从谈起。

第二层:控制影响------别让一个慢点拖垮整条链路

发现大模型变慢之后,团队的第一反应是"赶紧把模型服务修好"。但这是错的------第一步不是修好,而是先止血。

因为线上事故往往不是"一个点坏了就结束",而是"一个点坏了以后,继续把整条链路拖垮"。在我们的 ChatBI 里,故障是这样扩散的:大模型响应慢 → 业务服务调用它时没有超时,请求一直挂着等 → 线程被占满 → 连接池耗尽 → 连"看历史看板"这种根本不用大模型的请求也进不来 → 整个系统不可用。

本来只是一个依赖慢,最后变成全站雪崩。这就是故障扩散 。第二层要做的,就是限制故障半径

  • 超时:调用大模型、查询数据库、请求第三方,都不能无限等待。没有超时,等于把自己的稳定性交给了下游。这次事故的根因,恰恰就是缺了一个超时。
  • 熔断:当大模型连续超时,与其让每个请求都去等死,不如暂时停止调用、直接走降级------熔断不是放弃,而是不让自己和对方一起被拖垮。
  • 隔离:"问答查询"和"看历史看板"不该共用同一个资源池。否则一个高成本的大模型调用,就能耗尽整个系统的线程,连不相干的功能一起拖死。

控制影响还必须盯住一个地方:请求堆积。请求会堆在 HTTP 入口、线程池、连接池、大模型调用队列里。队列只要没有上限,系统就会"表面还在接请求,内部早已处理不过来",最后整体雪崩。

这一层最该问清楚的是:

  • 请求会堆在哪里?那个地方有没有上限?
  • 超过上限以后是拒绝、降级还是转异步,有没有想清楚?

这一层解决的是:系统出问题以后,能不能避免小故障变成大事故。

第三层:保护核心------资源不够时,先保住谁

止住了扩散,新的问题来了:大模型还是慢,资源还是紧张,那这有限的资源该优先给谁?

答案是:不是所有功能都同等重要。 在我们的 ChatBI 里------

  • 用户追问的"智能推荐相关问题"失败了,返回几个默认问题就行。
  • 自然语言问答的大模型调用失败了,可以降级到固定筛选器、模板查询,或者直接让用户看已有看板。
  • 但"用户的数据权限校验"不能降级成"假装通过"------那是安全底线。

所以服务治理必须提前区分核心链路增强能力:核心链路优先保障,增强能力允许降级。否则系统在高压下会把宝贵资源消耗在不那么重要的地方,真正关键的业务反而被拖垮。

降级不是临时拍脑袋,而是提前设计好的替代路径:哪些功能返回默认值,哪些用缓存结果,哪些必须失败即阻断,都要在架构阶段就说清楚。

保护核心还需要限流 。限流不是为了拒绝用户,而是为了让系统在资源有限时仍然可控。还是用 ChatBI 举例:如果不限流,一个用户连续提交复杂问题,就能同时吃掉大模型 token、查询引擎资源和数据库连接,把别的租户全饿死。这时候限流不是体验问题,而是公平性和稳定性问题------既要按租户/用户限 QPS,也要专门限制大查询、高成本分析这类"业务级"重负载。

这一层最该问清楚的是:

  • 哪些是核心链路必须保住,哪些只是增强体验可以降级?
  • 单个用户或租户,能不能把整个系统拖垮?

这一层解决的是:系统在压力下能不能做取舍,而不是一起崩。

第四层:恢复现场------失败之后,能不能回到可信状态

熬过了高峰,团队决定回滚刚上线的一个版本------结果发现回滚不了:这次发布顺带改了数据库字段,新代码写进去的数据,旧代码读不出来。

这就是第四层的价值:成熟的服务治理,不假设系统不会失败,而是假设失败一定会发生,并提前设计恢复能力。

恢复首先是回滚 。很多系统只设计了"发布成功"的路径,没设计"发布失败"的路径。但真实上线里失败很常见:代码有 bug、配置写错、数据库变更不兼容、灰度期间新老版本同时读写数据。所以架构设计必须提前问:代码能不能回滚?配置能不能回滚?数据库变更是否向前兼容、新老版本能否同时运行? 尤其是数据变更,不能只想"怎么改过去",还要想"改坏了怎么回来"------是否双写、是否影子表、是否按租户灰度,都属于恢复能力的一部分。我们这次的教训,就是漏掉了"向前兼容"这一步。

恢复还包括数据修正------这比服务挂掉更危险。有些故障是"服务可用,但结果不可信":ChatBI 返回了错误的指标口径,用户看到的是一个正常的图表,但数字本身是错的,业务据此做了决策。比起白屏,这种"看起来正常实则错误"才是真正的隐患。所以系统要有数据校验、对账、异常值检测、审计记录和人工修正入口;否则数据一旦错了,就只能靠临时 SQL 和人工猜测救火。

这一层最该问清楚的是:

  • 发布失败、数据库改坏了,能不能快速退回上一个稳定状态?
  • 数据错了能不能发现、能不能追溯是谁在何时写入、能不能修正并验证?

这一层解决的是:系统失败以后,能不能重新回到可信状态。

第五层:定位与复盘------让一次事故变成系统能力

事故平息后复盘,团队想还原"那一个小时到底发生了什么",却发现查不清------网关、业务服务、大模型、查询引擎、数据库,每个地方都有日志,但没有一条贯穿的 trace-id,只能靠时间戳和经验拼凑。

这就是最后一层要解决的:让问题能被定位,并推动系统变得更稳。

很多团队有监控、有日志、有告警,出了问题却仍查不清,原因就是这些信息没被串成链路。所以服务治理必须要求关键链路可追踪:日志里要有请求标识、用户/租户信息、关键参数摘要、错误码、耗时、下游依赖和返回状态(敏感信息脱敏)。有了贯穿的 trace-id,才能回答"这次查询慢,到底慢在意图识别、SQL 生成、查询引擎,还是大模型那一步"。如果只能看到"请求失败",看不到失败发生在哪一段,系统就根本不可治理。

最后还要有复盘机制。复盘不是为了追责,而是为了把一次事故沉淀成能力。它要回答:为什么没提前发现(第一层)?为什么故障会扩散(第二层)?为什么降级没生效(第三层)?为什么回滚那么慢(第四层)?下一次靠什么机制避免?------你会发现,一次像样的复盘,正好把前四层重新检验了一遍。

这一层最该问清楚的是:

  • 一个请求的完整链路,能不能串起来、能不能分段定位到是哪一步出的问题?
  • 事故之后,有没有落地的长期修复动作,而不只是一句"以后注意"?

这一层解决的是:系统能不能从失败中学习,而不是反复摔在同一个地方。

回到题眼:服务治理是一套"从失败倒推"的系统能力

走完这五层,再回头看那次 ChatBI 故障,就会发现它其实是一根线上的五个点:

层次 能力 在那次故障里意味着
第一层 发现问题 能不能在第一分钟就知道大模型变慢了
第二层 控制影响 能不能不让"模型慢"拖垮整个系统
第三层 保护核心 资源紧张时,能不能保住权限校验和看板
第四层 恢复现场 发布改坏了,能不能干净地退回去
第五层 定位复盘 能不能查清根因,并让下一次不再重演

所以,服务治理从来不是"加监控、加限流、加熔断"这么一份工具清单。这些只是手段。它真正的内核,是那个贯穿始终的题眼------从失败场景倒推设计,并据此建立一套系统能力。

它的价值,从不在系统顺利时体现,而在系统不顺利时体现:当下游变慢时能保护自己,当流量突增时能限制压力,当部分能力失败时能保住核心,当发布出错时能快速恢复,当事故发生后能定位根因、推动系统变得更稳。

这才是服务治理真正要训练的能力:不是追求系统永远不失败,而是让系统在失败发生时,仍然可控、可恢复、可演进。