中间件站点可靠性工程研究
概览
围绕中间件与微服务体系,系统梳理 SLI、SLO、SLA 的定义方法,以及可观测性与服务治理如何形成可靠性闭环。
摘要
站点可靠性工程,即 SRE,是一种以工程化手段管理系统可靠性的实践方法。它的核心不是“多加监控、多加人值班”,而是通过 SLI、SLO、SLA 把可靠性从主观感受转化为可度量、可协商、可治理、可复盘的工程对象。Google SRE 体系中,SLI 是对服务水平的定量度量,SLO 是基于 SLI 设定的目标值,SLA 则通常是面向服务使用方的正式承诺,并可能包含违约后果。Google SRE 文档明确指出,SLI 是服务水平某一方面的“精确定义的定量指标”,SLO 是由 SLI 衡量的目标值或目标范围;Google Cloud 也强调,SLA 通常是对服务用户的承诺,未达成时可能触发赔偿、延期服务等惩罚。(Google SRE)
本文认为,中间件 SRE 的难点不在于照搬应用服务的可用性指标,而在于中间件往往是共享依赖、控制平面和数据平面的组合体。因此,中间件的可靠性指标必须同时覆盖:数据面请求成功率、控制面配置传播时延、规则一致性、存储持久性、客户端感知可用性、故障隔离能力和恢复能力。对于微服务而言,SLI/SLO/SLA 则应围绕用户旅程、接口契约、调用链路和业务正确性设计。可观测体系不是服务治理的附属系统,而是服务治理的事实来源;服务治理也不是可观测体系的下游执行器,而是反过来为可观测体系提供拓扑、标签、变更事件和治理上下文。二者应该构成“观测—判断—治理—验证—复盘”的闭环。
关键词:SRE;SLI;SLO;SLA;中间件;微服务;服务治理;可观测性;错误预算;站点可靠性工程
一、引言
在传统运维体系中,系统可靠性往往被描述为“稳定”“没问题”“最近故障少”“机器负载不高”等经验性表达。这种表达最大的问题是:它无法指导工程决策。当研发团队希望快速发布功能,运维团队希望降低风险,业务团队希望减少故障时,如果没有一组共同认可的可靠性语言,团队之间只能依靠争论、拍脑袋和事后追责。
SRE 试图解决这个问题。Google SRE 体系提出的“四个黄金信号”——延迟、流量、错误、饱和度,是监控用户面系统时最重要的基础维度。Google SRE 文档明确建议,如果只能监控四类指标,应优先关注 latency、traffic、errors、saturation。(Google SRE) 但对于现代企业架构,尤其是中间件和微服务体系,仅有这四类指标还不够。原因在于:
第一,中间件不是单一业务接口,而是多个业务系统共同依赖的基础设施。注册中心、配置中心、限流系统、网关、消息队列、缓存、数据库代理、链路追踪平台等,一旦发生故障,影响面往往呈现放大效应。
第二,微服务不是孤立服务,而是由服务调用、异步消息、缓存访问、数据库访问、配置变更、限流熔断规则共同组成的动态系统。一个服务自身进程存活,并不代表用户体验正常。
第三,可观测体系如果只负责“看见问题”,但不能驱动限流、熔断、降级、路由、扩缩容、灰度回滚等治理动作,就会退化为事故后的取证系统,而不是事故前和事故中的控制系统。
因此,本文主张:中间件站点可靠性工程的核心,是以 SLI/SLO/SLA 为可靠性契约,以可观测体系为事实基础,以服务治理为执行手段,构建持续闭环的可靠性工程体系。
二、SLI、SLO、SLA 的概念及其设计原因
2.1 SLI:服务水平指标
SLI,全称 Service Level Indicator,即服务水平指标。它回答的问题是:系统当前表现到底如何?
SLI 必须是定量指标,不能是模糊描述。比如:
| 可靠性维度 | 错误表达 | 正确 SLI 表达 |
|---|---|---|
| 可用性 | 服务挺稳定 | 最近 30 天成功请求数 / 总有效请求数 |
| 延迟 | 接口有点慢 | p95 延迟、p99 延迟 |
| 正确性 | 数据大体没问题 | 正确结果数 / 总请求数 |
| 新鲜度 | 配置同步很快 | 配置发布到客户端生效的 p99 时延 |
| 持久性 | 消息不丢 | 成功持久化消息数 / 已确认消息数 |
一个合格的 SLI 需要满足四个条件:
- 可度量:必须能通过指标、日志、链路、探测任务或业务校验计算出来。
- 用户相关:不能只看机器指标,而要反映调用方、业务方、用户侧的体验。
- 边界清晰:必须说明统计窗口、分母、分子、过滤条件。
- 可归因:指标异常时,要能进一步定位到服务、接口、调用方、机房、版本、依赖或治理规则。
我的判断是:很多团队的监控失败,不是因为指标少,而是因为 SLI 定义错了。 例如只监控 CPU、内存、进程存活、端口存活,却不监控用户请求成功率、配置生效时延、消息堆积时延、规则命中正确率,这种监控对可靠性治理价值很低。
2.2 SLO:服务水平目标
SLO,全称 Service Level Objective,即服务水平目标。它回答的问题是:系统应该达到什么可靠性水平?
SLO 通常由三部分组成:
SLO = SLI + 目标阈值 + 统计窗口例如:
订单创建接口在最近 30 天内,99.9% 的有效请求应在 300ms 内成功返回。这里:
| 组成部分 | 示例 |
|---|---|
| SLI | 有效订单创建请求的成功率和延迟 |
| 目标阈值 | 成功率 ≥ 99.9%,p95 延迟 ≤ 300ms |
| 统计窗口 | 最近 30 天 |
SLO 的重要价值在于它引入了 错误预算。如果 SLO 是 99.9%,那么允许的不可用比例就是 0.1%。这 0.1% 就是错误预算。Google SRE Workbook 指出,有了 SLO 后可以推导错误预算,并且需要制定错误预算策略,用于决定服务预算耗尽时团队应该采取什么行动。(Google SRE)
错误预算的本质是一个工程管理工具:
错误预算 = 1 - SLO例如:
| SLO | 30 天错误预算 |
|---|---|
| 99% | 约 7.2 小时不可用 |
| 99.9% | 约 43.2 分钟不可用 |
| 99.99% | 约 4.32 分钟不可用 |
SLO 的意义不是追求“永不出错”,而是明确系统可以承受多少失败。如果错误预算充足,可以允许更快发布、更大胆实验;如果错误预算快速燃烧,就必须降低变更频率,优先修复可靠性问题。
2.3 SLA:服务水平协议
SLA,全称 Service Level Agreement,即服务水平协议。它回答的问题是:服务提供方对服务使用方承诺什么?如果做不到,后果是什么?
SLA 与 SLO 的区别非常关键:
| 对比项 | SLO | SLA |
|---|---|---|
| 性质 | 内部可靠性目标 | 对外或跨团队正式承诺 |
| 目的 | 指导工程治理 | 明确责任边界和违约后果 |
| 是否有惩罚 | 通常没有直接惩罚 | 通常有赔偿、降级、补偿、考核 |
| 设置原则 | 应该严于 SLA | 不应高于系统真实能力 |
| 面向对象 | 研发、SRE、平台团队 | 客户、业务方、上下游团队 |
一个非常重要的原则是:SLO 应该严于 SLA。
例如,对外承诺 SLA 为 99.9%,内部 SLO 可以设为 99.95%。这样可以给系统留出安全缓冲。如果内部 SLO 和外部 SLA 完全相同,那么一旦 SLO 轻微跌破,SLA 就可能立即违约,这种设计非常危险。
2.4 为什么要设计 SLI、SLO、SLA
设计 SLI/SLO/SLA 的原因不是为了做报表,而是为了建立可靠性治理秩序。
第一,把可靠性从感性判断变成量化判断。 没有 SLI,就无法判断服务到底是好还是坏。服务进程存活不代表服务可靠,请求成功率高也不代表业务正确。可靠性必须被精确定义。
第二,把团队争论变成目标协商。 研发想发版,业务想稳定,平台想降低运维风险。如果没有 SLO,争论没有共同标准;有了 SLO,讨论可以转化为:“当前错误预算是否允许继续发布?”
第三,把告警从噪音变成决策信号。 Google SRE Workbook 强调,基于 SLI 和错误预算生成告警时,目标应该是通知真正重要的事件,即那些正在消耗大量错误预算的事件。(Google SRE) 这比“CPU 超过 80% 就报警”要成熟得多。
第四,把事故复盘变成系统改进。 事故后不只是问“谁的问题”,而是问:哪个 SLI 退化?哪个 SLO 被打穿?错误预算为什么燃烧?治理策略是否及时?可观测数据是否足够?
第五,把平台能力变成服务契约。 中间件平台不能只说“我们提供注册中心、配置中心、限流系统”,而应该说:“我们保证配置发布 p99 在 3 秒内生效,注册发现可用性达到 99.95%,限流规则命中正确率达到 99.99%。”
三、中间件如何定义 SLI、SLO、SLA
中间件的 SLI/SLO/SLA 不能简单照搬普通业务接口。中间件通常具备以下特点:
- 共享依赖:多个业务共同依赖,一次故障影响多个系统。
- 控制平面与数据平面分离:例如配置发布是控制面,请求转发是数据面。
- 强一致与最终一致混合:例如注册中心、配置中心、治理规则分发。
- 客户端 SDK 深度参与:可靠性不只取决于服务端,也取决于客户端缓存、重试、降级。
- 故障影响具有放大性:中间件抖动可能导致业务雪崩。
所以,中间件指标必须按照能力域来设计,而不是只按机器资源设计。
3.1 中间件 SLI 的核心分类
3.1.1 可用性 SLI
适用于注册中心、配置中心、网关、限流服务、消息队列、缓存代理等。
可用性 SLI = 成功请求数 / 有效请求总数但这里的“成功”必须按中间件语义定义:
| 中间件类型 | 成功事件定义 |
|---|---|
| 注册中心 | 服务注册成功、心跳续约成功、服务发现返回有效实例 |
| 配置中心 | 配置读取成功、配置发布成功、客户端监听成功 |
| API 网关 | 请求被正确路由并返回非网关侧错误 |
| 限流系统 | 规则查询成功、限流判断成功、配额扣减成功 |
| MQ | 消息发送确认成功、消息持久化成功、消费确认成功 |
| 缓存代理 | get/set/delete 请求成功,且非客户端非法请求 |
这里必须排除调用方自身错误。例如 HTTP 400、鉴权失败、非法参数,不应该全部算作中间件失败。否则 SLI 会被业务误用污染。
3.1.2 延迟 SLI
中间件延迟不能只看平均值,必须看分位数,尤其是 p95、p99、p999。
| 中间件类型 | 延迟 SLI 示例 |
|---|---|
| 注册中心 | 服务发现 p99 延迟 |
| 配置中心 | 配置发布到客户端生效 p99 时延 |
| 网关 | 网关自身处理 p99 延迟,不含后端业务耗时 |
| MQ | produce ack p99、端到端投递 p99 |
| 缓存代理 | 命令执行 p99 延迟 |
| 限流系统 | 单次限流判断 p99 延迟 |
注意:中间件延迟必须区分自身耗时和下游耗时。 比如网关请求慢,可能是后端服务慢,不一定是网关慢。因此网关 SLI 至少要拆成:
gateway_total_latency
gateway_internal_latency
upstream_service_latency否则治理动作会误判。
3.1.3 正确性 SLI
这是中间件最容易被忽略、但最重要的指标。
| 中间件能力 | 正确性 SLI |
|---|---|
| 注册中心 | 发现结果是否包含健康实例,是否剔除异常实例 |
| 配置中心 | 客户端配置版本是否与服务端期望版本一致 |
| 限流系统 | 规则命中是否正确,配额扣减是否准确 |
| 路由系统 | 灰度流量是否进入正确版本 |
| 熔断系统 | 熔断状态是否符合错误率和窗口规则 |
| MQ | 消息是否重复、乱序、丢失,是否满足承诺语义 |
| 缓存 | 数据是否过期、击穿、污染 |
我认为,中间件 SRE 如果不定义正确性 SLI,只定义可用性和延迟,是不合格的。 因为中间件最可怕的故障往往不是“挂了”,而是“还活着,但返回了错误结果”。
3.1.4 一致性与传播 SLI
控制平面类中间件必须定义传播类指标。
例如配置中心:
配置传播时延 = 客户端观察到目标配置版本的时间 - 服务端发布成功时间注册中心:
实例摘除传播时延 = 客户端不再发现异常实例的时间 - 服务端判定实例异常的时间治理规则中心:
规则生效时延 = 流量实际按新规则执行的时间 - 规则发布成功时间这类指标比“接口可用性”更贴近中间件真实价值。配置中心接口 100% 可用,但配置 5 分钟才生效,对业务来说依然是严重问题。
3.1.5 持久性与恢复 SLI
适用于 MQ、注册配置存储、规则中心、元数据中心。
| 指标 | 含义 |
|---|---|
| RPO | 故障后最多允许丢失多少数据 |
| RTO | 故障后多久恢复服务 |
| 数据丢失率 | 丢失数据量 / 应持久化数据量 |
| 副本同步延迟 | follower 与 leader 的复制滞后 |
| 快照恢复成功率 | 从快照恢复成功次数 / 恢复总次数 |
如果一个中间件承载核心配置、治理规则、消息数据,却没有 RPO/RTO 指标,那么它的可靠性体系是不完整的。
3.1.6 饱和度 SLI
饱和度不是普通资源监控,它要反映系统是否接近处理极限。
| 中间件 | 饱和度指标 |
|---|---|
| 网关 | 连接数、活跃请求数、线程池队列、upstream pending request |
| MQ | topic backlog、consumer lag、broker 磁盘水位 |
| 注册中心 | watch 数量、推送队列积压、心跳处理队列 |
| 配置中心 | 长连接数量、变更推送队列、客户端监听数 |
| 限流系统 | 热点规则 QPS、配额存储冲突、远程判断耗时 |
| 缓存 | 内存水位、淘汰率、热点 key 访问量 |
饱和度指标的价值在于预测故障,而不是等故障发生后再报警。
3.2 中间件 SLO 示例
| 中间件 | SLI | SLO 示例 |
|---|---|---|
| 注册中心 | 服务发现成功率 | 最近 30 天 ≥ 99.95% |
| 注册中心 | 异常实例摘除传播时延 | p99 ≤ 5 秒 |
| 配置中心 | 配置读取成功率 | 最近 30 天 ≥ 99.99% |
| 配置中心 | 配置发布生效时延 | p99 ≤ 3 秒 |
| API 网关 | 网关自身 5xx 率 | 最近 30 天 ≤ 0.05% |
| API 网关 | 网关内部处理延迟 | p99 ≤ 20ms |
| 限流系统 | 限流判断成功率 | 最近 30 天 ≥ 99.99% |
| 限流系统 | 规则命中正确率 | 最近 30 天 ≥ 99.999% |
| MQ | produce ack 成功率 | 最近 30 天 ≥ 99.95% |
| MQ | 消息端到端投递延迟 | p99 ≤ 1 秒 |
| 规则中心 | 规则发布成功率 | 最近 30 天 ≥ 99.99% |
| 规则中心 | 规则生效时延 | p99 ≤ 5 秒 |
这里要注意一个设计原则:中间件 SLO 必须分等级。
例如:
| 等级 | 适用对象 | 可用性目标 |
|---|---|---|
| P0 核心链路 | 支付、下单、核心网关、核心注册配置 | 99.99% |
| P1 重要链路 | 主业务系统、核心管理平台 | 99.95% |
| P2 普通链路 | 内部后台、低频任务 | 99.9% |
| P3 非核心链路 | 实验性服务、低优先级平台 | 99% |
不分等级地给所有中间件都设 99.99%,是典型的伪可靠性工程。可靠性是有成本的,应该把高目标留给真正关键的业务路径。
3.3 中间件 SLA 示例
中间件 SLA 可以面向两类对象:
第一类是企业内部业务团队。 例如平台团队向业务团队承诺:
注册中心在 P0 业务命名空间内提供 99.95% 月可用性;
配置中心 P0 配置发布 p99 生效时延不超过 3 秒;
限流系统在核心链路中提供 99.99% 判断成功率;
若 SLA 未达成,平台团队必须在事故复盘中给出根因、修复计划和防复发措施。第二类是外部客户。 例如云产品或 SaaS 平台对外承诺:
API 网关月可用性不低于 99.9%;
若低于 SLA,按照合同给予服务补偿。我的建议是:内部中间件也应该有 SLA,但不要一开始就设计成财务赔偿,而应设计成工程责任协议。 例如明确故障等级、响应时间、升级机制、复盘时限、整改时限、降级预案和业务方接入规范。
四、微服务如何定义 SLI、SLO、SLA
微服务的 SLI/SLO/SLA 与中间件不同。微服务更贴近业务语义,应围绕“用户请求是否被正确完成”来定义,而不是围绕“服务进程是否存活”来定义。
Spring Boot 官方文档把可观测性定义为从外部观察运行中系统内部状态的能力,并指出它包含日志、指标和链路三大支柱;对于 Spring Boot 应用,指标和链路通常基于 Micrometer Observation。(Home) 这说明微服务可靠性指标的采集不应该停留在机器层,而要进入应用框架、接口、调用链和业务标签层。
4.1 微服务 SLI 的核心分类
4.1.1 请求可用性
请求可用性 = 成功请求数 / 有效请求总数但是“成功请求”必须按业务语义定义。比如:
| 场景 | 是否算成功 |
|---|---|
| HTTP 200 且业务 code=0 | 成功 |
| HTTP 200 但业务 code=库存扣减失败 | 不一定成功,要看业务定义 |
| HTTP 400 参数错误 | 通常不算服务失败 |
| HTTP 401 未授权 | 通常不算服务失败 |
| HTTP 500 | 服务失败 |
| 超时 | 服务失败 |
| 熔断降级返回兜底结果 | 是否成功取决于是否满足用户预期 |
这点非常关键。很多系统只看 HTTP 状态码,会严重低估业务失败率。
4.1.2 请求延迟
微服务延迟 SLI 应该至少包含:
p50 / p95 / p99 / p999并按以下维度拆分:
| 维度 | 示例 |
|---|---|
| service | order-service |
| endpoint | POST /orders |
| caller | checkout-service |
| region | cn-hz / sg |
| zone | az1 / az2 |
| version | v1.2.3 |
| status | success / error |
| dependency | mysql / redis / mq |
只看整体 p99 没有意义。一个接口整体 p99 很好,但某个大客户、某个区域、某个版本 p99 很差,这依然是可靠性问题。
4.1.3 业务正确性
业务正确性是微服务区别于基础设施的关键指标。
例如:
| 服务 | 业务正确性 SLI |
|---|---|
| 订单服务 | 成功创建订单数 / 应创建订单请求数 |
| 支付服务 | 支付状态最终一致成功率 |
| 库存服务 | 库存扣减准确率 |
| 账户服务 | 余额变更正确率 |
| 推荐服务 | 推荐结果非空率、推荐新鲜度 |
| 搜索服务 | 查询成功且结果满足基础质量约束的比例 |
对于核心服务,我强烈建议把业务正确性纳入 SLO。只保证接口 99.99% 返回,但返回错误业务结果,是没有价值的可靠性。
4.1.4 依赖健康度
微服务不是孤立运行的。一个服务的可靠性取决于它依赖的数据库、缓存、MQ、RPC 服务和第三方 API。
应定义:
依赖调用成功率
依赖调用 p99 延迟
依赖超时率
依赖重试率
依赖熔断次数
依赖降级命中率更进一步,可以定义:
关键依赖可用性对本服务 SLO 的贡献度这样才能回答一个重要问题:当前服务 SLO 被打穿,到底是自身问题、依赖问题、调用方流量问题,还是治理规则问题?
4.1.5 异步链路 SLI
微服务大量使用 MQ、事件驱动和最终一致性,不能只定义同步接口指标。
异步 SLI 包括:
| 指标 | 示例 |
|---|---|
| 消息生产成功率 | order-created 事件发送成功率 |
| 消息消费成功率 | 库存服务消费订单事件成功率 |
| 消费延迟 | 消息从生产到消费完成 p99 ≤ 5 秒 |
| 堆积量 | consumer lag |
| 死信率 | dead letter 数量 / 总消息数 |
| 最终一致性时延 | 订单创建到库存扣减完成 p99 时延 |
如果系统大量依赖 MQ,但 SLO 只覆盖 HTTP 接口,这个 SLO 是残缺的。
4.2 微服务 SLO 示例
| 服务 | SLI | SLO 示例 |
|---|---|---|
| 用户登录 | 登录成功率 | 最近 30 天 ≥ 99.9% |
| 用户登录 | 登录接口延迟 | p95 ≤ 300ms,p99 ≤ 800ms |
| 订单创建 | 订单创建成功率 | 最近 30 天 ≥ 99.95% |
| 订单创建 | 订单创建业务正确率 | 最近 30 天 ≥ 99.99% |
| 支付服务 | 支付请求成功率 | 最近 30 天 ≥ 99.99% |
| 支付服务 | 支付状态最终一致时延 | p99 ≤ 10 秒 |
| 搜索服务 | 查询成功率 | 最近 30 天 ≥ 99.9% |
| 推荐服务 | 推荐结果非空率 | 最近 30 天 ≥ 99.5% |
| 消息消费 | 消费成功率 | 最近 30 天 ≥ 99.95% |
| 消息消费 | 消费延迟 | p99 ≤ 5 秒 |
微服务 SLO 必须基于接口重要性分层:
| 接口等级 | 示例 | SLO 策略 |
|---|---|---|
| 核心交易接口 | 下单、支付、扣库存 | 高可用、高正确性、低延迟 |
| 核心读接口 | 首页、商品详情、搜索 | 高可用、中高延迟要求 |
| 内部管理接口 | 后台配置、运营平台 | 中等可用性 |
| 离线任务接口 | 报表、数据同步 | 强调完成率和时效性 |
| 实验接口 | A/B 实验、推荐探索 | 允许更高错误预算 |
4.3 微服务 SLA 示例
微服务 SLA 可以分为外部 SLA 和内部 SLA。
外部 SLA 示例:
开放 API 在自然月内可用性不低于 99.9%;
若低于 99.9%,按照合同提供服务补偿;
计划内维护窗口不计入 SLA;
客户自身错误请求不计入 SLA。内部 SLA 示例:
订单服务向支付服务承诺:
POST /orders/create 在 P0 等级下月可用性 ≥ 99.95%,p99 延迟 ≤ 800ms;
当错误预算燃烧超过阈值时,订单服务团队必须冻结非紧急发布,并在 24 小时内给出修复计划。我认为,微服务内部 SLA 的价值非常大。它能把“服务之间互相甩锅”变成“按契约治理依赖关系”。
五、定义这些指标有什么用
5.1 指导告警
没有 SLO 的告警通常是噪音。 有 SLO 的告警才是可靠性信号。
传统告警:
CPU > 80%
线程池队列 > 1000
接口错误数 > 100SLO 告警:
订单服务最近 1 小时错误预算燃烧率过高;
如果持续 6 小时,将耗尽 30 天错误预算。SLO 告警更接近业务风险。Grafana 文档也指出,告警可以基于错误预算燃烧率定义,而不是对每个小偏差都立即响应;SLO 还能让不同团队围绕共同可靠性目标对齐。(Grafana Labs)
5.2 指导发布
错误预算充足时:
允许正常发布
允许灰度实验
允许架构调整错误预算快速消耗时:
冻结非必要发布
暂停高风险变更
优先修复稳定性问题
扩大灰度观察窗口
降低发布频率这比“最近感觉不太稳,先别发版”更可执行。
5.3 指导容量规划
SLO 能帮助判断容量是否足够:
流量增长 30% 后,p99 延迟是否仍满足 SLO?
MQ backlog 是否会导致消费延迟打穿 SLO?
注册中心 watch 数量增长后,推送延迟是否还能满足 SLO?容量规划不应该只看 CPU 水位,而应该看 SLO 是否仍能达成。
5.4 指导架构设计
如果某个服务的 SLO 是 99.99%,那它可能需要:
多副本部署
跨 AZ 容灾
限流熔断
异步削峰
降级方案
幂等机制
数据备份
故障演练如果某个服务 SLO 只有 99%,则没必要投入同等成本。可靠性设计必须分级,否则就是浪费。
5.5 指导事故复盘
事故复盘应围绕 SLI/SLO 展开:
哪个 SLI 退化?
哪个 SLO 被打穿?
错误预算消耗了多少?
故障影响了哪些调用方、接口、区域、版本?
治理动作是否及时?
可观测数据是否足够定位?
后续如何降低同类故障的错误预算消耗?这比单纯写“加强监控、加强测试、加强值班意识”有价值得多。
5.6 指导平台产品化
对于中间件平台来说,SLI/SLO/SLA 可以直接转化为平台能力:
SLO 看板
错误预算看板
租户可靠性分级
治理规则推荐
容量风险预测
发布准入检查
故障影响面分析
服务依赖评分也就是说,SRE 指标不是监控系统的字段,而是平台工程的产品基础。
六、如何更好地依靠可观测体系进行服务治理
OpenTelemetry 官方文档指出,OpenTelemetry 的目的在于收集、处理和导出 signals;这些信号包括可度量的系统状态,也包括跨分布式系统组件传播的事件。OpenTelemetry 也被定义为用于生成、采集、导出日志、指标和链路等遥测数据的厂商中立开源可观测框架。(OpenTelemetry) OpenTelemetry Collector 则提供接收、处理和导出遥测数据的厂商中立实现,可以减少同时维护多个 agent 或 collector 的负担。(OpenTelemetry)
基于这些能力,服务治理不应该再依赖人工观察,而应该依赖可观测数据形成闭环。
6.1 可观测体系的基础架构
一个合理的可观测体系可以设计为:
业务服务 / 中间件 / 网关 / Service Mesh
↓
Metrics + Logs + Traces + Events
↓
OpenTelemetry SDK / Agent / Collector
↓
Prometheus / Tempo / Elasticsearch / Loki / ClickHouse
↓
SLO 计算 / 错误预算 / 拓扑分析 / 根因分析
↓
服务治理平台
↓
限流 / 熔断 / 降级 / 路由 / 灰度 / 扩缩容 / 回滚其中每类数据的作用不同:
| 数据类型 | 作用 |
|---|---|
| Metrics | 计算 SLI、SLO、错误预算、告警 |
| Traces | 分析调用链路、瓶颈、依赖关系 |
| Logs | 定位错误细节、业务上下文、审计证据 |
| Events | 记录发布、配置变更、治理规则变更、故障演练 |
| Topology | 建立服务依赖图和影响面分析 |
| Profiles | 分析 CPU、内存、锁竞争等性能问题 |
6.2 服务治理的闭环模型
我建议采用如下闭环:
观测 → 判断 → 决策 → 执行 → 验证 → 复盘第一步:观测
采集以下数据:
服务请求成功率
接口 p95/p99 延迟
错误码分布
调用方分布
依赖调用耗时
实例负载
版本信息
灰度流量比例
限流熔断命中情况
配置变更事件
发布事件第二步:判断
判断服务是否违反 SLO:
当前错误率是否超过预算?
错误预算燃烧率是否过快?
是否只影响某个调用方?
是否只影响某个版本?
是否只影响某个机房?
是否与最近发布或配置变更相关?第三步:决策
根据判断结果选择治理动作:
| 观测现象 | 治理动作 |
|---|---|
| 某版本错误率升高 | 灰度暂停、流量回切、自动回滚 |
| 某调用方流量异常 | 调用方限流、隔离、配额调整 |
| 下游依赖超时 | 熔断、降级、缩短超时、减少重试 |
| p99 延迟升高 | 扩容、热点隔离、缓存预热 |
| MQ 消费堆积 | 扩消费者、限生产者、优先级消费 |
| 配置发布异常 | 回滚配置、暂停发布、客户端降级 |
| 注册发现异常 | 启用本地缓存、保护最后可用实例 |
第四步:执行
执行治理规则:
动态路由
灰度发布
熔断
限流
降级
隔离
重试预算控制
超时控制
负载均衡权重调整
扩缩容
配置回滚第五步:验证
治理动作执行后,要再次观察:
错误预算燃烧是否下降?
p99 延迟是否恢复?
错误率是否下降?
影响面是否收敛?
是否引入新的副作用?第六步:复盘
复盘不应该只关注“事故原因”,还要关注:
SLI 是否定义正确?
SLO 是否合理?
告警是否及时?
治理动作是否有效?
是否可以自动化?
是否需要调整限流、熔断、降级策略?
是否需要改造架构?6.3 基于可观测数据的治理策略
6.3.1 限流治理
限流不应该只基于静态 QPS,而应该基于 SLO 状态动态调整。
例如:
如果服务错误预算燃烧率过高:
降低低优先级调用方配额
保留核心调用方配额
对非核心接口启用排队或拒绝这比所有流量一刀切更合理。
6.3.2 熔断治理
熔断应该结合:
错误率
超时率
p99 延迟
并发数
下游依赖健康度
错误预算燃烧率不能简单地“失败 50 次就熔断”。否则高流量服务和低流量服务会得到完全不同但不合理的治理效果。
6.3.3 灰度治理
灰度发布必须依赖可观测数据。
灰度判断条件应包括:
新版本错误率是否高于基线?
新版本 p99 是否恶化?
核心接口 SLO 是否受影响?
是否只影响某些调用方?
是否出现新的异常日志模式?
链路中是否新增慢依赖?如果灰度系统没有接入 SLO 和错误预算,只按时间自动扩大流量,这是危险的。
6.3.4 降级治理
降级策略应该分层:
| 等级 | 策略 |
|---|---|
| L1 | 关闭非核心功能 |
| L2 | 使用缓存结果 |
| L3 | 返回默认结果 |
| L4 | 拒绝低优先级请求 |
| L5 | 保护核心链路,只保留下单、支付等能力 |
降级是否触发,应该由 SLO 状态、依赖健康度、错误预算燃烧率共同决定。
6.3.5 路由治理
路由治理可以依据:
地域
机房
版本
调用方
用户分群
错误率
延迟
实例健康度
成本
合规要求例如跨地域架构中,大陆 region 与新加坡 region 之间不能只按延迟路由,还要考虑数据合规、用户归属、跨境数据约束和故障隔离边界。
七、服务治理和可观测体系之间的依赖与驱动关系
服务治理和可观测体系不是简单的上下游关系,而是双向依赖、互相驱动。
Istio 文档指出,服务网格可以为应用提供零信任安全、可观测性和高级流量管理能力,而不需要应用代码改造;同时 Istio 会为网格内服务通信生成详细遥测数据,帮助操作者排查、维护和优化应用。(Istio) Envoy 的可观测能力也覆盖 statistics、access logging、tracing 等方面,分布式追踪可以帮助开发者理解大规模面向服务架构中的调用流、并行关系和延迟来源。(Envoy Proxy)
这说明现代服务治理平台天然应该和可观测体系深度融合。
7.1 可观测体系依赖服务治理
可观测数据要有价值,必须依赖服务治理提供上下文。
7.1.1 依赖服务注册元数据
没有服务注册元数据,指标里只有 IP 和端口:
10.1.2.3:8080
10.1.2.4:8080有了治理元数据,才能知道:
service=order-service
env=prod
region=cn-hz
zone=az1
version=v1.2.3
owner=trade-team
priority=P0没有这些标签,可观测系统只能看到“机器异常”,看不到“业务影响”。
7.1.2 依赖路由和调用关系
治理系统知道:
checkout-service → order-service → inventory-service → payment-service可观测系统基于这些关系才能构建服务拓扑,分析影响面。
7.1.3 依赖治理规则事件
当发生故障时,必须知道:
是否刚发布新版本?
是否刚调整限流规则?
是否刚修改路由权重?
是否刚变更超时时间?
是否刚开启熔断?
是否刚修改配置?如果可观测系统没有接入这些治理事件,根因分析会非常困难。
7.2 服务治理依赖可观测体系
服务治理的动作不能凭空执行,必须依赖可观测数据。
7.2.1 限流依赖流量观测
没有调用方 QPS、接口 QPS、错误率、延迟和优先级,就无法做精细限流。
7.2.2 熔断依赖错误观测
没有错误率、超时率、依赖延迟,就无法判断是否应该熔断。
7.2.3 灰度依赖版本观测
没有版本维度的指标和链路,就无法判断新版本是否健康。
7.2.4 扩容依赖饱和度观测
没有 CPU、内存、线程池、连接池、队列、backlog、consumer lag,就无法判断是否需要扩容。
7.2.5 降级依赖业务影响观测
没有业务 SLI,就无法知道降级是否真的保护了核心链路。
7.3 二者的驱动关系
服务治理和可观测体系之间应形成如下驱动关系:
服务治理提供:
服务目录
调用关系
路由规则
版本信息
流量策略
限流规则
熔断规则
变更事件
可观测体系提供:
SLI
SLO 达成情况
错误预算
延迟分布
错误分布
饱和度
链路瓶颈
影响面
根因线索
二者共同驱动:
自动限流
自动熔断
自动降级
自动回滚
智能扩容
变更准入
事故复盘
架构优化一句话总结:服务治理决定系统如何行动,可观测体系决定行动是否有依据。
八、中间件 SRE 落地方法
8.1 第一步:建立服务分级
先按业务重要性分级:
| 等级 | 示例 | 可靠性要求 |
|---|---|---|
| P0 | 支付、下单、注册中心核心集群、配置中心核心集群 | 极高 |
| P1 | 搜索、推荐、核心网关、MQ 主链路 | 高 |
| P2 | 运营后台、普通任务服务 | 中 |
| P3 | 实验系统、低频内部工具 | 低 |
8.2 第二步:建立 SLI 目录
每个服务必须定义:
可用性 SLI
延迟 SLI
错误率 SLI
饱和度 SLI
正确性 SLI
依赖 SLI
变更事件中间件还必须额外定义:
控制面 SLI
数据面 SLI
配置传播 SLI
规则一致性 SLI
客户端感知 SLI
RPO / RTO8.3 第三步:建立 SLO 模板
例如:
P0 HTTP API:
availability ≥ 99.95%
p99 latency ≤ 800ms
error budget window = 30 days
P0 配置中心:
read availability ≥ 99.99%
publish success ≥ 99.99%
propagation p99 ≤ 3s
P0 注册中心:
discovery availability ≥ 99.95%
heartbeat success ≥ 99.99%
unhealthy instance removal p99 ≤ 5s8.4 第四步:建立错误预算策略
例如:
| 错误预算状态 | 策略 |
|---|---|
| 剩余 > 50% | 正常发布 |
| 剩余 20% ~ 50% | 高风险发布需审批 |
| 剩余 5% ~ 20% | 只允许低风险变更 |
| 剩余 < 5% | 冻结非紧急发布 |
| 已耗尽 | 必须进入稳定性修复周期 |
8.5 第五步:接入发布和配置变更
所有变更都应该成为可观测事件:
应用发布
配置发布
路由调整
限流规则调整
熔断规则调整
扩容缩容
数据库变更
中间件升级没有变更事件,就很难做根因分析。
8.6 第六步:治理动作自动化,但必须有护栏
自动化治理不能无脑执行。必须有护栏:
最大限流比例
最大回滚范围
灰度最小观察时间
核心调用方保护名单
人工确认阈值
自动化动作冷却时间
治理动作审计日志我不建议一开始就追求全自动故障自治。更现实的路径是:
先做到自动发现
再做到自动推荐
再做到半自动执行
最后再做有限范围自动闭环九、结论
本文围绕“中间件站点可靠性工程”讨论了 SLI、SLO、SLA 在中间件和微服务体系中的定义方法及其工程价值。本文的核心结论如下:
第一,SLI/SLO/SLA 是 SRE 的可靠性语言。SLI 负责度量现实,SLO 负责定义目标,SLA 负责形成承诺。没有这三者,可靠性管理就会停留在主观经验层面。
第二,中间件 SRE 不能照搬微服务 SRE。中间件必须额外关注控制面、数据面、一致性、传播时延、规则正确性、客户端感知、RPO/RTO 和故障放大效应。
第三,微服务 SRE 必须围绕用户旅程和业务正确性定义指标。接口返回 200 不等于业务成功,进程存活不等于服务可靠。
第四,SLO 的最大价值是错误预算。错误预算把发布速度和系统稳定性放到同一套工程语言中,让团队能基于数据做决策。
第五,可观测体系是服务治理的事实基础。没有指标、日志、链路、事件和拓扑,限流、熔断、降级、灰度、回滚都会变成盲目操作。
第六,服务治理反过来驱动可观测体系完善。治理系统提供服务目录、调用关系、版本、路由、规则和变更事件,使可观测数据具备业务上下文。
最终,成熟的中间件 SRE 体系不应该只是“监控 + 告警 + 值班”,而应该是:
可靠性目标定义
↓
可观测数据采集
↓
错误预算计算
↓
治理策略执行
↓
效果验证
↓
事故复盘与系统改进这才是面向现代微服务与中间件平台的站点可靠性工程。

参与讨论
评论会同步到 stellhub/stell-web 仓库的 GitHub Discussions。