集群可用性目标往往被写成一个整体数字,例如核心链路全年可用性不低于99.95%。这个数字适合对外承诺,却不适合直接作为监控系统的唯一判断依据。一个请求从入口网关进入,经过鉴权、业务服务、缓存、数据库和消息队列,任何一跳的延迟或失败都可能消耗整体可用性。假如监控只统计最终成功率,当某个依赖服务开始劣化时,整体指标可能仍然显示正常,直到重试和超时把集群拖垮。因此,第一步不是增加更多告警,而是把可用性目标拆解到请求链路和基础设施层级。

一、按请求链路拆解可用性目标
可用性目标拆解的第一层是用户请求链路。以一次下单请求为例,它可以拆成DNS解析、TLS握手、网关转发、订单服务、库存服务、支付服务和数据库写入。每一跳都有独立的成功率和延迟分布。集群级SLO可以定义成这些跳转成功率的乘积:如果入口网关成功率99.9%,订单服务99.9%,库存服务99.5%,支付服务99.9%,数据库99.9%,那么整条链路的最差理论成功率只有99.1%左右。这个简单计算说明,整体目标不能平均分配到每个组件,必须为高扇出或强依赖服务设置更严格的子目标。
拆解时建议使用用户视角的请求计数,而不是容器CPU使用率。可用性的核心定义是“好的请求数除以总请求数”。好的请求通常指在约定时间内返回且业务语义正确。对于异步链路,还应区分消息投递成功和消费成功,因为中间件可能已经接收消息,但消费者积压导致用户看不到结果。把请求链路画成一张拓扑图,并给每个节点标注请求量、超时阈值和重试策略,是后续设定监控指标的基础。
另一个容易忽略的点是重试对可用性计算的放大作用。客户端重试一次,服务端可能收到两次请求,如果只统计服务端成功率,会低估用户感受到的失败。监控应尽量从入口或网关层采集用户视角的请求结果,对于内部重试则作为单独维度记录,避免重复计算掩盖真实情况。
二、用SLO和错误预算驱动监控阈值
将可用性目标转化为监控指标的关键概念是SLO和错误预算。SLO是服务在某个时间窗口内的目标,例如30天内99.95%的请求必须成功。错误预算等于1减去SLO,表示这段时间内允许失败的请求比例。99.95%对应的错误预算为0.05%,如果30天有1亿请求,那么允许失败50万次。监控系统的任务不是禁止一切错误,而是跟踪错误预算的消耗速度。
把错误预算接入告警的好处是避免阈值一刀切。例如一个低流量管理接口错误率偶尔达到5%可能并不会快速耗尽预算,而一个每秒数万次的查询接口即使错误率只有0.1%,也可能在几小时内烧光预算。可以根据错误预算消耗比例设置多级告警:当过去1小时消耗了月度错误预算的2%时提醒值班人员,消耗10%时升级为严重告警。这样监控覆盖的重点就从“有没有报错”转向“错误是否在可控范围内”。
实现上可以先用Prometheus记录请求总数和失败数,然后通过记录规则或告警规则计算错误预算消耗。下面是一段示例规则,用来计算最近7天错误率并对比SLO目标:
groups:
- name: slo-alerts
interval: 30s
rules:
- record: job:http_requests_total:rate7d
expr: sum by (job) (rate(http_requests_total[7d]))
- record: job:http_requests_failed:rate7d
expr: sum by (job) (rate(http_requests_failed[7d]))
- alert: SLOErrorBudgetFastBurn
expr: |
(
job:http_requests_failed:rate7d
/
(job:http_requests_total:rate7d > 0)
) > 0.001
for: 15m
labels:
severity: warning
annotations:
summary: '服务 {{ $labels.job }} 错误率超过0.1%'
这段规则中,0.001对应99.9%的SLO,实际部署时应根据每个服务的SLO单独设置。使用记录规则可以减少重复计算,也能让错误预算消耗的查询更快。需要注意,告警阈值不要直接等于错误预算总量,否则等告警触发时预算已经用尽,失去了提前介入的机会。
三、监控覆盖的四个关键维度
有了分解目标和SLO之后,还要检查监控是否真正覆盖到可能破坏可用性的路径。监控覆盖不是单纯增加指标数量,而是确保四个维度都有数据:流量、错误、延迟和饱和度,也就是常说的四个黄金信号。流量指标反映当前请求量是否偏离正常模型,错误指标反映失败比例,延迟指标关注慢请求占比,饱和度指标用于发现资源耗尽或队列堆积。
流量和错误容易覆盖,但延迟和饱和度经常被简化。比如一个服务平均延迟只有50毫秒,但P99延迟达到3秒,仍然会有大量用户超时。监控需要同时采集平均延迟、P95、P99和最大延迟,并针对关键接口设置延迟阈值。饱和度则要覆盖CPU、内存、磁盘IO、网络带宽、连接池、线程池和消息积压。只监控CPU和内存会漏掉连接池耗尽这类典型的可用性杀手。
另外还要检查监控的采集频率和存储周期。频率太低会漏掉短时故障,比如30秒采集一次可能无法捕捉持续10秒的抖动。存储周期过短则无法计算月度错误预算。建议关键指标采集间隔不超过15秒,原始数据保留至少30天,聚合数据保留更长时间。对于分布式集群,还需要在指标中保留集群ID、机房、可用区等标签,方便定位是局部故障还是全局故障。
四、验证监控覆盖并避免常见误区
即使指标配置齐全,也需要通过故障演练验证监控覆盖是否真正有效。可以主动注入延迟、杀掉依赖服务、打满连接池或触发限流,然后检查告警是否按预期触发,值班人员能否在告警信息中找到关键线索。演练中常见的问题是告警太多,真正重要的信息被淹没。解决方法是按严重程度和影响范围分组,避免每个实例都触发相同告警。
一个常见误区是把基础设施可用性等同于业务可用性。某台虚拟机宕机并不一定导致用户不可用,因为有副本和自动迁移;而所有实例都活着但线程池卡死,业务可能已经不可用。监控覆盖应以用户请求结果为第一优先级,基础设施指标作为辅助定位手段。另一个误区是只监控内部服务,忽略云厂商API、DNS、CDN等外部依赖。外部依赖故障同样会消耗集群可用性,需要纳入监控并通过拨测或日志采集覆盖。
最后建议定期复盘错误预算消耗情况。如果某个服务经常快速耗尽预算,说明SLO可能设置得过严或服务本身需要架构改造。如果预算几乎从未消耗,说明监控可能漏报了错误。把可用性目标分解和监控覆盖结合起来,本质上是建立一套反馈机制,让团队既能提前发现风险,也能用数据指导优先级。