
做运维这些年,我发现一个特别有意思的现象:
很多公司都知道 SLO 很重要,但真正让他定 SLO 的时候,最后往往变成一句话:
“核心系统嘛,99.99% 应该差不多吧?”
然后大家点点头,方案通过。
过几个月线上出问题,才发现——这个 99.99% 到底代表什么?谁都说不清。
数据库认为自己达标了,API 认为自己达标了,前端也认为自己达标了,但用户已经在群里骂了半小时。
所以我一直觉得:
SLO 不是给监控系统看的数字,而是给业务和用户看的承诺。
尤其是复杂产品,真正困难的不是把 SLO 写成 99.9%、99.99%,而是回答三个问题:
到底什么算“好”?什么算“坏”?坏到什么程度才值得我们花钱去解决?
这才是 SLO 设计真正难的地方。
很多人第一次接触 SLO,容易把几个概念混在一起。
简单理解:
比如一个订单 API:
SLI:成功率
SLO:99.95%
SLA:99.9%这意味着:
我们实际监控订单 API 的成功率,然后要求:
在规定统计周期内,至少 99.95% 的请求应该成功。
这里有一个非常重要的点:
SLO不是“越高越好”。
很多团队喜欢追求:
99%
99.9%
99.99%
99.999%好像数字越多 9,系统就越牛。
其实不是。
因为每多一个 9,背后往往都是实打实的钱。
我们直接算一笔账。
假设一个月按照 30 天计算:
SLO | 每月允许不可用时间 |
|---|---|
99% | 7小时12分钟 |
99.9% | 43分钟12秒 |
99.95% | 21分钟36秒 |
99.99% | 4分钟19秒 |
99.999% | 26秒 |
看到这里你就应该明白问题了。
99.999%听起来只是比99.99%多一个9,但允许故障时间直接从4分钟变成26秒。
这意味着什么?
意味着你可能为了这几十秒的可用性,去搞:
最后发现:
一年下来为了省几十分钟故障时间,花了几百万。
这时候 SLO 就不是工程指标了,而变成了烧钱指标。
所以我的观点非常明确:
SLO不是追求极限,而是在“用户体验、业务价值、工程成本”之间找一个最划算的平衡点。
这是很多团队最容易犯的错误。
比如一个电商系统。
有人问:
“我们电商平台 SLO 是多少?”
这个问题本身就不太对。
因为电商平台不是一个东西。
它可能包含:
用户登录
↓
商品搜索
↓
商品详情
↓
购物车
↓
创建订单
↓
支付
↓
库存扣减
↓
物流
↓
消息通知你告诉我整个系统:
SLO = 99.99%其实没什么意义。
因为:
用户根本不感知“整个系统”。
用户感知的是:
我能不能登录?
商品能不能搜到?
能不能下单?
钱扣了没有?
订单有没有生成?
所以复杂产品设计 SLO,第一步不是看 Kubernetes,也不是看 CPU。
而是:
比如一个电商系统,我可能这样设计:
登录:
可用性 99.9%
商品搜索:
可用性 99.95%
商品详情:
可用性 99.95%
创建订单:
可用性 99.99%
支付:
可用性 99.99%
推荐:
可用性 99%
消息通知:
可用性 99%你会发现一个很明显的规律:
不是所有服务都值得99.99%。
推荐系统挂了:
用户还能买东西。
支付挂了:
用户连钱都付不了。
这两个系统对业务的重要程度完全不同。
所以 SLO 应该体现业务价值。
一个接口:
HTTP 200就一定代表用户体验好吗?
当然不是。
假设商品详情接口:
99.99% 请求最终返回成功但是:
平均耗时 8 秒这时候你的监控可能告诉你:
系统非常稳定。
用户告诉你:
你这破网站打不开。
所以 SLO 至少应该考虑:
例如:
商品详情:
Availability SLO >= 99.95%
Latency SLO:
99% 请求 < 500ms
99.9% 请求 < 1s这里为什么不用平均值?
因为平均值特别容易骗人。
例如 1000 个请求:
990个请求:100ms
10个请求:10秒平均下来可能仍然看起来还不错。
但那 10 个用户已经骂完了。
所以线上 SLO 更应该关注:
P50
P90
P95
P99
P99.9尤其是用户体验敏感的接口。
这是 SLO 最有价值的东西之一。
假设:
SLO = 99.9%那么错误预算就是:
Error Budget = 1 - SLO
= 0.1%如果一个月产生:
10,000,000 次请求那么允许失败:
10,000,000 × 0.1%
= 10,000 次代码可以简单算一下:
def calculate_error_budget(total_requests, slo):
error_rate = 1 - slo
return int(total_requests * error_rate)
total_requests = 10_000_000
slo = 0.999
budget = calculate_error_budget(total_requests, slo)
print(f"允许失败请求数:{budget}")结果就是:
允许失败请求数:10000这时候 SLO 就不再是一个漂亮的百分比。
它变成了一个非常具体的问题:
这个月我们到底还有多少“犯错的额度”?
这就非常有意思了。
比如:
目标 SLO:99.9%
本月预算:
10,000 次失败
当前已经消耗:
2,000 次
剩余:
8,000 次那开发团队完全可以:
但是如果突然变成:
已经消耗:
9,800 次这时候还准备:
“今晚上线一个大版本。”
运维就应该站出来:
哥们,预算快没了。
甚至可以把发布策略直接自动化。
if error_budget_remaining < 0.1:
deployment_allowed = False
else:
deployment_allowed = True这时候 SLO 就真正进入了工程体系。
它不再是 PPT 上的一行字。
我的经验是:
不要从“我们想做到多少”开始。
而应该从:
“用户到底能接受多少?”
开始。
可以问业务三个问题。
比如:
支付
资金结算
订单创建
库存扣减这些通常优先级高。
比如:
推荐
搜索
消息通知
数据刷新用户重新点一次可能就好了。
这种场景通常不需要疯狂追求五个9。
比如:
在线支付失败
↓
还能货到付款
短信失败
↓
还能 App 推送
推荐挂了
↓
还能商品搜索有兜底,就意味着用户真实感知到的风险下降。
这时候 SLO 就可以相对宽松。
实际生产环境可以建立这样一个模型:
产品
│
┌────────┼────────┐
│ │ │
核心 重要 辅助
│ │ │
99.99% 99.9% 99%
│ │ │
支付/订单 搜索 推荐甚至可以进一步加入延迟。
例如:
services:
payment:
availability: 99.99%
latency_p99: 1000ms
order:
availability: 99.99%
latency_p99: 800ms
search:
availability: 99.95%
latency_p99: 500ms
recommendation:
availability: 99.0%
latency_p99: 2000ms这样一来:
SLO终于和业务发生关系了。
比如订单服务:
用户
↓
CDN
↓
Gateway
↓
Nginx
↓
Order API
↓
Redis
↓
MySQL
↓
MQ到底谁负责 SLO?
这是非常现实的问题。
如果你定义:
Order API 99.99%但 MySQL 挂了导致订单全部失败。
API 层可能认为:
请求正常进入了业务却认为:
订单根本没创建所以真正有价值的 SLO,应该尽量贴近:
用户能不能完成业务目标。
例如:
订单创建成功率比:
Order API HTTP 200比例更接近业务。
这个区别特别重要。
例如:
技术指标:
API Availability >= 99.95%
MySQL Availability >= 99.99%
Redis Availability >= 99.99%
Kafka Availability >= 99.99%看起来每个组件都很优秀。
但是业务指标:
订单成功率 = 99.5%那还是有问题。
为什么?
因为复杂系统不是简单的:
99.99% + 99.99% + 99.99%最后就等于 99.99%。
系统存在大量:
所以真正应该盯住的,是:
最终业务结果。
比如你的支付系统依赖第三方支付平台。
你自己的 SLO:
99.99%但第三方:
99.9%那你再怎么努力,也不可能轻松保证整个支付链路 99.99%。
所以这时候应该:
自己的服务 SLO
+
第三方依赖 SLO
+
降级能力
=
最终业务 SLO比如:
支付服务
│
├── 支付宝
│
├── 微信支付
│
└── 银行通道如果某一个通道挂掉:
自动切换其他通道那么最终用户体验可能仍然保持稳定。
这时候真正值钱的就不是:
“我们单个支付接口99.999%。”
而是:
“任何一个支付通道出问题,用户依然可以完成支付。”
这才叫架构能力。
我特别反对一种做法:
年初定一次 SLO,然后年底复盘一下。
这其实没有多大意义。
因为业务会变化。
比如:
刚上线:
99%
用户增长:
99.9%
成为核心业务:
99.95%
交易规模扩大:
99.99%SLO应该随着:
不断调整。
甚至可以做成自动报表:
服务 SLO 当前值 预算消耗
------------------------------------------------
支付 99.99% 99.995% 20%
订单 99.99% 99.97% 65%
搜索 99.95% 99.98% 30%
推荐 99.00% 99.95% 10%一眼就知道:
哪个系统真的危险。
以前我也觉得:
运维做好 SLO,就是把系统做到足够稳定。
后来才发现不是。
SLO真正解决的是“我们到底应该把时间和钱花在哪里”。
如果所有服务都要求:
99.99%那最后的结果很可能是:
开发不敢上线
运维不敢变更
架构越来越复杂
成本越来越高
业务越来越慢这其实也是一种失败。
真正成熟的团队应该敢于接受:
某些东西就是可以偶尔失败的。
推荐挂几分钟,也许没关系。
短信晚几秒,也许没关系。
后台报表慢一点,也许没关系。
但支付不能挂。
订单不能莫名其妙丢失。
用户已经付款,却不能查到订单,更不能接受。
所以我认为,一个好的 SLO 设计最终应该回答一句非常朴素的话:
“我们愿意为了什么体验,付出多少钱?”
如果这个问题回答清楚了,SLO 基本就不会离谱。
SLO从来不是:
99.9%
99.99%
99.999%这几个数字的游戏。
它背后其实是一个非常现实的工程问题:
用户需要什么?业务最怕什么?系统哪里最值得投入?
所以复杂产品设计 SLO,我建议按照这条路线走:
用户旅程
↓
核心业务
↓
SLI设计
↓
SLO分层
↓
Error Budget
↓
技术指标
↓
监控告警
↓
发布策略
↓
持续复盘最后送给运维同行一句我自己比较认同的话:
不要为了把系统做到99.999%,把整个团队搞成99.999%的痛苦。
真正优秀的 SRE,不是让所有系统都永远不出问题。
而是知道:
什么问题绝对不能出,什么问题出了可以接受,以及为了减少那一次故障,到底值不值得再投入一倍成本。
这,才是 SLO 真正的价值。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。