SLI、SLO、SLA 这三个词我在面试里问过不下五十个人能把三者关系说明白的不超过五个。更多人能背出全称——服务水平指标、服务水平目标、服务水平协议——但一到实际场景就露馅问他“你们系统的可用性是多少”回答“99.99%”再问“这个数怎么算出来的、窗口多长、分母是什么、超了会怎样”就开始支支吾吾。这三个词不是背概念用的它们分别对应“怎么量”“量到什么程度算合格”“不合格赔多少钱”三件完全不同的事混在一起谈团队就会陷入一种很典型的内耗运维说自己达标了产品说用户还在骂老板说合同要赔钱了三方用的是三套口径。我把这几年在几个项目里踩过的坑、写过的文档、压测现场翻过的车整理成这一篇。内容覆盖 SLI 怎么挑、SLO 怎么定数字、SLA 怎么签条款以及最容易被跳过但最要命的一环——压测实战里怎么把 SLI 真打出来、把 SLO 真验证掉。适合刚接手稳定性工作的同学也适合已经在写 SLO 文档但总觉得落地不了的人。全文用大白话讲配可抄的模板和脚本不玩概念。1. 先把三个词摆到桌面上它们到底各管什么1.1 一家餐厅的比喻一次讲清三者的位置我习惯用一家连锁餐厅来解释这三个概念比任何官方定义都直观。SLI 是服务员手里的记录本这一单从点单到上菜用了多少分钟、这一单有没有上错菜、这一单客人有没有投诉。它是观测到的事实是数字不带任何感情色彩。记录本上写“今天 100 单里有 96 单在 30 分钟内上齐”这就叫 SLI。SLO 是店长给自己定的内部规矩“我们要求 95% 的订单 30 分钟内上齐”。注意这条规矩是给自己看的是团队内部的努力方向。它比现状略高一点够得着但不轻松用来驱动改进。店长每天早上看记录本发现昨天只有 93%就知道后厨出问题了得去查。SLA 是跟外卖平台签的那份合同“月度准时率低于 90%每单赔 5 元”。它有外部对象、有赔付条款、有法律或商务后果。合同一旦签了就不是“努力方向”了是“必须守住的红线”。三者串起来是一条因果链用 SLI 观测现实用 SLO 管理期望用 SLA 约束商业风险。缺了 SLISLO 就是拍脑袋缺了 SLOSLA 就是裸奔缺了 SLASLO 就没有商业抓手做着做着就成了运维自娱自乐的报表。这里有个特别容易被搞反的地方我早年就栽过对外承诺的 SLA必须比内部追求的 SLO 更宽松中间要留缓冲。当时我们内部 SLO 定 99.9%转头跟客户签 SLA 也写 99.9%觉得“一致才显专业”。结果那个月一次计划内变更抖了三分钟内部刚好踩线达标对外却已经违约商务那边追着我们出说明。后来才明白SLO 是“我要做到的水平”SLA 是“我承诺不低于的水平”前者必须留出余量兜住意外顺序不能倒。1.2 一张表把三者的差异钉死概念讲多了容易糊直接上对照表。这张表我一般会放在团队文档的第一页新人进来先看这个。维度SLI指标SLO目标SLA协议本质一个可测量的数字给这个数字设的合格线带后果的对外承诺面向对象工程团队自己工程团队 产品客户、合作方、商务典型形式“成功请求占比 99.93%”“30 天滚动窗口内不低于 99.9%”“月度可用性低于 99.5% 按比例返还”违反后果无只是事实冻结发布、复盘、投入资源赔付、信用受损、合同风险谁来定研发/运维研发 产品 业务商务 法务 技术变更频率随架构变几个月一次季度评审一年或按合同周期严格程度事实最严内部追求最松对外保底看最后一行这就是最容易搞反的地方。很多团队把 SLA 写得比 SLO 还狠等于自己给自己挖坑——内部还没跑稳就对外承诺高标准后面所有精力都花在“解释为什么没达标”上而不是“怎么变好”。1.3 三个高频混淆点逐个拆掉混淆一把资源指标当 SLI。CPU 使用率 85%、内存占用 70%、磁盘 IO 很高——这些是资源指标不是 SLI。它们能解释“为什么慢”但不能回答“用户有没有受影响”。一台机器 CPU 打满但请求照样 20ms 返回用户根本无感反过来 CPU 只有 30%但数据库锁等待把 P99 拖到 2 秒用户已经在骂了。SLI 必须站在用户视角从请求入口统计资源指标是排查时的辅助线索。混淆二把 SLO 当成一个孤零零的百分数。“我们 SLO 是 99.9%”这句话信息量为零。完整的 SLO 是四件套指标定义 阈值 统计窗口 统计口径。同样是 99.9%“按自然月、按请求数、剔除健康检查、剔除 4xx 客户端错误”和“按滚动 7 天、按分钟采样、不剔除任何流量”算出来的结果能差出两个数量级。只报数字不报口径等于没说。混淆三把 SLA 当技术文档。SLA 是要给商务和法务看的里面每一条都会被拿去当证据。写“系统应保证高可用”这种话等于没写因为“高可用”无法度量写“可用性不低于 99.9%”就必须同时写清“可用性怎么算、数据谁提供、争议怎么处理”否则真出事时双方各拿一份数据谁也说服不了谁。2. SLI 怎么挑能采集到不等于该采集2.1 一个好 SLI 必须同时满足三个硬条件我筛 SLI 有个很土的办法拿三个问题去问全过才算合格。第一问它是不是从用户视角出发的用户关心的是“我点了按钮页面多久出来、有没有报错”不关心你内部调了几个服务、走了几层网关。所以 SLI 的采集点应该尽量靠外——入口网关、负载均衡层的位置最合适。你在某个内部微服务上埋点算成功率那个服务 99.99% 漂亮得很但上游网关超时把请求掐了用户照样看到白屏这个 SLI 就是自欺欺人。第二问好和坏能不能一刀切开好的 SLI 判据清晰不需要争论。“请求耗时小于 500ms”就是清晰的“响应比较快”就没法用。有些指标天生模糊比如“页面加载体验”就得先定义成一个硬阈值比如“首屏渲染完成时间小于 2 秒的请求占比”才能拿来当 SLI。第三问能不能按窗口聚合成比例SLI 最终的用法是“在某个时间窗口内好事件占总事件的百分比”。所以它必须是可计数的总请求数、成功请求数、快请求数、慢请求数。如果某个指标只能看瞬时快照聚合不出比例那它更适合当监控告警项而不是 SLI。三个问题过完你会发现很多“看起来很重要”的指标被淘汰了这很正常。SLI 数量贵精不贵多一个服务三到五个足够多了反而没人看。2.2 常见服务类型的 SLI 参考清单不同类型的服务用户疼的地方不一样SLI 的选法也不一样。下面这张表是我这几年攒下来的新项目起步可以直接照抄再微调。服务类型推荐主 SLI辅助 SLI不建议当主 SLI 的指标同步 HTTP 接口成功请求占比非 5xx 且非超时快请求占比P90 阈值平均响应时间、CPU 使用率异步消息消费消息处理成功占比端到端延迟入队到落库 阈值占比队列堆积条数只作告警数据库/存储读写成功占比慢查询占比 100ms连接数、缓存命中率定时批处理任务按时完成占比单批次处理时长机器负载前端页面首屏可用占比无白屏、无报错接口错误率、资源加载失败率PV、UV文件/图片处理处理成功占比处理时长分位值磁盘剩余空间注意“不建议”那一列这些指标不是没用而是不能当主 SLI。它们是诊断工具出问题时帮我们定位但不能用来衡量“用户是否满意”。把资源指标写进 SLA 更是灾难因为资源占用高不等于服务不可用客户不会为你的 CPU 买单。2.3 分母陷阱窗口、剔除和那个最会骗人的平均值这一节是我最想强调的因为踩过的坑最多。先说窗口。同样一次持续 3 分钟的抖动用 1 分钟粒度采样会看到 3 个红点视觉上很刺眼用 1 小时聚合那 3 分钟被稀释到 5% 的权重里几乎看不出来。所以窗口的选择直接决定“你有多容易发现问题”。我的经验是两层窗口并用长窗口7 天或 30 天看趋势、算 SLO 达成率短窗口1 分钟或 5 分钟做告警触发。只用一个窗口要么太钝要么太吵。再说剔除。分母里塞进不该算的流量成功率会虚高得离谱。最典型的是健康检查流量负载均衡每分钟探测一次一天就是 1440 次全是 200安安静静躺在分母里把一个真实成功率 98% 的服务“拉”到 99.5%。还有4xx 客户端错误用户传错参数、爬虫乱扫接口这些不该算服务端失败但也不能随手全剔——要区分“用户自己的错”和“我们的接口设计有问题导致的错”。我的做法是维护一张明确的剔除清单写进 SLO 文档谁都能查到剔了什么、为什么剔。最后说平均值这个指标最会骗人。举个真实算过的例子100 个请求95 个耗时 20ms5 个耗时 3 秒。平均值 (95×20 5×3000) / 100 169ms。169ms 看起来岁月静好但实际情况是 5% 的用户在骂娘。所以延迟类的 SLI 一律用分位值或达标占比永远别看平均值。我们内部有条不成文的规矩谁在汇报里写“平均响应时间”谁请全组喝咖啡。2.4 埋点位置与采集成本别把自己埋进坑里采集点放哪里直接决定成本。入口层采集成本最低一次埋点覆盖所有下游标签也简单接口名、状态码、耗时。服务内部采集定位最准但成本高每个服务都要改代码而且标签维度一多就会出现高基数问题——比如把用户 ID、订单号当标签打进去指标条数瞬间爆炸存储直接被打穿。我一般的策略是两层埋点各司其职入口层算 SLI 和 SLO这是“对外口径”服务内部埋点只用于问题定位不作为达标判定依据样本可以采样、可以有损。这样既保证了 SLO 数据的权威性又不至于让存储成本失控。还有个细节埋点必须带一致的接口标识。我见过一个项目网关层叫/api/v1/order/create服务内部叫/orderCreate两边对不上做归因分析时全靠人工猜效率极低。定 SLI 之前先把接口命名规范对齐这一步花半天后面省几十个小时。3. SLO 怎么定从“我要 99.99%”到能落地的数字3.1 错误预算把百分比翻译成“每月能坏多久”盯着 99.9% 这种数字没感觉得翻译成时间。计算方法很简单月停机预算 30 天 × 24 小时 × 60 分钟 × (1 - SLO)。按 30 天算一个月是 43200 分钟。SLO每月允许不可用时长每天允许直观感受99%432 分钟7.2 小时约 14.4 分钟一个月能坏半天多99.5%216 分钟3.6 小时约 7.2 分钟一次大故障就用完99.9%43.2 分钟约 1.4 分钟一次变更抖动就吃掉一半99.95%21.6 分钟约 43 秒基本不能有主动故障99.99%4.32 分钟约 8.6 秒一次自动重启就超了看完这张表很多“我要 99.99%”的诉求会自己收回。因为每多一个 9代价是成倍的多机房、多副本、灰度发布、自动化回滚、7×24 值守全得跟上。我在一个项目里算过从 99.9% 提到 99.99%机器成本涨了约 1.8 倍人力投入接近翻倍。所以定 SLO 的正确姿势不是“越高越好”而是算清楚每提升一个 9 能带来多少业务收益值不值这个钱。请求口径也一样。总请求 1 亿次SLO 99.9%意味着允许 10 万次失败。10 万次听起来很多但如果这些失败集中在某个爆款活动的前 10 分钟用户体验的伤害是灾难级的。所以光看总预算不够还得看预算消耗速度——这就是所谓的燃烧率如果按均匀速度消耗一个月 43.2 分钟的预算每小时只能烧掉约 1.44 分钟如果某一小时烧掉了 15 分钟那燃烧率就是 10 倍以上必须立刻介入。多窗口燃烧率告警就是基于这个逻辑长窗口1 小时或 6 小时判断“是否真的在快速失血”短窗口5 分钟判断“是否还在持续”两个都满足才发告警能有效压掉抖动误报。3.2 用压测数据倒推容量再回头校准 SLOSLO 不是拍出来的得用容量数据托底。推算链路是这样的第一步估峰值 QPS。拿历史数据看日常峰值再乘活动系数。比如日常峰值 800 QPS大促预估流量翻 1.5 倍那目标峰值就是 1200 QPS。这个系数别怕保守宁可多留。第二步定冗余系数。单副本挂掉、机房抖动、突发流量都得靠冗余兜。我一般取 1.5 到 2.0核心链路取高值。第三步用压测找单实例拐点。这个最关键。阶梯加压观察 P99 和错误率找到“P99 还在阈值内、错误率还没抬头”的那个最大 QPS这就是单实例安全容量。假设某接口实测在 P99 ≤ 200ms 下单实例能扛 300 QPS。第四步算实例数。需要承载 1200 × 1.6 1920 QPS1920 / 300 6.4向上取整 7 个再考虑挂一个实例不影响加 1 个最终 8 个。这就是 SLO 背后的容量依据。第五步反推 SLO 是否成立。如果压测发现8 个实例下 P99 已经到了 350ms而 SLI 阈值定的是 200ms那说明要么降 SLO要么加机器要么优化代码。三种选择都行但必须选一个不能装看不见。这里还有一个很多人忽略的换算并发数与 QPS 的关系。按小定律并发 ≈ QPS × 平均响应时间秒。目标 2000 QPS、平均 RT 50ms所需并发约 100。压测工具的并发数如果按这个算往往比“拍脑袋开 1000 并发”靠谱得多后者只会把被测服务打成一锅粥测出来的数据毫无参考价值。3.3 分层定 SLO核心链路和边缘功能不该一个标准把所有功能都定成 99.95%是最常见的偷懒做法也是最贵的做法。我一般按业务影响分三档层级典型功能建议 SLO理由核心链路登录、下单、支付、扣款99.95%挂了直接损失钱和口碑重要功能商品详情、购物车、订单查询99.9%影响体验但可短暂降级边缘功能评论、推荐位、历史浏览99.5%挂了页面还能用异步任务报表生成、数据同步99%按天延迟可容忍不阻塞交易分层的好处是可以把有限的资源投在刀刃上。核心链路该多机房就多机房边缘功能老老实实单机房加降级开关出了问题一键关掉用户甚至感知不到。3.4 一份可以直接抄的 SLO 文档结构SLO 文档别写成散文用结构化格式谁都改得动、看得懂。service: order-create owner: 交易组 version: 2024-06 slis: - name: availability definition: 入口网关统计的订单创建请求中返回非 5xx 且未超时3s的占比 source: gateway_access_log exclusions: - 健康检查流量path/healthz - 参数校验失败4xx且错误码属于 CLIENT_* - name: latency definition: 订单创建请求耗时 500ms 的占比 source: gateway_access_log note: 按分位值统计不看平均值 slos: - sli: availability target: 99.95% window: 30d rolling budget_minutes: 21.6 - sli: latency target: 99.0% window: 7d rolling alerts: - type: burn_rate long_window: 1h short_window: 5m threshold: 14.4 action: 通知值班并冻结发布 review_cycle: 每季度注意exclusions和note这两栏很多人写 SLO 文档会漏掉结果半年后没人记得当初剔了什么流量口径彻底失传。文档里写清“剔了什么、为什么剔”比写“目标 99.95%”重要得多。4. SLA 怎么签把工程指标翻译成合同语言4.1 一份可执行的 SLA 至少要有四个条款我见过太多 SLA 只有一句话——“系统可用性不低于 99.9%”——这种协议在真出事时几乎无法执行。一份能落地的 SLA至少要包含四块内容。第一块是指标与统计口径。用什么指标可用性、成功率、响应时间、什么窗口自然月还是滚动 30 天、按什么单位统计按分钟、按请求数、按接口加权、哪些情况不计入计划维护窗口、客户侧网络问题、不可抗力。这四件事写不全后面必有争议。第二块是测量方法与数据来源。数据从哪来、由谁提供、采样频率多少。我一般主张双方共同认可的第三方探针 服务方自身的网关日志双轨并行日常以服务方数据为准出现争议时以探针数据为准。这条写清楚能省掉 90% 的扯皮。第三块是排除项。计划内维护提前 72 小时通知的、客户侧配置错误、客户自有网络故障、超出约定流量上限的部分这些都应该明确排除。不写排除项等于把所有不确定性都揽到自己身上。第四块是赔付方式。按未达标幅度分档返还服务费或者延长服务期。这里有个细节必须设赔付上限一般是当月服务费的某个比例。没有上限的赔付条款签的时候手都在抖。4.2 缓冲怎么留SLO 和 SLA 之间那道安全垫前面说过 SLA 要比 SLO 宽松具体留多少我的经验值是至少半个 9 的差距也就是 SLO 99.95% 对应 SLA 99.9%SLO 99.9% 对应 SLA 99.5%。这个缓冲的作用是当内部 SLO 已经在红线附近挣扎时对外还有一层空间不至于立刻违约。缓冲还能倒逼流程。内部一旦触发 SLO 告警但还没到 SLA 违约线这就是最后的机会窗口——发布冻结、资源加派、根因排查全都在这段时间里做。等踩到 SLA 线才动手赔钱已经是既成事实了。还有个更细的做法把缓冲期做成台账。每次接近 SLO 上限就记录一笔季度评审时看这些记录能明显看出哪块系统的余量在变薄提前扩容比事后救火便宜得多。4.3 统计口径的四个隐形雷区雷区一自然月 vs 滚动 30 天。自然月对客户友好每月重新开始算但对服务方不友好——2 月只有 28 天预算天然少一截而且月末冲量时出问题影响会被放大。滚动 30 天更平滑但客户不容易理解。我一般对外用自然月对内用滚动窗口两套口径各自服务于不同目的。雷区二按分钟算 vs 按请求算。按分钟算这一分钟内有失败就算这一分钟不可用对低频接口极不友好——一天只有 100 个请求的接口一次失败就等于那一分钟全黑月度可用性直接掉一大截。按请求算更公平但对高频接口又太宽松。我的做法是高频接口按请求算低频接口按分钟算并且在 SLA 里写清楚分界线。雷区三谁来判定“不可用”。是接口返回 5xx 算还是响应时间超过阈值也算这两者的差别巨大。很多协议只写“不可用”实际执行时才发现双方理解不同。必须在协议里给出明确的判定规则最好附几个例子。雷区四争议期与举证责任。出问题后多久内提出异议有效谁负责举证我一般会写“客户应在事件发生后 15 个工作日内提出逾期视为认可服务方数据”。这条看着像法律条文实际作用很大——能把半年后突然翻旧账的情况挡掉。4.4 对外承诺前的自检清单签 SLA 之前我通常会走一遍这个清单任何一项打不了勾就不签。核心链路的 SLI 已经连续观测满 3 个月数据稳定口径无争议内部 SLO 比 SLA 至少严格半个 9且有台账记录余量变化压测验证过峰值流量 × 冗余系数下SLI 仍能达标有明确的降级方案和熔断开关且演练过至少一次排除项、赔付上限、争议期三项条款已由商务和法务确认数据来源双方认可探针部署完成并比对过结果最后一条特别重要。我见过一次签完合同才发现双方用的探针部署在不同区域网络路径都不一样测出来的可用性差了 0.3 个百分点光对齐口径就开了三次会。这种事前置成本极低后置成本极高。5. 压测实战把 SLI 打出来把 SLO 验证掉5.1 压测之前必须想清楚的三件事压测最容易犯的错是“上来就打”打完拿一堆曲线不知道说明什么。开打之前有三件事必须先定下来。第一压测目标是什么。是验证容量能不能扛住大促峰值、验证稳定性连续跑 8 小时有没有内存泄漏、还是验证降级方案挂掉一个副本会怎样目标不同场景设计完全不同。我一般把目标写成一句话贴在群里比如“验证订单创建接口在 2000 QPS 下 P99 不超过 500ms连续 2 小时错误率低于 0.1%”。第二流量模型是什么。真实流量不是均匀的。下单接口的读写比、接口之间的调用比例、用户行为的分布都得尽量还原。最常见的错误是用单一接口打满测出来的容量漂亮一上混合链路立刻崩——因为数据库连接池、线程池这些共享资源在混合场景下争抢激烈得多。第三环境是不是隔离的。压测环境混着别人的服务测出来的数据一文不值。至少要做到独立的数据库实例、独立的缓存、不共用消息队列。做不到完全隔离就在低峰期压并在报告里注明污染风险。5.2 场景设计从单接口到混合链路的三级递进我的习惯是分三级压每级都有明确的产出。第一级单接口基线。只压一个接口阶梯加量找到这个接口的单实例拐点。产出是“单实例安全容量”这个数后面算实例数全靠它。这一级最重要的不是峰值数字而是拐点前后的形态什么时候 P99 开始抬头、什么时候错误率开始爬升、两者是不是同步。如果 P99 先抬、错误率不涨说明是慢查询或锁等待如果错误率先涨、P99 还好多半是连接池耗尽或者限流生效。第二级混合链路。按真实调用比例混合多个接口比如下单 30%、查询 50%、其他 20%。这一级能暴露共享资源争抢问题也是最能反映真实情况的。很多问题在这一级才出现单接口压的时候缓存命中率 95%混合压之后降到 70%因为不同接口的数据互相挤占。第三级故障注入。在混合链路跑着的时候随机摘掉一个实例、制造一次数据库主从切换、模拟一次下游超时。这一级验证的是降级和容错是否真的有效以及 SLO 在故障期间还能不能守住。我见过不止一次降级开关写了但从来没测过真出事时一按下去返回的数据结构不兼容前端直接崩。5.3 压测中盯什么三个必须实时看的指标压测过程中屏幕上至少要同时挂三块东西。第一块是成功率曲线。掉头向下的那一刻就是拐点。注意要区分 5xx、超时、连接拒绝这三者的含义完全不同5xx 是服务端处理出错超时是处理太慢连接拒绝是根本连不上端口、连接数、文件描述符。我有一次压测看到成功率突然掉到 60%第一反应是代码有问题查了半天发现是压测机自身的文件描述符上限到了虚惊一场。第二块是 P99 / P999 曲线。只盯平均值会错过所有信号。P99 抬头往往比错误率上涨早几分钟是最好的预警。如果 P99 从 100ms 缓慢爬到 300ms 而错误率还没动说明系统已经在排队了再加一点量就会雪崩。第三块是被压服务的资源水位。CPU、内存、连接池占用、线程池活跃数、GC 次数。这一块的作用是建立因果链成功率掉了是因为连接池满了连接池满了是因为某个慢查询占住了连接慢查询是因为索引没走对。有了这条链优化才有方向。还有个小技巧压测时把下游依赖的调用耗时也打出来。很多时候压力测试里被测服务本身很健康但下游某个接口从 20ms 变成 200ms把整条链路的 P99 拖垮了这时候优化被测服务毫无意义。5.4 一份可以改改就用的压测脚本骨架下面这个用 Python 标准库写的骨架不依赖第三方包适合快速验证小流量场景。核心是三件事阶梯加压、按窗口统计、输出分位值。import time, statistics, threading, urllib.request, urllib.error from concurrent.futures import ThreadPoolExecutor TARGET http://127.0.0.1:8080/api/order/create DURATION 60 # 每个档位持续秒数 STEPS [50, 100, 200, 400, 800] # 并发档位 TIMEOUT 3 # 超时阈值与 SLI 定义的阈值保持一致 def one_call(): start time.perf_counter() ok False try: req urllib.request.Request(TARGET, datab{sku:1,qty:1}, headers{Content-Type: application/json}) with urllib.request.urlopen(req, timeoutTIMEOUT) as resp: ok 200 resp.status 300 except Exception: ok False cost (time.perf_counter() - start) * 1000 return ok, cost def run_step(concurrency): results [] lock threading.Lock() deadline time.time() DURATION def worker(): while time.time() deadline: r one_call() with lock: results.append(r) with ThreadPoolExecutor(max_workersconcurrency) as pool: for _ in range(concurrency): pool.submit(worker) total len(results) success sum(1 for ok, _ in results if ok) costs sorted(c for _, c in results) p lambda q: costs[min(int(len(costs) * q), len(costs) - 1)] if costs else 0 qps total / DURATION print(f并发{concurrency:4d} QPS{qps:8.1f} 成功率{success/total*100:6.2f}% fP50{p(0.50):7.1f}ms P95{p(0.95):7.1f}ms P99{p(0.99):7.1f}ms f慢请求占比{(1 - sum(1 for c in costs if c 500)/total)*100:5.2f}%) if __name__ __main__: for step in STEPS: run_step(step) time.sleep(10) # 档位之间留冷却避免上一档的排队效应污染下一档几个实操要点冷却时间不能省上一档积压的请求会在下一档开头集中释放导致数据失真超时阈值必须和 SLI 定义一致否则算出来的“慢请求占比”和 SLO 口径对不上输出里要同时给 QPS、成功率、分位值、慢请求占比因为这四个数要一起看才能判断拐点。这个脚本适合几百 QPS 以内的验证再往上压测机自身会成为瓶颈那时候得换分布式压测方案思路是一样的。5.5 压测报告怎么写才能支撑 SLO一份能拿去做 SLO 决策的压测报告至少要回答四个问题。第一单实例安全容量是多少。给出具体数字和判定依据“P99 ≤ 200ms 且错误率 0.1% 的前提下单实例最大承载 300 QPS”。第二满足目标峰值需要几个实例。把计算过程写出来别只给结论。目标峰值 × 冗余系数 / 单实例容量向上取整再加故障冗余。第三拐点在哪里超过会怎样。描述拐点前后的形态变化比如“超过 320 QPS 后 P99 从 180ms 跳到 900ms错误率从 0.02% 涨到 4%说明瓶颈在线程池”。第四有哪些风险项和未验证项。诚实写出“本次未验证数据库主从切换场景”“压测环境缓存未隔离”这类限制比写一堆漂亮结论有用得多。6. 常见问题与排查实录6.1 一张速查表覆盖八成疑问现象可能原因排查方向SLO 长期 100%从不告警SLI 口径太宽或分母混入健康检查查剔除清单、查采样粒度用户投诉多但 SLI 漂亮SLI 采集点太靠内未覆盖入口超时把采集点前移到网关压测 QPS 上不去CPU 却不忙压测机瓶颈或连接数限制查压测机资源、查文件描述符P99 突然翻倍但错误率不变慢查询、锁等待、GC 停顿查下游耗时、查 GC 日志混合压测比单接口差很多共享资源争抢连接池、缓存分开看各接口命中率与等待时间故障注入后降级没生效开关未演练、返回结构不兼容定期演练校验降级返回SLA 到期前突然“数据对不上”双方探针口径不一致提前双轨比对写清争议条款6.2 五个真实踩过的坑坑一把平均值写进 SLO。早期我们的 SLO 写的是“平均响应时间 200ms”结果系统在长尾请求上烂得一塌糊涂平均值依然很好看。改成“P99 500ms 的占比 ≥ 99%”之后问题立刻暴露出来也才有了后来的优化方向。坑二压测环境带缓存预热数据虚高。第一次压测前先跑了十分钟预热缓存全热测出来的容量比生产高 40%。上线后第一批冷请求打进来数据库直接被压垮。后来规定压测必须包含冷启动场景或者明确标注“本次为热缓存数据”。坑三SLA 没写排除项。一次计划内数据库升级提前发了通知但因为 SLA 里没写排除条款客户照样要求按比例返还。金额不大但流程上非常被动。从那以后排除项成了必填栏。坑四燃烧率告警设太灵敏。一开始用 5 分钟窗口、2 倍燃烧率就告警结果每天几十条值班同学直接屏蔽。后来改成双窗口1 小时 5 分钟、14.4 倍阈值告警量降到每周一两条每一条都是真问题。坑五SLI 埋点漏了异步回调。下单接口本身成功率 99.98%但支付回调的成功率只有 97%两边的 SLI 分开看都还行合起来看用户体验是断的。教训是SLI 要覆盖完整业务闭环不能只盯着第一个接口。6.3 复盘怎么做才不流于形式出问题之后的复盘我坚持三条规矩。第一只看时间线不追责。从第一个异常信号出现到发现、到定位、到恢复每一分钟在做什么全部写清楚。追责会让所有人开始保护自己信息就断了。第二一定要落到 SLI 上。这次故障影响了哪个 SLI、损失了多少错误预算、距离 SLO 红线还剩多少。用预算说话比用“影响很大”说话有说服力得多。第三产出必须是可验证的动作。“加强监控”不是动作“在网关层增加回调接口的失败率告警阈值 1%5 分钟窗口”才是动作。而且要有负责人和截止时间下次复盘先检查上次的动作有没有做完。我在实际项目里的体会是SLI、SLO、SLA 这三样东西最难的不是定义是坚持用同一套口径说话。口径一旦漂移所有数据都会失去可比性团队就会退回到“我觉得还行”的讨论里。所以我现在做任何稳定性相关的评审第一个问题永远是这个数字是怎么算出来的窗口多长分母是什么。答不上来后面的话就不用听了。