面试 · 概念解释型
目标:考察对 SRE 核心概念的精确理解和清晰表达能力。每题回答控制在 3-5 分钟。 答题框架:是什么 → 为什么需要 → 如何落地(视题目类型选用适用步骤)。
1. 什么是 SRE?它与传统运维的本质区别是什么?#
参考答案:
是什么:SRE(Site Reliability Engineering)是 Google 创立的用软件工程方法解决运维问题的实践体系。核心定义:让软件工程师来设计运维团队("SRE is what happens when you ask a software engineer to design an operations team")。
为什么需要:传统运维靠线性加人应对规模增长,成本不可持续。SRE 通过自动化和量化管理,让运维工作量与系统规模解耦——系统扩大 10 倍,运维工作不随之 10 倍增长。
如何落地:三个核心实践:
- 运维工作 ≤ 50%:SRE 至少一半时间做工程,不是操作
- SLO 量化可靠性:用 SLI/SLO/Error Budget 替代"尽量不出事"
- 自动化优先:宁可花 10 小时写工具,也不花 5 分钟做第 10 次手动操作
与传统运维的本质区别:
| 维度 | 传统运维 | SRE |
|---|---|---|
| 工作方式 | 手动操作、凭经验 | 写代码自动化、数据驱动 |
| 可靠性目标 | "尽量不出事" | 精确定义 SLO + 错误预算 |
| 发布态度 | 阻碍发布 | 用数据决定能不能发 |
| 工作内容 | 100% 运维操作 | ≤50% 运维 + ≥50% 工程 |
| 事故处理 | 救火→修好→忘了 | 救火→复盘→Action Items 闭环 |
2. 什么是 SLI?举例说明常见的三类 SLI。#
参考答案:
是什么:SLI(Service Level Indicator)是服务质量的具体测量值,必须站在用户视角。判断标准:这个指标变差时用户会察觉到吗?改善时用户会受益吗?都是"是"才是合格 SLI。
为什么需要:没有 SLI,可靠性就是"凭感觉"——"最近好像不太稳"。SLI 把可靠性变成可度量、可对比、可追溯的数字。
如何落地:三类核心 SLI:
- 可用性 SLI:成功请求 / 总请求。good = 2xx + 3xx;5xx、429、499、超时计失败,纯客户端 4xx(400/404)通常豁免(详见下方"关键判断")。
- 延迟 SLI:请求响应时间的分位数(P95/P99/P999),不用平均值——平均值掩盖长尾。
- 错误率 SLI:失败请求 / 总请求。需明确什么算失败——5xx、网关超时(504)、429 限流、499 客户端超时断连都必须算失败。
PromQL 示例:
# 可用性:good = 2xx + 3xx
sum(rate(http_requests_total{status=~"2..|3.."}[5m])) / sum(rate(http_requests_total[5m]))
# 延迟 P99
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, job))关键判断:4xx 是否计入失败分母? 429(限流)、499(客户端断连)、以及网关超时必须算失败——它们说明服务确实没接住请求。而纯客户端错误(400 参数错、404 路径不存在)通常豁免:从分子分母同时剔除,避免用户乱敲 URL 拉低你的 SLI。切忌用 status!~"5.." 这种写法——它把 429、4xx 全当成功,和"429 算失败"的口径自相矛盾。
反面例子:CPU 使用率、内存占用、Pod 重启次数是系统指标,不是 SLI——它们不直接反映用户体验。
3. 什么是 SLO?为什么不能设 100%?#
参考答案:
是什么:SLO(Service Level Objective)是给 SLI 定的目标值,如"月度成功率 ≥ 99.9%""P99 延迟 ≤ 500ms"。SLO 是 SRE 和业务方共同协商的结果——略高于用户期望、略低于系统能力上限。
为什么不能 100%:
- 成本指数增长:每增加一个九,成本通常翻 3-5 倍(99.9%→99.99% 需要多活架构、严格发布流程)
- 边际收益递减:99.99% 和 99.999% 用户几乎感知不到差异
- 阻碍创新:追求 100% 意味着不敢变更,系统变化石
- 客观不存在:硬件、网络、DNS 依赖链任何环节都可能出问题
- 错误预算是创新空间:允许失败 = 允许尝试
如何落地:
- 先看用户期望(支付 vs 内部工具不同)
- 再看历史数据(过去 3 个月实际水平)
- 计算成本(每提高一个九的工程投入)
- 用数字沟通("每月允许 43 分钟不可用"比"99.9%"更直观)
4. 什么是 SLA?SLA 和 SLO 的关系是什么?#
参考答案:
是什么:SLA(Service Level Agreement)是在 SLO 基础上叠加法律/商业后果的正式协议。未达标通常涉及赔偿(服务信用、退款、违约金)。
为什么需要:对外服务需要有明确的承诺和违约责任,让客户有信心使用。SLA 是商业合同的一部分。
如何落地:
- SLO 是内部目标(紧,如 99.95%)
- SLA 是对外承诺(松,如 99.9%)
- 中间的差距(0.05%)是 SRE 的操作缓冲空间
- SLA 不可等于 SLO——否则 SLO 一破就要赔付,没有容错余地
SLA 设计要点:
- 信用额度而非现金赔付(避免法律复杂性)
- 明确排除项(计划内维护、不可抗力)
- 连续多月未达标有升级条款(允许客户无罚金解约)
- 度量方法可被客户独立验证
5. 什么是 Error Budget?它是如何计算的?#
参考答案:
是什么:Error Budget(错误预算)= 1 - SLO。它把"可靠性"从一个模糊概念变成精确的数字决策工具。
如何计算:以月度 SLO 99.9% 为例:
Error Budget = (1 - 0.999) × 30天 × 24h × 60min = 43.2 分钟/月
即每月允许 43.2 分钟的"完全不可用时间"为什么需要:传统模式下"该不该发版"靠吵架,SRE 凭感觉拦,开发觉得被针对。Error Budget 让决策数据化:
- Budget 充足(>50%)→ 正常发布
- Budget 收紧(25-50%)→ 发布需 review
- Budget 紧张(10-25%)→ 仅修复性发布
- Budget 耗尽(<10%)→ 冻结发布,全员修稳定性
如何落地:
- 用 Prometheus Recording Rules 预计算预算消耗
- Dashboard 公开显示当前 Budget 余额
- 发布前检查 Budget,作为发布决策依据
- 季度回顾 Budget 消耗模式,调整 SLO
6. 什么是 Toil(琐事)?它和"不喜欢的工作"有什么区别?#
参考答案:
是什么:Toil 是 Google SRE 定义的精确概念,需同时满足六个特征:
- 手动:需要人执行
- 重复:不是一次性的
- 可自动化:技术上能被机器替代
- 无持久价值:做完后服务状态没有进步
- 操作型:执行性工作而非创造性
- 随规模线性增长(O(n)):工作量随服务规模至少线性增长——这是判定"必须消灭"的核心依据。不随规模增长的一次性重复劳动危害有限;随 n 增长的 toil 才会在扩容时把人吞掉。
为什么需要消除:Toil 是 SRE 工程时间的吞噬者。Toil > 50% 时 SRE 疲于救火,没时间做自动化,toil 永远减不掉,恶性循环导致人员离职。
如何落地:消除 toil 的优先级矩阵:
| 高频(每周 N 次) | 低频(每月 1-2 次) | |
|---|---|---|
| 简单(<1天自动化) | P0 立刻做 | P1 排期 |
| 复杂(>3天自动化) | P1 优先做 | P3 等迭代 |
不是 Toil 的例子:紧急故障响应(有持久价值且每次不同)、写 Runbook(有持久价值)、架构设计(创造性)。
7. 什么是四个黄金信号(Four Golden Signals)?#
参考答案:
是什么:Google SRE 提出的服务监控四维度,是"看任何一个系统的第一眼该看什么"的肌肉记忆:
- Latency(延迟):请求处理时间,用 P50/P95/P99 分位数,区分成功/失败请求
- Traffic(流量):请求量(QPS/RPS),是其他信号的分母
- Errors(错误):失败请求比例,区分显式错误(5xx)和隐式错误(200 但业务错)
- Saturation(饱和度):资源"有多满",强调剩余容量而非使用率
为什么需要:面对陌生服务,工程师能在 15 分钟内搭出"够用"的监控基线。四个信号覆盖了用户感知的所有维度。
如何落地:
- 每个新服务必须配齐四个信号的 Dashboard
- 排障时按"黄金信号 → RED 定位接口 → USE 排查资源"下钻
- 延迟用分位数不用平均,饱和度看 throttle 不看使用率
8. 什么是 RED 方法?它和 USE 方法的区别是什么?#
参考答案:
是什么:
RED(面向服务/请求驱动):
- Rate:每秒请求数
- Errors:失败请求比例
- Duration:请求延迟分位数
USE(面向资源/硬件):
- Utilization:资源使用率
- Saturation:排队等待的工作量
- Errors:资源错误事件
为什么需要两者:RED 覆盖服务层但不覆盖资源层(没有饱和度),USE 覆盖资源层但不覆盖请求层(没有流量)。两者互补才能形成完整的"服务+资源"监控。
如何落地:
- 每个微服务配 RED 面板
- 每个资源(CPU/内存/磁盘/网络)配 USE 面板
- 排障顺序:黄金信号发现异常 → RED 定位具体接口 → USE 排查底层资源
- USE 关注"队列长度"而非"使用率"——队列长度 > 0 才是真正的饱和
9. 什么是告警疲劳(Alert Fatigue)?怎么治理?#
参考答案:
是什么:告警疲劳是监控系统最危险的状态——告警太多太吵,工程师开始生理脱敏,真故障也被忽略。这不是"工程师不负责任",是人类的适应本能。
为什么需要治理:告警疲劳直接导致 MTTR 飙升。真故障发生时,值班人第一反应是"先观察 5 分钟看是不是误报",这 5 分钟可能是灾难性的。
如何落地:五步治理:
- 告警审计:每月 2 小时,Top 10 最频繁告警逐一 review
- 三层分流:Page(紧急)/ Ticket(工单)/ Log(仅记录)
- 症状型告警:page 级告警必须基于用户感受,不能基于 CPU/内存
- 每条 page 必须有 Runbook:没 Runbook 不能是 page
- 燃烧率告警替代简单阈值:多窗口 AND 逻辑减少误报
实战效果:一次告警审计通常能砍掉 50-60% 的无效 page。告警从 42 次/周降到 8 次/周后,真阳率从 35% 涨到 75%。
10. 什么是燃烧率(Burn Rate)?为什么需要多窗口?#
参考答案:
是什么:燃烧率 = 当前错误率 / (1 - SLO),即 Error Budget 消耗速度相对于正常速度的倍数。1x = 匀速达标,14.4x = 1 小时烧 2% 月度预算。
为什么需要多窗口:
- 单看短窗口(5min):毛刺多,误报频繁
- 单看长窗口(6h):真实故障已持续很久才发现
- 多窗口 AND 逻辑:短窗口确认"现在在出问题",长窗口确认"不是瞬时抖动"
如何落地:Google SRE Workbook 经典三档(针对 99.9% SLO / 30 天窗口,Table 5-8):
| 严重度 | 长窗口 | 短窗口 | 燃烧率 | 告警时已耗预算 |
|---|---|---|---|---|
| Page | 1h | 5m | 14.4x | 2% |
| Page | 6h | 30m | 6x | 5% |
| Ticket | 3d | 6h | 1x | 10% |
("已耗预算" = 燃烧率 × 窗口 / 30 天。14.4x 约 2 天烧光整月预算,1h 检测窗口触发时刚烧掉 2%;6x/6h 那档触发时烧掉 5%;1x/3d 那档触发时烧掉 10%。)
注意:Google 原表里 6x 也是 page(次紧急),1x 才是 ticket。很多团队把这三档映射成自己的 P0/P1/P2 通知层级(如把 6x 降为 ticket、1x 只上 Dashboard),这是结合本团队 on-call 承受度的调优选择,不要标成"Google 推荐"——标签说 Google、数值却不是 Google,是面试穿帮点。
为什么用 AND 不用 OR:OR 因短窗口抖动频繁触发;AND 要求两个窗口都确认问题,滤掉瞬时毛刺。
11. 什么是混沌工程(Chaos Engineering)?它的目标是什么?#
参考答案:
是什么:混沌工程是在受控条件下,通过主动注入故障来验证系统韧性假设的实验。
为什么需要:SLO 量化了可靠性的目标值,但没验证系统是否真能达到。没有混沌工程的 SLO 是"未经测试的承诺"。系统演进时韧性可能悄悄退化——代码改了、配置变了、依赖换了,不演练就不知道。
如何落地:核心特征:
- 假设驱动:每次实验都有明确假设(如"MySQL failover 时 P99 不超过 2s")
- 安全护栏:爆炸半径限制(mode: one)、自动回滚、时间窗口控制
- 复盘驱动:没复盘的演练等于没演练
- 场景库:积累 40+ 故障剧本,覆盖基础设施/Pod/网络/存储/中间件
目标不是"系统能扛",而是发现系统在哪儿没准备好——监控没接、告警没配、Runbook 过时。
12. 什么是 Blameless Postmortem?它的核心要素是什么?#
参考答案:
是什么:Blameless Postmortem(无指责复盘)是把事故分析的重点从"谁做错了"转向"系统为什么允许这个错误发生"。Blameless ≠ 不追责,而是把"人为什么会犯错"当成系统问题来分析。
为什么需要:如果组织文化里还有"谁的锅"这个问题,工程师不敢说真话,复盘就是表面文章,根因永远是"操作失误"。Blameless 让工程师敢说真话,才能找到真正的根因。
如何落地:核心要素:
- 时间轴:精确到分钟的事件序列
- 根因分析:直接原因 + 传播原因 + 触发条件
- 贡献因素:为什么检测/预防机制没起作用
- Action Items:必须有 Owner + Deadline,分五类(Fix/Prevent/Detect/Mitigate/Process)
- 运气成分:识别"这次没出事纯属运气"的因素
- 不写人名:全部用角色(IC/Ops Lead)
双层归因:不只问"什么坏了"(触发因素),更问"为什么没兜住/为什么是一类"(结构性缺陷)。
13. 什么是 Incident Commander (IC)?为什么 IC 不应该下场写代码?#
参考答案:
是什么:IC(事故指挥官)是事故响应的唯一指挥。职责是组织响应节奏、做重大决策、分配任务、主持定期通报。
为什么 IC 不能下场:
- IC 写代码的那一刻,群龙无首——没人做全局判断和协调
- IC 的核心技能是冷静 + 信息整合,不是技术深度
- IC 需要每 15 分钟产出状态摘要、判断是否需要升级、确认回滚路径安全——这些"指挥"工作已经占满带宽
- IC 下场 = 失去全局视角,响应节奏立即崩溃
如何落地:
- SEV-1/2 事故必须显式任命 IC
- IC 任命在事故频道置顶
- IC 只指挥,Ops Lead 负责执行
- IC 培养是长期投资,需要多次事故演练
14. 什么是 SEV 分级?SEV-1 和 SEV-2 的区别是什么?#
参考答案:
是什么:SEV(Severity)是事故严重级别的分级标准,决定响应节奏和资源投入。
SEV-1 vs SEV-2:
| 维度 | SEV-1 | SEV-2 |
|---|---|---|
| 影响 | 全站宕机/核心业务不可用/数据丢失/安全事件 | 单个核心功能不可用 |
| 用户范围 | >50% | 10%-50% |
| 响应 | 立即拉群,IC 上线,IMOC 通知高管 | 拉群,IC 上线 |
| Mitigation 目标 | 15 分钟 | 30 分钟 |
| 角色任命 | IC + Ops Lead + CL + IMOC | IC + Ops Lead + CL |
如何落地:
- 宁可高估不要低估——升级容易降级难
- 分级决定流程不决定责任——SEV-1 不等于谁写错了
- 有上升风险就升级——看起来 SEV-2 但可能变 SEV-1,直接按 SEV-1 处理
15. 什么是死机开关(Dead Man's Switch/Watchdog)?为什么必须有?#
参考答案:
是什么:死机开关是一条永远在触发的告警,反向使用:
- Watchdog 持续 firing → healthchecks.io 定期收到心跳
- 如果超过一定时间没收到心跳 → 整条告警链路(Prometheus → Alertmanager → 通知)自己挂了
- 触发反向告警
为什么必须有:监控系统自己死了没人知道是最危险的盲区。没有 Watchdog,"没有告警"可能意味着"一切正常",也可能意味着"告警系统挂了"——你无法区分。
如何落地:
- alert: Watchdog
expr: vector(1)
for: 0s
labels:
severity: none- Alertmanager 路由到独立 receiver(healthchecks.io)
- 反向告警通道必须独立于主告警通道(不同群、不同 webhook)
- 来自实战教训:5 套并行监控栈中只有 1 套有 Watchdog,其余 4 套完全暴露
16. 什么是症状型告警和原因型告警?为什么 page 必须是症状型?#
参考答案:
是什么:
- 症状型(好的):基于用户实际感受到的问题,如「Payment API 错误率 > 5%」
- 原因型(不好的):基于系统内部组件状态,如「Redis master pod 不可用」
为什么 page 必须是症状型:
- 遗漏率低:用户感知到的都能覆盖,不用穷举所有根因
- 噪声率低:只在用户真受影响时响,不会"Redis 挂了但 replica 接管了"也 page
- 可操作性强:收到就知道"服务有问题",不用推断
- 维护成本低:SLO 不变就不改告警
如何落地:原因型指标的归宿——不直接 page,但用在:
- Dashboard 面板(随时可看)
- 告警规则的子条件("错误率 > 5% AND CPU > 90%")
- 抑制条件(集群挂了抑制 pod 告警)
- Ticket 级告警(磁盘满、证书过期)
Google SRE 铁律:会 page 的告警必须是症状型。
17. 什么是渐进式发布?标准的分阶段灰度策略是什么?#
参考答案:
是什么:渐进式发布是把一次发布拆成多个小步骤,逐步扩大流量比例的发布策略。核心思想:即使有 bug,影响面有多小、恢复有多快。
为什么需要:70% 的生产事故与变更相关。全量发布 = 全量风险,渐进发布 = 局部风险。
如何落地:标准灰度流程:
- Stage 1:金丝雀 1-5%,观察 10-30 分钟
- Stage 2:扩大 10-25%,观察 15-30 分钟
- Stage 3:扩大 50%,观察 10-15 分钟
- Stage 4:全量 100%
每一步观察指标:
- 错误率:> 基线 3 倍 → 回滚
- P99 延迟:> 基线 2 倍 → 回滚
- SLO Burn Rate:> 14.4x → 自动回滚
- 业务指标:下降 > 5% → 回滚
灰度要按 user_id 固定路由(不是随机请求),观察窗口要足够长(覆盖延迟稳定时间)。
18. 什么是爆炸半径(Blast Radius)?#
参考答案:
是什么:爆炸半径是混沌工程中的安全概念,指一次故障注入实验影响的最大范围。
为什么需要:生产演练不能变成真事故。没有爆炸半径限制的演练,可能一次注入打挂整个服务,从"演练"变"事故"。
如何落地:原则是每次实验只影响最小单元:
| 级别 | 影响 | Chaos Mesh 配置 |
|---|---|---|
| Pod-level | 只 kill 一个 pod | mode: one |
| Node-level | 只影响一个 node | node selector 限定 |
| Service-level | 只对一个 service 注入 | label selector 限定 |
| Tenant-level | 只影响一个租户 | namespace 限定 |
配套安全机制:
- Stop-Loss 自动回滚(错误率 > 5% 持续 60s 立即终止)
- 时间窗口限制(只在工作日 14:00-16:30 演练)
- 审批和公告(演练前 2 天公告)
19. 什么是 SRE 的 50% Toil 上限原则?#
参考答案:
是什么:Google SRE 的硬性约束——每个 SRE 的 toil 工作时间不能超过总时间的 50%。这是 SRE 区别于传统运维最关键的机制设计。
为什么需要:
- Toil < 50% → 剩余 50%+ 投入自动化 → toil 减少 → 良性循环
- Toil > 50% → 疲于救火 → 没时间自动化 → toil 不减 → 恶性循环 → 人员离职
如何落地:超过 50% 的处理顺序:
- 削减告警:toil 最大来源是噪音告警,一次审计砍 50%+
- 自动化优先:高频 toil 先自动化
- 推回给研发:因代码质量导致的 toil 还给研发
- 增加人手:以上都做了仍超 50%,确实需要加人
Google 内部这条规则写到 SRE 绩效考核里:Toil > 50% 的团队需向 SRE Director 解释并给出削减计划。
20. 什么是责任共担模型?SRE 和研发各自负责什么?#
参考答案:
是什么:责任共担模型是 SRE 体系的组织基础——可靠性是研发和 SRE 的共同责任,不是 SRE 的单方面承诺。
为什么需要:如果可靠性全靠 SRE,研发没有动力写可观测的代码、做容量规划、参与 on-call。责任共担让研发对可靠性有"skin in the game"。
如何落地:分工边界:
| 责任 | SRE | 研发 |
|---|---|---|
| SLO 体系 | 建框架、搭工具 | 定义自己服务的 SLI,协商 SLO |
| 告警 | 维护基础设施 | 维护服务的告警规则和 Runbook |
| On-call | 基础设施层 | 应用层(自己的服务) |
| 发布 | 提供工具和 Budget 数据 | 决定发布策略和时机 |
| 复盘 | 主持复盘会 | 写复盘文档,执行 Action Items |
核心理念:"你 build 你 run"——研发对自己服务的可靠性负有第一责任。
21. 什么是可观测性(Observability)?它和监控的区别是什么?#
参考答案:
是什么:可观测性源自控制论——能否从外部输出反推系统内部状态。监控只能回答你提前想到的问题(known unknowns),可观测性要求系统能回答你没提前想到的问题(unknown unknowns)。
为什么需要:线上出了你从没预想过的故障,你能不能靠现有信号一路问到根因?能 = 可观测,不能 = 只是"有监控"。
如何落地:三支柱 + 关联键:
- Metrics 指标:便宜、可全量长留,回答"有多少/多快/多频繁"
- Logs 日志:贵但细,回答"这一次到底发生了什么"
- Traces 链路:微服务命根子,回答"哪一跳慢了"
- 关联键:trace_id 必须在三种信号里都存在,能从指标下钻到链路再下钻到日志
三支柱不是"三选一",是"下钻漏斗"——指标发现问题 → 链路定位到 span → 日志看根因。
22. 什么是 PodDisruptionBudget(PDB)?为什么必须有?#
参考答案:
是什么:PDB 是 K8s 资源,限制同时不可用的 Pod 数量,保证自愿驱逐(voluntary disruption)时仍有足够副本可用。
为什么需要:没有 PDB,一次 K8s 节点维护可能同时驱逐多个 Pod,导致服务短暂不可用。PDB 强制 K8s 在驱逐前检查"还剩多少副本",不够就等待。
如何落地:
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: order-api-pdb
spec:
minAvailable: 2 # 至少 2 个可用
# 或 maxUnavailable: 1 # 最多 1 个不可用
selector:
matchLabels:
app: order-api实战教训:一次混沌演练发现整个 namespace 都没 PDB——一个 kubectl delete pod 就能让服务全挂。PDB 是服务可靠性的基础护栏,新服务上线必须配。
23. 什么是熔断(Circuit Breaker)?三状态是怎么工作的?#
参考答案:
是什么:熔断器是分布式系统的保护机制,当下游错误率高/响应慢时自动切断调用,防止雪崩。
为什么需要:A 调 B,B 慢 → A 线程池被 B 占满 → A 也卡 → 雪崩扩散到整个调用链。熔断在 B 慢时让 A 快速失败,保护 A 不被拖垮。
如何落地:三状态自动切换:
| 状态 | 行为 | 转换条件 |
|---|---|---|
| CLOSED | 正常通过 | 失败次数达阈值 → OPEN |
| OPEN | 立即返回错误 | 冷却时间到 → HALF-OPEN |
| HALF-OPEN | 放行少量探测 | 成功 → CLOSED,失败 → OPEN |
关键参数:失败阈值 5-10 次/分钟、熔断时长 30-60s、HALF-OPEN 探测 1-3 个请求。OPEN 时要有 fallback 逻辑(返回缓存/默认值)。
24. 什么是舱壁模式(Bulkhead)?它和熔断的区别?#
参考答案:
是什么:舱壁模式从船舶设计借用——船体被分隔成多个水密舱,一个舱进水不会让整艘船沉没。在软件中是资源隔离,防止一个故障扩散到其他部分。
如何落地:隔离维度:
- 线程池隔离:不同下游用独立线程池
- 连接池隔离:不同 DB 用独立连接池
- 部署隔离:核心服务和非核心分离
- 租户隔离:大客户单独资源池
和熔断的区别:
| 熔断 | 舱壁 | |
|---|---|---|
| 解决问题 | 下游慢拖垮上游 | 故障扩散 |
| 触发 | 动态(错误率超阈值) | 常驻(架构级) |
| 可见性 | 有告警(OPEN 次数) | 无告警(容易被忽视) |
舱壁是最容易被忽视的隔离手段——缺少它时故障传播是瞬时的。
25. 什么是 Feature Flag?它如何降低发布风险?#
参考答案:
是什么:Feature Flag(功能开关)是把"代码部署"和"功能启用"解耦的机制。代码部署到生产但开关关闭,不影响用户;按需打开开关分用户/分区域启用。
为什么需要:传统发布中"部署 = 启用",风险集中。Feature Flag 让发布和启用分离,出问题时关开关秒级止损,不需要重新部署。
如何落地:使用场景:
- 逐步放量:新功能只向 1% 用户开放
- 紧急关闭:某功能导致问题,关开关秒级止损
- A/B 实验:同功能两种实现对比效果
- 运维开关:关闭非核心功能释放资源
风险:
- 开关膨胀:必须有生命周期管理,定期清理已全量开启的 Flag
- Flag 配置变更也是发布:需要和代码发布一样的灰度策略
26. 什么是容量水位线?它和 SLO 告警的区别?#
参考答案:
是什么:容量水位线是资源使用的预警阈值,如 CPU > 50% 预警、> 80% 危险(与方案设计题的水位线表 50/80 口径一致)。
为什么需要:水库不能等水满了再泄洪——容量管理也一样,不能等 CPU 100% 了再加机器。水位线是预测性指标。
和 SLO 告警的区别:
| 水位线告警 | SLO 告警 | |
|---|---|---|
| 性质 | 预测性(还没影响用户) | 结果性(已经影响用户) |
| 紧急度 | Ticket 级 | Page 级 |
| 目的 | 容量管理 | 用户体验保护 |
如何落地:好的容量管理是在水位线告警阶段就处理,不要等到 SLO 告警。各类资源水位线:CPU < 50% 安全、内存 < 60% 安全、磁盘 < 70% 安全。
27. 什么是 Error Budget 的双层归因?#
参考答案:
是什么:双层归因是 Postmortem 中根因分析的方法论——不只问"什么坏了"(触发因素),更问"为什么没兜住"(结构性缺陷)。
为什么需要:触发因素千变万化(addon 更新、节点轮换、流量突发),但结构性缺陷可以根治。只修触发因素 = 同类故障会以其他形式重演;修结构性缺陷 = 拆掉一类定时炸弹。
如何落地:举例——CNI 自锁故障:
- 第一层(触发因素):addon 更新让 IRSA 短暂失效 → 修复:等 addon 更新完再扩节点
- 第二层(结构性缺陷):node role 没配 CNI policy 兜底 → 修复:给所有 node role 配 CNI policy
第一层修复只防"这次",第二层修复防"一类"。双层归因是从"灭火"升级到"拆弹"的关键。
28. 什么是服务成熟度分级?怎么用?#
参考答案:
是什么:服务成熟度分级是评估服务可靠性水平的框架,从低到高分 5 级:
| 等级 | 标准 | 典型特征 |
|---|---|---|
| L0 裸奔 | 无 SLO、无告警、无 Runbook | "出了事才知道" |
| L1 有监控 | 有 RED 面板,有基础告警 | "出了事能看到" |
| L2 有 SLO | SLO + Error Budget + 燃烧率告警 | "可靠性可量化" |
| L3 自愈 | 常见故障自动恢复 | "出了事能自己好" |
| L4 混沌验证 | 通过混沌工程持续验证 | "韧性有保证" |
为什么需要:没有分级就没有改进路线图。团队不知道"我们在哪""要去哪"。
如何落地:组织制定时间表:
- 新建服务 1 个月内达到 L1
- 核心服务 3 个月内达到 L2
- 支付等关键服务 6 个月内达到 L3
- 所有核心服务 12 个月内达到 L4
每月 review 服务等级,未达标的限期整改。新服务上线必须满足 L1 准入清单。
29. 什么是负载卸载(Load Shedding)?过载时如何优雅降级?#
参考答案:
是什么:负载卸载是系统过载时主动丢弃部分请求以保住整体可用,而不是让所有请求一起变慢直到全崩。优雅降级是配套手段——在资源不足时把核心路径降到"最简可用版本"。
为什么需要:容量有上限,过载时"公平地慢"= 全员超时 = 有效吞吐归零。主动丢一部分负载,反而能让剩下能处理的那部分正常完成。这是过载治理的第一性原理:保住有效吞吐,而不是保住每一个请求。
如何落地:
- 按优先级丢:先丢低优先级 / 可重试 / 健康检查之外的流量;critical 请求(支付、下单)优先保。
- 在入口就丢:越早拒绝越省资源,返回 429/503 +
Retry-After,别让请求进来占了资源再失败。 - 优雅降级:关个性化推荐、关非核心校验、返回缓存/默认值、只保核心链路。
- 配合限流、熔断、有界队列:队列必须有界——满了立即拒绝,绝不无限排队。
- 关键约束:丢一个请求要比处理它更便宜,否则"丢"的动作本身也会拖垮系统。
反例:无界队列 + 全部重试 = 过载被正反馈放大成雪崩。不丢负载的系统在过载时不是"变慢",是"一起死"。
30. 什么是稳态假设(Steady-State Hypothesis)?它在混沌工程里扮演什么角色?#
参考答案:
是什么:稳态假设是混沌工程的出发点——先用可测量的指标定义系统"正常"的稳态(如成功率 > 99.9%、P99 < 300ms、下单转化率落在正常带内),然后假设"注入故障后这个稳态仍能维持",再注入真实事件试图证伪这个假设。
为什么需要:没有稳态定义就没有判据。"kill 个 pod 系统没挂"是空洞结论——没挂到什么程度?稳态假设让实验可证伪:假设成立 = 通过,假设被打破 = 发现了脆弱点 = Action Item。
如何落地(混沌工程四步):
- 定义稳态:选能反映用户体验的指标 + 正常波动带(业务指标 > 系统指标——订单量比 CPU 更能说明"用户还好吗")。
- 假设稳态在实验组和对照组都持续。
- 注入真实世界事件:注入的是真实故障模式(节点宕、依赖延迟、依赖返错),不是随机破坏。
- 试图证伪:稳态被打破就是发现,别为了"通过"而放水。
关键:稳态假设把混沌工程从"搞破坏"变成"做实验"。写不清楚稳态和假设,就不该做这个实验。
31. 什么是 RPO 和 RTO?为什么备份必须做恢复演练?#
参考答案:
是什么:
- RPO(Recovery Point Objective,恢复点目标):最多能容忍丢多少数据(时间维度)。RPO = 5min → 灾难时最多丢 5 分钟数据 → 备份/复制频率至少每 5 分钟一次。
- RTO(Recovery Time Objective,恢复时间目标):从故障到恢复服务最多允许多久。RTO = 1h → 必须 1 小时内恢复。
为什么需要:SLO 管的是日常可用性,RPO/RTO 管的是灾难场景(Region 挂、数据被误删、勒索加密)——两者是不同维度,不能互相替代。
为什么必须做恢复演练:没验证过的备份等于没有备份。常见翻车:备份任务显示"成功"但文件损坏/不完整、恢复脚本早已过时、恢复实际耗时远超 RTO、恢复缺依赖(密钥/schema 版本对不上)、根本没人会操作。只有真正跑一遍"从备份恢复到可用",RPO/RTO 才不是纸面数字。
如何落地:
- 季度做恢复演练,计时对照 RTO、校验数据完整性对照 RPO。
- 恢复步骤写进 runbook,轮流由不同人执行(防单点知识)。
- 关键数据做异地/异账号备份,防勒索和误删波及备份本身。
32. 5 个各 99.9% 的组件串行调用,整体可用性是多少?加冗余并联怎么算?#
参考答案:
串联(依赖链,全部要好整体才好):整体可用性 = 各组件可用性相乘。
- 5 个 99.9% 串联 = 0.999^5 ≈ 99.5%。
- 月度允许不可用从 43 分钟暴涨到 ~3.6 小时。
关键洞察:串联把可用性往下拖——同步强依赖越多,整体越低。这就是为什么要减少关键路径上的强依赖:能异步的异步、能降级的降级、能去掉的去掉,别把可有可无的依赖放进关键链。
并联(冗余,任一好整体就好):整体不可用概率 = 各自不可用概率相乘。
- 2 个 99.9% 并联 = 1 - (0.1%)² = 1 - 10⁻⁶ = 99.9999%(六个九)。
- 冗余把可用性往上抬。
如何用:先画依赖图算串联基线,发现整体被拖低 → 对关键组件加冗余(多副本/多 AZ)并联抬升,或砍掉非必要强依赖。注意并联必须真正独立——共享同一个数据库、同一个 AZ、同一条网络,就不是真并联,一次故障会同时命中所有"副本",算出来的六个九是假的。
33. 什么是幂等性?为什么分布式系统里的重试几乎都要求幂等?exactly-once 真的存在吗?#
参考答案:
是什么:幂等(Idempotent)指同一操作执行一次和执行多次效果相同。"把余额设为 100"幂等;"余额 +100"不幂等。
为什么重试需要幂等:网络超时下,调用方无法区分"请求没到达"和"处理了但响应丢了"。对非幂等操作重试 = 可能扣两次款、下两次单。所以重试的前提是操作幂等,否则重试就是在制造脏数据。
exactly-once 的真相:网络层面做不到真正的 exactly-once 投递。工程上实现的是 at-least-once 投递 + 幂等消费 = 有效一次(effectively-once)。手段:
- 幂等键:去重表 / 唯一约束,同一个 requestId 只生效一次。
- 乐观锁版本号:带版本更新,版本不匹配就拒绝。
- 状态机:只接受合法的状态转移,重复消息落到同一状态。
关键:重试、消息队列、发布订阅默认都是 at-least-once,业务侧必须自己保证幂等,别指望中间件白送你 exactly-once。
延伸:概念解释型面试题的答题技巧——先一句话定义(是什么),再展开核心特征(为什么需要),最后给具体例子或落地方法(如何落地)。不要背书,用自己的话讲。三步框架让答案有层次、有深度、有实操性。