Skip to content

中间件站点可靠性工程研究 ​

概览 ​

围绕中间件与微服务体系,系统梳理 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 需要满足四个条件:

  1. 可度量:必须能通过指标、日志、链路、探测任务或业务校验计算出来。
  2. 用户相关:不能只看机器指标,而要反映调用方、业务方、用户侧的体验。
  3. 边界清晰:必须说明统计窗口、分母、分子、过滤条件。
  4. 可归因:指标异常时,要能进一步定位到服务、接口、调用方、机房、版本、依赖或治理规则。

我的判断是:很多团队的监控失败,不是因为指标少,而是因为 SLI 定义错了。 例如只监控 CPU、内存、进程存活、端口存活,却不监控用户请求成功率、配置生效时延、消息堆积时延、规则命中正确率,这种监控对可靠性治理价值很低。

2.2 SLO:服务水平目标 ​

SLO,全称 Service Level Objective,即服务水平目标。它回答的问题是:系统应该达到什么可靠性水平?

SLO 通常由三部分组成:

text
SLO = SLI + 目标阈值 + 统计窗口

例如:

text
订单创建接口在最近 30 天内,99.9% 的有效请求应在 300ms 内成功返回。

这里:

组成部分示例
SLI有效订单创建请求的成功率和延迟
目标阈值成功率 ≥ 99.9%,p95 延迟 ≤ 300ms
统计窗口最近 30 天

SLO 的重要价值在于它引入了 错误预算。如果 SLO 是 99.9%,那么允许的不可用比例就是 0.1%。这 0.1% 就是错误预算。Google SRE Workbook 指出,有了 SLO 后可以推导错误预算,并且需要制定错误预算策略,用于决定服务预算耗尽时团队应该采取什么行动。(Google SRE)

错误预算的本质是一个工程管理工具:

text
错误预算 = 1 - SLO

例如:

SLO30 天错误预算
99%约 7.2 小时不可用
99.9%约 43.2 分钟不可用
99.99%约 4.32 分钟不可用

SLO 的意义不是追求“永不出错”,而是明确系统可以承受多少失败。如果错误预算充足,可以允许更快发布、更大胆实验;如果错误预算快速燃烧,就必须降低变更频率,优先修复可靠性问题。

2.3 SLA:服务水平协议 ​

SLA,全称 Service Level Agreement,即服务水平协议。它回答的问题是:服务提供方对服务使用方承诺什么?如果做不到,后果是什么?

SLA 与 SLO 的区别非常关键:

对比项SLOSLA
性质内部可靠性目标对外或跨团队正式承诺
目的指导工程治理明确责任边界和违约后果
是否有惩罚通常没有直接惩罚通常有赔偿、降级、补偿、考核
设置原则应该严于 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 不能简单照搬普通业务接口。中间件通常具备以下特点:

  1. 共享依赖:多个业务共同依赖,一次故障影响多个系统。
  2. 控制平面与数据平面分离:例如配置发布是控制面,请求转发是数据面。
  3. 强一致与最终一致混合:例如注册中心、配置中心、治理规则分发。
  4. 客户端 SDK 深度参与:可靠性不只取决于服务端,也取决于客户端缓存、重试、降级。
  5. 故障影响具有放大性:中间件抖动可能导致业务雪崩。

所以,中间件指标必须按照能力域来设计,而不是只按机器资源设计。

3.1 中间件 SLI 的核心分类 ​

3.1.1 可用性 SLI ​

适用于注册中心、配置中心、网关、限流服务、消息队列、缓存代理等。

text
可用性 SLI = 成功请求数 / 有效请求总数

但这里的“成功”必须按中间件语义定义:

中间件类型成功事件定义
注册中心服务注册成功、心跳续约成功、服务发现返回有效实例
配置中心配置读取成功、配置发布成功、客户端监听成功
API 网关请求被正确路由并返回非网关侧错误
限流系统规则查询成功、限流判断成功、配额扣减成功
MQ消息发送确认成功、消息持久化成功、消费确认成功
缓存代理get/set/delete 请求成功,且非客户端非法请求

这里必须排除调用方自身错误。例如 HTTP 400、鉴权失败、非法参数,不应该全部算作中间件失败。否则 SLI 会被业务误用污染。

3.1.2 延迟 SLI ​

中间件延迟不能只看平均值,必须看分位数,尤其是 p95、p99、p999。

中间件类型延迟 SLI 示例
注册中心服务发现 p99 延迟
配置中心配置发布到客户端生效 p99 时延
网关网关自身处理 p99 延迟,不含后端业务耗时
MQproduce ack p99、端到端投递 p99
缓存代理命令执行 p99 延迟
限流系统单次限流判断 p99 延迟

注意:中间件延迟必须区分自身耗时和下游耗时。 比如网关请求慢,可能是后端服务慢,不一定是网关慢。因此网关 SLI 至少要拆成:

text
gateway_total_latency
gateway_internal_latency
upstream_service_latency

否则治理动作会误判。

3.1.3 正确性 SLI ​

这是中间件最容易被忽略、但最重要的指标。

中间件能力正确性 SLI
注册中心发现结果是否包含健康实例,是否剔除异常实例
配置中心客户端配置版本是否与服务端期望版本一致
限流系统规则命中是否正确,配额扣减是否准确
路由系统灰度流量是否进入正确版本
熔断系统熔断状态是否符合错误率和窗口规则
MQ消息是否重复、乱序、丢失,是否满足承诺语义
缓存数据是否过期、击穿、污染

我认为,中间件 SRE 如果不定义正确性 SLI,只定义可用性和延迟,是不合格的。 因为中间件最可怕的故障往往不是“挂了”,而是“还活着,但返回了错误结果”。

3.1.4 一致性与传播 SLI ​

控制平面类中间件必须定义传播类指标。

例如配置中心:

text
配置传播时延 = 客户端观察到目标配置版本的时间 - 服务端发布成功时间

注册中心:

text
实例摘除传播时延 = 客户端不再发现异常实例的时间 - 服务端判定实例异常的时间

治理规则中心:

text
规则生效时延 = 流量实际按新规则执行的时间 - 规则发布成功时间

这类指标比“接口可用性”更贴近中间件真实价值。配置中心接口 100% 可用,但配置 5 分钟才生效,对业务来说依然是严重问题。

3.1.5 持久性与恢复 SLI ​

适用于 MQ、注册配置存储、规则中心、元数据中心。

指标含义
RPO故障后最多允许丢失多少数据
RTO故障后多久恢复服务
数据丢失率丢失数据量 / 应持久化数据量
副本同步延迟follower 与 leader 的复制滞后
快照恢复成功率从快照恢复成功次数 / 恢复总次数

如果一个中间件承载核心配置、治理规则、消息数据,却没有 RPO/RTO 指标,那么它的可靠性体系是不完整的。

3.1.6 饱和度 SLI ​

饱和度不是普通资源监控,它要反映系统是否接近处理极限。

中间件饱和度指标
网关连接数、活跃请求数、线程池队列、upstream pending request
MQtopic backlog、consumer lag、broker 磁盘水位
注册中心watch 数量、推送队列积压、心跳处理队列
配置中心长连接数量、变更推送队列、客户端监听数
限流系统热点规则 QPS、配额存储冲突、远程判断耗时
缓存内存水位、淘汰率、热点 key 访问量

饱和度指标的价值在于预测故障,而不是等故障发生后再报警。

3.2 中间件 SLO 示例 ​

中间件SLISLO 示例
注册中心服务发现成功率最近 30 天 ≥ 99.95%
注册中心异常实例摘除传播时延p99 ≤ 5 秒
配置中心配置读取成功率最近 30 天 ≥ 99.99%
配置中心配置发布生效时延p99 ≤ 3 秒
API 网关网关自身 5xx 率最近 30 天 ≤ 0.05%
API 网关网关内部处理延迟p99 ≤ 20ms
限流系统限流判断成功率最近 30 天 ≥ 99.99%
限流系统规则命中正确率最近 30 天 ≥ 99.999%
MQproduce 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 可以面向两类对象:

第一类是企业内部业务团队。 例如平台团队向业务团队承诺:

text
注册中心在 P0 业务命名空间内提供 99.95% 月可用性;
配置中心 P0 配置发布 p99 生效时延不超过 3 秒;
限流系统在核心链路中提供 99.99% 判断成功率;
若 SLA 未达成,平台团队必须在事故复盘中给出根因、修复计划和防复发措施。

第二类是外部客户。 例如云产品或 SaaS 平台对外承诺:

text
API 网关月可用性不低于 99.9%;
若低于 SLA,按照合同给予服务补偿。

我的建议是:内部中间件也应该有 SLA,但不要一开始就设计成财务赔偿,而应设计成工程责任协议。 例如明确故障等级、响应时间、升级机制、复盘时限、整改时限、降级预案和业务方接入规范。


四、微服务如何定义 SLI、SLO、SLA ​

微服务的 SLI/SLO/SLA 与中间件不同。微服务更贴近业务语义,应围绕“用户请求是否被正确完成”来定义,而不是围绕“服务进程是否存活”来定义。

Spring Boot 官方文档把可观测性定义为从外部观察运行中系统内部状态的能力,并指出它包含日志、指标和链路三大支柱;对于 Spring Boot 应用,指标和链路通常基于 Micrometer Observation。(Home) 这说明微服务可靠性指标的采集不应该停留在机器层,而要进入应用框架、接口、调用链和业务标签层。

4.1 微服务 SLI 的核心分类 ​

4.1.1 请求可用性 ​

text
请求可用性 = 成功请求数 / 有效请求总数

但是“成功请求”必须按业务语义定义。比如:

场景是否算成功
HTTP 200 且业务 code=0成功
HTTP 200 但业务 code=库存扣减失败不一定成功,要看业务定义
HTTP 400 参数错误通常不算服务失败
HTTP 401 未授权通常不算服务失败
HTTP 500服务失败
超时服务失败
熔断降级返回兜底结果是否成功取决于是否满足用户预期

这点非常关键。很多系统只看 HTTP 状态码,会严重低估业务失败率。

4.1.2 请求延迟 ​

微服务延迟 SLI 应该至少包含:

text
p50 / p95 / p99 / p999

并按以下维度拆分:

维度示例
serviceorder-service
endpointPOST /orders
callercheckout-service
regioncn-hz / sg
zoneaz1 / az2
versionv1.2.3
statussuccess / error
dependencymysql / redis / mq

只看整体 p99 没有意义。一个接口整体 p99 很好,但某个大客户、某个区域、某个版本 p99 很差,这依然是可靠性问题。

4.1.3 业务正确性 ​

业务正确性是微服务区别于基础设施的关键指标。

例如:

服务业务正确性 SLI
订单服务成功创建订单数 / 应创建订单请求数
支付服务支付状态最终一致成功率
库存服务库存扣减准确率
账户服务余额变更正确率
推荐服务推荐结果非空率、推荐新鲜度
搜索服务查询成功且结果满足基础质量约束的比例

对于核心服务,我强烈建议把业务正确性纳入 SLO。只保证接口 99.99% 返回,但返回错误业务结果,是没有价值的可靠性。

4.1.4 依赖健康度 ​

微服务不是孤立运行的。一个服务的可靠性取决于它依赖的数据库、缓存、MQ、RPC 服务和第三方 API。

应定义:

text
依赖调用成功率
依赖调用 p99 延迟
依赖超时率
依赖重试率
依赖熔断次数
依赖降级命中率

更进一步,可以定义:

text
关键依赖可用性对本服务 SLO 的贡献度

这样才能回答一个重要问题:当前服务 SLO 被打穿,到底是自身问题、依赖问题、调用方流量问题,还是治理规则问题?

4.1.5 异步链路 SLI ​

微服务大量使用 MQ、事件驱动和最终一致性,不能只定义同步接口指标。

异步 SLI 包括:

指标示例
消息生产成功率order-created 事件发送成功率
消息消费成功率库存服务消费订单事件成功率
消费延迟消息从生产到消费完成 p99 ≤ 5 秒
堆积量consumer lag
死信率dead letter 数量 / 总消息数
最终一致性时延订单创建到库存扣减完成 p99 时延

如果系统大量依赖 MQ,但 SLO 只覆盖 HTTP 接口,这个 SLO 是残缺的。

4.2 微服务 SLO 示例 ​

服务SLISLO 示例
用户登录登录成功率最近 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 示例:

text
开放 API 在自然月内可用性不低于 99.9%;
若低于 99.9%,按照合同提供服务补偿;
计划内维护窗口不计入 SLA;
客户自身错误请求不计入 SLA。

内部 SLA 示例:

text
订单服务向支付服务承诺:
POST /orders/create 在 P0 等级下月可用性 ≥ 99.95%,p99 延迟 ≤ 800ms;
当错误预算燃烧超过阈值时,订单服务团队必须冻结非紧急发布,并在 24 小时内给出修复计划。

我认为,微服务内部 SLA 的价值非常大。它能把“服务之间互相甩锅”变成“按契约治理依赖关系”。


五、定义这些指标有什么用 ​

5.1 指导告警 ​

没有 SLO 的告警通常是噪音。 有 SLO 的告警才是可靠性信号。

传统告警:

text
CPU > 80%
线程池队列 > 1000
接口错误数 > 100

SLO 告警:

text
订单服务最近 1 小时错误预算燃烧率过高;
如果持续 6 小时,将耗尽 30 天错误预算。

SLO 告警更接近业务风险。Grafana 文档也指出,告警可以基于错误预算燃烧率定义,而不是对每个小偏差都立即响应;SLO 还能让不同团队围绕共同可靠性目标对齐。(Grafana Labs)

5.2 指导发布 ​

错误预算充足时:

text
允许正常发布
允许灰度实验
允许架构调整

错误预算快速消耗时:

text
冻结非必要发布
暂停高风险变更
优先修复稳定性问题
扩大灰度观察窗口
降低发布频率

这比“最近感觉不太稳,先别发版”更可执行。

5.3 指导容量规划 ​

SLO 能帮助判断容量是否足够:

text
流量增长 30% 后,p99 延迟是否仍满足 SLO?
MQ backlog 是否会导致消费延迟打穿 SLO?
注册中心 watch 数量增长后,推送延迟是否还能满足 SLO?

容量规划不应该只看 CPU 水位,而应该看 SLO 是否仍能达成。

5.4 指导架构设计 ​

如果某个服务的 SLO 是 99.99%,那它可能需要:

text
多副本部署
跨 AZ 容灾
限流熔断
异步削峰
降级方案
幂等机制
数据备份
故障演练

如果某个服务 SLO 只有 99%,则没必要投入同等成本。可靠性设计必须分级,否则就是浪费。

5.5 指导事故复盘 ​

事故复盘应围绕 SLI/SLO 展开:

text
哪个 SLI 退化?
哪个 SLO 被打穿?
错误预算消耗了多少?
故障影响了哪些调用方、接口、区域、版本?
治理动作是否及时?
可观测数据是否足够定位?
后续如何降低同类故障的错误预算消耗?

这比单纯写“加强监控、加强测试、加强值班意识”有价值得多。

5.6 指导平台产品化 ​

对于中间件平台来说,SLI/SLO/SLA 可以直接转化为平台能力:

text
SLO 看板
错误预算看板
租户可靠性分级
治理规则推荐
容量风险预测
发布准入检查
故障影响面分析
服务依赖评分

也就是说,SRE 指标不是监控系统的字段,而是平台工程的产品基础。


六、如何更好地依靠可观测体系进行服务治理 ​

OpenTelemetry 官方文档指出,OpenTelemetry 的目的在于收集、处理和导出 signals;这些信号包括可度量的系统状态,也包括跨分布式系统组件传播的事件。OpenTelemetry 也被定义为用于生成、采集、导出日志、指标和链路等遥测数据的厂商中立开源可观测框架。(OpenTelemetry) OpenTelemetry Collector 则提供接收、处理和导出遥测数据的厂商中立实现,可以减少同时维护多个 agent 或 collector 的负担。(OpenTelemetry)

基于这些能力,服务治理不应该再依赖人工观察,而应该依赖可观测数据形成闭环。

6.1 可观测体系的基础架构 ​

一个合理的可观测体系可以设计为:

text
业务服务 / 中间件 / 网关 / 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 服务治理的闭环模型 ​

我建议采用如下闭环:

text
观测 → 判断 → 决策 → 执行 → 验证 → 复盘

第一步:观测 ​

采集以下数据:

text
服务请求成功率
接口 p95/p99 延迟
错误码分布
调用方分布
依赖调用耗时
实例负载
版本信息
灰度流量比例
限流熔断命中情况
配置变更事件
发布事件

第二步:判断 ​

判断服务是否违反 SLO:

text
当前错误率是否超过预算?
错误预算燃烧率是否过快?
是否只影响某个调用方?
是否只影响某个版本?
是否只影响某个机房?
是否与最近发布或配置变更相关?

第三步:决策 ​

根据判断结果选择治理动作:

观测现象治理动作
某版本错误率升高灰度暂停、流量回切、自动回滚
某调用方流量异常调用方限流、隔离、配额调整
下游依赖超时熔断、降级、缩短超时、减少重试
p99 延迟升高扩容、热点隔离、缓存预热
MQ 消费堆积扩消费者、限生产者、优先级消费
配置发布异常回滚配置、暂停发布、客户端降级
注册发现异常启用本地缓存、保护最后可用实例

第四步:执行 ​

执行治理规则:

text
动态路由
灰度发布
熔断
限流
降级
隔离
重试预算控制
超时控制
负载均衡权重调整
扩缩容
配置回滚

第五步:验证 ​

治理动作执行后,要再次观察:

text
错误预算燃烧是否下降?
p99 延迟是否恢复?
错误率是否下降?
影响面是否收敛?
是否引入新的副作用?

第六步:复盘 ​

复盘不应该只关注“事故原因”,还要关注:

text
SLI 是否定义正确?
SLO 是否合理?
告警是否及时?
治理动作是否有效?
是否可以自动化?
是否需要调整限流、熔断、降级策略?
是否需要改造架构?

6.3 基于可观测数据的治理策略 ​

6.3.1 限流治理 ​

限流不应该只基于静态 QPS,而应该基于 SLO 状态动态调整。

例如:

text
如果服务错误预算燃烧率过高:
    降低低优先级调用方配额
    保留核心调用方配额
    对非核心接口启用排队或拒绝

这比所有流量一刀切更合理。

6.3.2 熔断治理 ​

熔断应该结合:

text
错误率
超时率
p99 延迟
并发数
下游依赖健康度
错误预算燃烧率

不能简单地“失败 50 次就熔断”。否则高流量服务和低流量服务会得到完全不同但不合理的治理效果。

6.3.3 灰度治理 ​

灰度发布必须依赖可观测数据。

灰度判断条件应包括:

text
新版本错误率是否高于基线?
新版本 p99 是否恶化?
核心接口 SLO 是否受影响?
是否只影响某些调用方?
是否出现新的异常日志模式?
链路中是否新增慢依赖?

如果灰度系统没有接入 SLO 和错误预算,只按时间自动扩大流量,这是危险的。

6.3.4 降级治理 ​

降级策略应该分层:

等级策略
L1关闭非核心功能
L2使用缓存结果
L3返回默认结果
L4拒绝低优先级请求
L5保护核心链路,只保留下单、支付等能力

降级是否触发,应该由 SLO 状态、依赖健康度、错误预算燃烧率共同决定。

6.3.5 路由治理 ​

路由治理可以依据:

text
地域
机房
版本
调用方
用户分群
错误率
延迟
实例健康度
成本
合规要求

例如跨地域架构中,大陆 region 与新加坡 region 之间不能只按延迟路由,还要考虑数据合规、用户归属、跨境数据约束和故障隔离边界。


七、服务治理和可观测体系之间的依赖与驱动关系 ​

服务治理和可观测体系不是简单的上下游关系,而是双向依赖、互相驱动。

Istio 文档指出,服务网格可以为应用提供零信任安全、可观测性和高级流量管理能力,而不需要应用代码改造;同时 Istio 会为网格内服务通信生成详细遥测数据,帮助操作者排查、维护和优化应用。(Istio) Envoy 的可观测能力也覆盖 statistics、access logging、tracing 等方面,分布式追踪可以帮助开发者理解大规模面向服务架构中的调用流、并行关系和延迟来源。(Envoy Proxy)

这说明现代服务治理平台天然应该和可观测体系深度融合。

7.1 可观测体系依赖服务治理 ​

可观测数据要有价值,必须依赖服务治理提供上下文。

7.1.1 依赖服务注册元数据 ​

没有服务注册元数据,指标里只有 IP 和端口:

text
10.1.2.3:8080
10.1.2.4:8080

有了治理元数据,才能知道:

text
service=order-service
env=prod
region=cn-hz
zone=az1
version=v1.2.3
owner=trade-team
priority=P0

没有这些标签,可观测系统只能看到“机器异常”,看不到“业务影响”。

7.1.2 依赖路由和调用关系 ​

治理系统知道:

text
checkout-service → order-service → inventory-service → payment-service

可观测系统基于这些关系才能构建服务拓扑,分析影响面。

7.1.3 依赖治理规则事件 ​

当发生故障时,必须知道:

text
是否刚发布新版本?
是否刚调整限流规则?
是否刚修改路由权重?
是否刚变更超时时间?
是否刚开启熔断?
是否刚修改配置?

如果可观测系统没有接入这些治理事件,根因分析会非常困难。

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 二者的驱动关系 ​

服务治理和可观测体系之间应形成如下驱动关系:

text
服务治理提供:
    服务目录
    调用关系
    路由规则
    版本信息
    流量策略
    限流规则
    熔断规则
    变更事件

可观测体系提供:
    SLI
    SLO 达成情况
    错误预算
    延迟分布
    错误分布
    饱和度
    链路瓶颈
    影响面
    根因线索

二者共同驱动:
    自动限流
    自动熔断
    自动降级
    自动回滚
    智能扩容
    变更准入
    事故复盘
    架构优化

一句话总结:服务治理决定系统如何行动,可观测体系决定行动是否有依据。


八、中间件 SRE 落地方法 ​

8.1 第一步:建立服务分级 ​

先按业务重要性分级:

等级示例可靠性要求
P0支付、下单、注册中心核心集群、配置中心核心集群极高
P1搜索、推荐、核心网关、MQ 主链路高
P2运营后台、普通任务服务中
P3实验系统、低频内部工具低

8.2 第二步:建立 SLI 目录 ​

每个服务必须定义:

text
可用性 SLI
延迟 SLI
错误率 SLI
饱和度 SLI
正确性 SLI
依赖 SLI
变更事件

中间件还必须额外定义:

text
控制面 SLI
数据面 SLI
配置传播 SLI
规则一致性 SLI
客户端感知 SLI
RPO / RTO

8.3 第三步:建立 SLO 模板 ​

例如:

text
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 ≤ 5s

8.4 第四步:建立错误预算策略 ​

例如:

错误预算状态策略
剩余 > 50%正常发布
剩余 20% ~ 50%高风险发布需审批
剩余 5% ~ 20%只允许低风险变更
剩余 < 5%冻结非紧急发布
已耗尽必须进入稳定性修复周期

8.5 第五步:接入发布和配置变更 ​

所有变更都应该成为可观测事件:

text
应用发布
配置发布
路由调整
限流规则调整
熔断规则调整
扩容缩容
数据库变更
中间件升级

没有变更事件,就很难做根因分析。

8.6 第六步:治理动作自动化,但必须有护栏 ​

自动化治理不能无脑执行。必须有护栏:

text
最大限流比例
最大回滚范围
灰度最小观察时间
核心调用方保护名单
人工确认阈值
自动化动作冷却时间
治理动作审计日志

我不建议一开始就追求全自动故障自治。更现实的路径是:

text
先做到自动发现
再做到自动推荐
再做到半自动执行
最后再做有限范围自动闭环

九、结论 ​

本文围绕“中间件站点可靠性工程”讨论了 SLI、SLO、SLA 在中间件和微服务体系中的定义方法及其工程价值。本文的核心结论如下:

第一,SLI/SLO/SLA 是 SRE 的可靠性语言。SLI 负责度量现实,SLO 负责定义目标,SLA 负责形成承诺。没有这三者,可靠性管理就会停留在主观经验层面。

第二,中间件 SRE 不能照搬微服务 SRE。中间件必须额外关注控制面、数据面、一致性、传播时延、规则正确性、客户端感知、RPO/RTO 和故障放大效应。

第三,微服务 SRE 必须围绕用户旅程和业务正确性定义指标。接口返回 200 不等于业务成功,进程存活不等于服务可靠。

第四,SLO 的最大价值是错误预算。错误预算把发布速度和系统稳定性放到同一套工程语言中,让团队能基于数据做决策。

第五,可观测体系是服务治理的事实基础。没有指标、日志、链路、事件和拓扑,限流、熔断、降级、灰度、回滚都会变成盲目操作。

第六,服务治理反过来驱动可观测体系完善。治理系统提供服务目录、调用关系、版本、路由、规则和变更事件,使可观测数据具备业务上下文。

最终,成熟的中间件 SRE 体系不应该只是“监控 + 告警 + 值班”,而应该是:

text
可靠性目标定义
        ↓
可观测数据采集
        ↓
错误预算计算
        ↓
治理策略执行
        ↓
效果验证
        ↓
事故复盘与系统改进

这才是面向现代微服务与中间件平台的站点可靠性工程。

GitHub Discussions

参与讨论

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

Powered by VitePress and GitHub Discussions.