面试 · 方案设计型
目标:考察架构设计和系统性规划能力。不是答"应该怎么做",而是要给出可落地的具体方案,包含架构图思路、工具选型、落地路径、验证方法、治理要点。 答题框架:需求 → 方案 → 如何落地 → 如何验证 → 如何治理。
1. 为一个日活百万的微服务设计一套 SLO + 告警体系。从头到尾怎么做?#
参考答案:
需求#
日活百万的微服务,需要建立完整的 SLO 体系,包括 SLI 选取、SLO 制定、告警配置、Error Budget 政策。
方案#
第一步:SLI 选取(第 1-2 周)
与业务方一起确定 2-3 个用户最关心的 SLI:
- SLI-1:HTTP 可用性 = 成功请求 / 总请求
- SLI-2:P99 延迟 =
histogram_quantile(0.99, ...) - SLI-3:核心业务成功率(如"下单接口的最终成功率")
第二步:SLO 制定(第 3-4 周)
- 看历史数据:过去 3 个月实际达到的可用性
- 与业务协商:可用性目标 99.9%(月度),P99 ≤ 500ms
- 换算 Error Budget:99.9% → 每月 43.2 分钟不可用
第三步:Recording Rules + Dashboard(第 5-6 周)
# 失败 = 非 2xx/3xx(含 5xx、429 限流、499 客户端断连、504 超时)
# 与全篇口径一致:good = 2xx+3xx;纯客户端 4xx(400/404)如需豁免可从分子分母同时剔除
- record: job:slo_errors_per_request:ratio_rate5m
expr: sum(rate(http_requests_total{status!~"2..|3.."}[5m])) by (job)
/ sum(rate(http_requests_total[5m])) by (job)
- record: job:slo_errors_per_request:ratio_rate1h
- record: job:slo_errors_per_request:ratio_rate6h
- record: job:slo_errors_per_request:ratio_rate3dDashboard:当前可用性(Stat)+ Error Budget 剩余(Gauge)+ Burn Rate 趋势(Time Series)。
第四步:燃烧率告警(第 7-8 周)
- P0:1h burn rate > 14.4x + 5m > 14.4x,for 2m → page
- P1:6h burn rate > 6x + 30m > 6x,for 15m → ticket
- P2:3d burn rate > 1x,for 1h → Dashboard
窗口/燃烧率组合取自 Google SRE Workbook Table 5-8(14.4x/1h、6x/6h、1x/3d)。注意 Google 原表里 6x 也是 page、1x 才是 ticket;这里把 6x 降为 ticket、1x 只上 Dashboard,是结合本团队 on-call 承受度的调优,不是照搬 Google。面试时要能说清哪些是标准、哪些是自己调的。
第五步:Error Budget 政策(第 9 周+)
| Budget 剩余 | 发布策略 |
|---|---|
| > 50% | 正常发布 |
| 25-50% | SRE review,灰度加倍 |
| 10-25% | 仅修复性发布 |
| < 10% | 冻结功能发布 |
紧急豁免例外(政策必写):冻结冻的是功能发布,不是紧急修复。安全补丁、数据修复、合规变更、事故缓解可豁免冻结,但要走更严的通道——事先定义豁免类别 + 明确审批人(SRE Lead + 业务/安全 owner 签字)+ 最小变更面 + 强制小步灰度 + 回滚预案预先验证。没有预写豁免的冻结政策,第一次遇到 0day 就会被现场推翻。
如何落地#
第六步:影子运行 + 回顾(第 9-16 周)
- 前 4 周只观察,不告警(调阈值)
- 第 5 周起 P0/P1 生效
- 每月回顾:Error Budget 消耗分布、SLO 目标是否需要调整
如何验证#
- 主动制造一次 firing:验证告警全链路推送到群
- 主动制造一次 resolved:验证恢复通知也送达
- 季度回顾:SLO 达标率、Budget 消耗模式、告警真阳率
如何治理#
- SLO 每季度回顾调整
- Error Budget 耗尽 = 冻结发布(管理层签字)
- Dashboard 对全员公开
- SLO 达标率进团队 OKR
2. 设计一套 On-call 值班体系。团队 8 人,服务 7×24。#
参考答案:
需求#
8 人团队,7×24 服务,需要可持续的 on-call 体系。
方案#
轮值方案:采用"工作日 + 周末分开"模型:
- 每周一名 primary(周一~周五白天)+ 一名 secondary
- 周末单独一名值班人(周五晚~周一早)
- 轮值表错开:primary 和 secondary 不在同一周
人员培养路径:
新人 Shadow 2 周 → Shadowed 2 周 → 独立+Backup 2 周 → 正式入表
总耗时 6 周告警分级:
| 级别 | 通道 | 响应要求 | 升级 |
|---|---|---|---|
| P0 | 钉钉+电话 | 5min ack | 5min → secondary, 15min → lead |
| P1 | 钉钉 | 15min ack | 30min → secondary |
| P2 | Dashboard | 下个工作日 | 无 |
补偿机制:
- 工作日 on-call:1 天调休
- 周末 on-call:2 天调休
- 夜间被叫醒(22:00-8:00):额外 0.5 天调休
- 大型事故(SEV-1/2 > 2h):加班费
如何落地#
交接 SOP:
- 轮换日上午 15 分钟交接会
- 移交待办、未解根因、环境变更、风险提醒
- 文档归档到 wiki
如何验证#
- 月度告警统计:告警数、夜间比例、MTTA
- 季度问卷调查:疲劳度 1-10、最烦的告警 Top 3
- 疲劳度 > 6 → 启动告警治理
如何治理#
- on-call 表现不和绩效挂钩
- 每月 review on-call 指标
- 管理层公开认可 on-call 辛苦
- 心理健康支持
3. 为一个关键服务设计容量规划方案。要求包含压测、水位线、自动扩缩。#
参考答案:
需求#
关键服务的容量规划,避免过载也避免过度采购。
方案#
压测基准建立:
- 基准压测:用 k6 逐步提高 QPS,找到单实例在满足 SLO(P99 < 500ms)前提下的最大承载量
- 假设结果:单实例承载 500 QPS(保持 P99 < 300ms),600 QPS 时 P99 开始恶化
- 混合压测:按真实流量比例(60% 读 + 30% 写 + 10% 复杂查询)混合压
水位线设定(区间无缝衔接,预警线上界即危险线下界):
| 资源 | 安全线 | 预警线 | 危险线 |
|---|---|---|---|
| CPU 使用率 | < 50% | 50-80% | > 80% |
| 内存 | < 60% | 60-85% | > 85% |
| DB 连接池 | < 50% | 50-80% | > 80% |
| Pod 副本数 | 留有 30% 余量 | — | 不足滚动更新 |
HPA 配置:
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
behavior:
scaleUp:
stabilizationWindowSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300Karpenter/CA 节点扩容:
- NodePool provisioner 配置匹配的实例类型
- 预留 Instance 覆盖基线,Spot 覆盖弹性部分
- 冷启动延迟监控:新节点从 Provisioning → Ready 的 P99
如何落地#
容量监控 Dashboard:
- 当前 QPS vs 容量上限(%)
- 各水位线实时状态
- 14 天 QPS 趋势 + 线性预测
- HPA 扩缩容事件时间线
如何验证#
- 每季度做一次完整压测,验证容量基准是否变化
- 监控 HPA 扩容成功率 + 扩容延迟
- 模拟流量突增,验证自动扩缩能否及时响应
如何治理#
月度容量回顾:
- 实际峰值 QPS vs 预测
- 是否逼近任何水位线
- 是否需要采购预留实例
- 成本 vs 预算
4. 为一个从零开始的团队设计混沌工程推行方案。#
参考答案:
需求#
团队从零开始推行混沌工程,需要分阶段落地方案。
方案#
第一阶段:Month 1(非生产环境)
目标:跑通整个 GameDay 流程
- 在 dev 环境搭建 Chaos Mesh
- 第一次 GameDay:最简单的
kubectl delete pod - 暴露"连演练都做不成"的问题:监控告警接了吗?Runbook 是最新的吗?
第二阶段:Month 2-3(staging 环境)
目标:建立场景库
- 挑选 10-15 个高频故障场景:Pod kill / OOM / MySQL failover / 网络延迟
- 为每个场景写假设文档 + 观测手段 + 回滚步骤
- 每两周一次 GameDay
第三阶段:Month 4-6(生产非高峰)
目标:谨慎推向生产
- 生产演练安全护栏:Blast radius →
mode: one,Stop-loss → 错误率 > 5% 自动终止 - 首次生产 GameDay:只做 pod-kill
- 逐步扩展到 network-delay
第四阶段:Month 6+
目标:常态化
- Chaos Mesh Schedule:工作日凌晨自动 pod-kill
- 业务 opt-in:打 label
chaos-candidate: "true"才被选中 - 每月一次复合故障 GameDay
如何落地#
- 说服管理层:用事故数据讲故事
- 选一个痛点最大的业务做试点 → 拿结果数据展示
- 强调"没有 SLO 验证的 SLO 是未测试的承诺"
如何验证#
- 每次演练后对照假设逐条验证
- 季度统计:演练发现的 Action Items 完成率
- 系统韧性指标:MTTR 趋势、同类故障复发率
如何治理#
- 场景库持续维护(新故障模式加入)
- 演练复盘必须 48h 内完成
- 常态化注入的简报推送到团队频道
5. 设计一套 Postmortem 流程 + Action Items 跟踪体系。#
参考答案:
需求#
建立规范化的故障复盘流程,确保每次事故都变成组织改进。
方案#
Postmortem 纪律:
- 48 小时内完成初稿
- 72 小时内开复盘会
- 所有 SEV-1/SEV-2 必须写,SEV-3 简洁版
模板结构:
1. 元数据(时间/SEV/IC/影响面)
2. 时间轴(精确到分钟)
3. 影响分析(用户/业务/SLA)
4. 根因分析(直接原因 + 传播原因 + 触发条件)
5. 贡献因素(为什么预防/检测/缓解机制没起作用)
6. 做得好的 / 做得不好的
7. 运气成分
8. Action Items(Fix/Prevent/Detect/Mitigate/Process)
9. Lessons LearnedAction Items 跟踪:
| 类型 | 含义 | 例子 |
|---|---|---|
| Fix | 修根因 | 为缺失索引建索引 |
| Prevent | 防再发 | PR 流程加 SQL lint |
| Detect | 早发现 | 加 staging 真实流量压测 |
| Mitigate | 减影响 | 告警窗口从 2m 调到 1m |
| Process | 流程改进 | 更新 rollback runbook |
如何落地#
跟踪机制:
- 所有 Action Items → Jira incident backlog
- 每周 IMOC review 未关闭 items
- 超期 > 1 周 → 报给 team lead
- P0/P1 进团队 OKR
- 月度事故回顾会回看所有 open items
如何验证#
追踪指标:
- Action Items 完成率(目标 > 80%)
- 平均完成时间
- 同类事故复发率(应趋近于 0)
如何治理#
事故数据库:所有 Postmortem 放同一仓库,打标签(scope/root_cause/severity)
季度回顾会:事故次数、平均 MTTR、根因分布、Top 3 教训、Action Items 完成情况。
Blameless 文化:复盘文档不写人名用角色,领导层明确支持 blameless。
6. 设计一个平台团队的可观测性架构。要求支持多云、多集群、统一入口。#
参考答案:
需求#
多云、多集群、统一入口的可观测性架构。
方案#
架构总览:
数据采集层:
各 K8s 集群 → Prometheus (scrape) / OTel Collector (push)
AWS 托管服务 → YACE (CloudWatch Exporter)
阿里云资源 → CMS → 阿里云 Prometheus
聚合层:
Prometheus → remote write → Thanos/Mimir (长期存储 + 全局查询)
日志 → OTel Collector → Loki (统一存储)
链路 → OTel Collector → Tempo
查询层:
Grafana → 统一 Data Source (Thanos/Mimir + Loki + Tempo)
告警层:
各集群 PrometheusRule → Alertmanager → 统一告警路由 → 钉钉/PagerDuty关键技术选型:
| 层 | 技术 | 理由 |
|---|---|---|
| 采集 | OTel Collector | 厂商中立,统一采集标准 |
| 指标存储 | Prometheus (本地) + Thanos (全局) | 解耦本地和长期需求 |
| 日志 | Loki (S3 后端) | 低成本、与 Prometheus label 对齐 |
| 链路 | Tempo (S3 后端) | 低成本、与 Loki 同哲学 |
| 告警路由 | Alertmanager | 分组/去重/抑制/静默 |
| 看板 | Grafana | 三信号统一展示 + 下钻 |
多集群设计:
每个集群:
├── Prometheus (本地 15d, 双副本 HA)
├── Alertmanager (3 副本)
├── OTel Collector (DaemonSet agent 模式)
└── Thanos Sidecar → 对象存储上传
全局:
├── Thanos Query → 聚合所有集群数据
├── Loki (S3, 30d)
├── Tempo (S3, 72h)
└── Grafana → 多集群入口如何落地#
成熟度规划:
Phase 1 (3 个月): 指标 → Prometheus + Grafana + 基础告警
Phase 2 (6 个月): 日志 → Loki + 结构化日志
Phase 3 (9 个月): SLO → 燃烧率告警 + Error Budget
Phase 4 (12 个月): 链路 → Tempo + 三信号关联下钻
Phase 5 (18 个月): 全量 GitOps + 成本治理如何验证#
- 排障下钻闭环:告警 → 概览盘 → RED → trace → log → 根因
- 死机开关:每个 Alertmanager 都有 Watchdog
- 三信号关联键:trace_id 在指标/日志/链路中都存在
如何治理#
- 配置全 GitOps(告警规则、Dashboard、Collector 配置进 Git)
- 成本治理:控基数、采样、分层保留、降采样
- 多租户:按 tenant 隔离数据和查询权限
7. 如何为一个现有系统(之前没有 SLO)引入 Error Budget 机制?分步推进方案。#
参考答案:
需求#
现有系统没有 SLO,需要引入 Error Budget 机制。
方案#
第一阶段:观察期(1-2 个月)
目标:不改变任何流程,只收集数据
- 选取 2 个代表性服务(一个关键 + 一个一般)
- 配 Recording Rules 计算 SLI,建 Dashboard
- 影子运行:计算 Error Budget 但不配置告警
- 观察一个月后产出数据:实际可用性、正常波动范围、误报会有多少
第二阶段:校准期(第 3 个月)
- 与业务方协商 SLO 目标:基于实际数据,设定"比当前水平略高但可达到"的目标
- 配置 P0 告警(14.4x 燃烧率),for 15m(先宽松)
- 第一个月不冻结发布,只标注「燃烧率超标」
- 月度 Error Budget 回顾会
第三阶段:政策引入(第 4-5 个月)
- 引入 Error Budget 消耗政策:Budget < 50% 提醒,< 25% review,< 10% 冻结
- 增加 P1/P2 告警
- 第二次回顾:调整 SLO 阈值和告警敏感度
第四阶段:推广(第 6 个月+)
- 扩展到更多服务
- 标准化 SLO 定义和 Recording Rules 模板
- 用 Sloth 自动生成告警规则
- Error Budget 影响发布决策成为团队习惯
如何落地#
关键沟通策略:
- 第一句:"我们不惩罚,我们先看数据"
- 把 SLO 讲成"允许失败的空间"而非"必须达到的标准"
- 用具体时间而非百分比做沟通
- 让业务方签字确认 SLO
如何验证#
- 影子运行阶段:数据是否准确(和实际体验对得上)
- 校准期:告警真阳率 > 70%
- 政策引入后:Budget 耗尽时是否真的冻结了发布
如何治理#
- SLO 每季度回顾调整
- Error Budget 政策需管理层签字
- Dashboard 对全员公开
- 季度回顾 Budget 消耗模式
8. 设计一个服务的可靠性准入清单(上线前 checklist)。#
参考答案:
需求#
新服务上线前的可靠性准入清单,作为硬门槛。
方案#
监控与告警:
- SLI 已定义(至少可用性 + P99 延迟)
- Prometheus Recording Rules 已部署
- RED 面板已创建(Rate/Errors/Duration)
- 燃烧率告警已配置(P0/P1/P2 三档)
- 告警全链路已验证(firing + resolved 均到达目标群)
- Runbook 已编写(含判断真问题、第一响应动作、回滚步骤、升级联系人)
- 死机开关(Watchdog)已覆盖
部署与韧性:
- 至少 2 副本(高可用基线)
- PodDisruptionBudget 已配置
- PodAntiAffinity 已配置(不同节点/AZ)
- Liveness/Readiness probe 已配置(区分启动慢和真挂)
- Graceful shutdown 已实现(SIGTERM → 排空请求 → 退出)
- 资源 requests/limits 已配(基于压测数据,非猜测)
- HPA 已配置且 min/max 合理
可靠性模式:
- 下游调用有超时配置
- 下游调用有重试(仅对幂等操作)
- 下游调用有熔断
- 降级方案已定义(核心路径的最简可用版本)
容量与发布:
- 单实例容量基准已建立(压测在 SLO 约束下的最大 QPS)
- 发布策略已定义(滚动/蓝绿/金丝雀)
- 回滚路径已验证(最近一次发布中实际回滚成功过)
- 数据库 Schema 变更是向后兼容的(不影响回滚)
安全:
- 不在代码中硬编码密钥(走 Secret/External Secrets Operator)
- 日志中不打印敏感信息(用户数据/密钥/token)
- 生产操作入口与开发环境隔离
如何落地#
- CI/CD 流水线集成检查(告警规则没提交则不能发布)
- SRE review 环节作为发布流程的必经节点
- 服务等级评估每月 review,未达标的限期整改
- 新服务 owner 必须参加"SRE 入门培训"
如何验证#
- 主动制造一次 firing 验证告警链路
- 模拟 Pod 故障验证 PDB
- 压测验证容量基准
如何治理#
- 新建服务 1 个月内达到 L1(有监控)
- 核心服务 3 个月内达到 L2(有 SLO)
- 支付等关键服务 6 个月内达到 L3(自愈)
- 所有核心服务 12 个月内达到 L4(混沌验证)
9. 团队想做生产环境的混沌工程演练。设计安全护栏方案。#
参考答案:
需求#
生产环境混沌工程演练的安全护栏方案。
方案#
护栏一:爆炸半径限制
spec:
mode: one # 只影响 1 个 Pod
selector:
namespaces: [order]
labelSelectors:
app: order-api
duration: "30s" # 30 秒后自动清理护栏二:Stop-Loss 自动回滚
apiVersion: batch/v1
kind: CronJob
metadata:
name: chaos-stop-loss
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: checker
image: curlimages/curl
command: ["sh", "-c"]
args:
- |
err_rate=$(curl -s "http://prometheus/api/v1/query?query=..." | jq '.data.result[0].value[1]')
if [ "$(echo "$err_rate > 5" | bc)" -eq 1 ]; then
kubectl delete podchaos --all -n chaos-testing
kubectl delete networkchaos --all -n chaos-testing
echo "CHAOS ABORT: error rate > 5%"
fi护栏三:时间窗口
HOUR=$(date +%H)
DAY=$(date +%u)
if [ "$DAY" -ge 6 ] || [ "$HOUR" -lt 14 ] || [ "$HOUR" -ge 17 ]; then
echo "不在允许的演练窗口(工作日 14:00-16:30)"
exit 1
fi护栏四:审批 + 公告
- 演练前 2 天在全员频道公告
- 生产演练需 SRE Lead + 业务 owner 双审批
- 演练中实时播报到事故响应群
- 演练前验证:所有人员的告警通知可达、on-call 明确、回滚路径预演过
护栏五:权限控制
Chaos Mesh ServiceAccount 只允许操作特定 namespace。
护栏六:先非生产后生产
Dev 环境(充分验证) → Staging(高流量模拟) → Prod 非高峰 → Prod 任意时段
每个阶段至少稳定跑 4 次后才进入下一阶段如何落地#
- 演练前写假设文档(不写假设不做实验)
- 演练中专人盯监控
- 演练后 48h 内复盘
如何验证#
- 演练前测试 Stop-Loss 是否能终止实验
- 演练前验证回滚路径
- 演练后检查是否有非预期影响
如何治理#
- 场景库持续维护
- 每次演练的 Action Items 进 OKR
- 常态化注入的简报推送团队频道
10. 设计一个团队从"群聊救火"演进到"结构化事故响应"的推进方案。#
参考答案:
需求#
从"群聊救火"演进到结构化事故响应。
方案#
现状诊断:先跑 2 周采集数据:每周平均多少次事故告警?SEV 级别分布?平均 MTTR?响应流程中最大的痛点?
第一周:事故分级 + 模板建立
- 定义 SEV-1 到 SEV-4 的判定标准
- 建立事故群命名规范:
#incident-YYYYMMDD-HHmm-<短描述> - 固化两个模板:状态摘要模板(IC 每 15 分钟发)+ 对外沟通模板(CL 发)
- 任命第一批 IC/CL 名单
第一月:角色试点
- SEV-2 以上任命 IC(暂不要求 CL)
- 用模板记录每次事故
- 月底回顾:哪些模板好用?哪些需要改?
第二月:全角色
- SEV-1/SEV-2 四个角色齐全(IC/Ops Lead/CL/IMOC)
- 搭事故沟通频道:status page 或专属群
- 建立 Postmortem 纪律:48h 内完成初稿
第三月:工具化
- 如果手动流程跑顺了,考虑引入事故管理工具(incident.io/FireHydrant)
- 工具负责:自动任命角色、定时提醒、模板填充、时间轴记录
如何落地#
各级别适用策略:
| 团队规模 | 做法 |
|---|---|
| < 10 人 | 值班人负责全部,不搞角色。但模板仍然用 |
| 10-50 人 | 引入 IC,SEV-1/2 规范化 |
| 50-200 人 | 四角色齐全 |
| > 200 人 | 专职 IMOC + 事故工具平台 |
如何验证#
- MTTR 趋势监控(应该下降)
- Postmortem 完成率(目标 100% for SEV-1/2)
- Action Items 完成率(目标 > 80%)
如何治理#
- 事故回顾会:不只复盘单个事故,看全季度模式
- 新人 onboarding:阅读经典 Postmortem
- 流程本身要迭代——每次复盘后 review 流程哪里可以改进
11. 为一条事故响应链设计升级策略(Escalation Policy)。#
参考答案:
需求#
事故响应链的升级策略,确保告警有人响应。
方案#
升级链结构:
Level 1(0-5min) : Primary On-Call
Level 2(5-10min) : Secondary On-Call
Level 3(10-15min) : Team Lead
Level 4(15min+) : IMOC / Manager on Duty规则:
- Primary 接到告警 → 5 分钟内必须 acknowledge
- 5 分钟未 ack → 自动升级到 Secondary
- Secondary 10 分钟内未 ack → 升级到 Team Lead
- Team Lead 15 分钟内未 ack → 升级到 IMOC
- SEV-1 直接通知到 Level 3(跳过 Secondary 的等待时间)
升级 ≠ 替代:升级到上级后,Primary 依然负责事故处理。上级是支援、不是接手。
如何落地#
Alertmanager 侧:
receivers:
- name: primary-oncall
webhook_configs:
- url: http://webhook-dingtalk:8060/dingtalk/primary/send
- name: secondary-oncall
webhook_configs:
- url: http://webhook-dingtalk:8060/dingtalk/secondary/sendPagerDuty 侧:
- Schedule(排班)→ Escalation Policy → Service
- Escalation Policy 里定义各级的延迟时间和通知对象
自研 Bot 侧:
alerts = receive_from_alertmanager()
for alert in alerts:
notify_primary(alert)
schedule_escalation_check(alert.id, delay=5*60)
if alert_not_acked(alert.id) and time_elapsed > 5*60:
notify_secondary(alert)如何验证#
- 主动制造一次"Primary 不 ack"的场景,验证升级是否触发
- 监控升级触发率(高 = Primary 响应有问题)
- MTTA 趋势(应该 < 5 分钟)
如何治理#
升级链反模式:
- ❌ 层级太多(>4 层)→ Primary 产生依赖心理
- ❌ Secondary 和 Primary 同时接收告警 → 浪费人力
- ❌ 升级链只停留在 Alertmanager 不进入物理通知
12. 团队需要从零建一套 Error Budget Dashboard。设计面板布局和关键查询。#
参考答案:
需求#
从零建 Error Budget Dashboard,让团队一目了然知道可靠性状态。
方案#
布局设计:
Row 1: 核心状态(4 个 Stat Panel,一眼看清)
┌─────────────┬─────────────┬──────────────┬──────────────────┐
│ 当前可用性 │ P99 延迟 │ Burn Rate │ Error Budget 剩余 │
│ 99.95% 🟢 │ 230ms 🟢 │ 0.5x 🟢 │ 78% 🟡 │
└─────────────┴─────────────┴──────────────┴──────────────────┘
Row 2: 趋势(Time Series)
├─ 可用性趋势(30d) + SLO 目标线
└─ P99 延迟趋势(7d)
Row 3: 燃烧率(Time Series,SLO 告警的核心)
├─ 1h burn rate + 6h burn rate + 告警阈值参考线
└─ 3d burn rate + 正常消耗 1x 参考线
Row 4: Error Budget 消耗(Time Series)
└─ 月度 Error Budget 剩余量从 100% 到现在的曲线
Row 5: 请求分布(Bar Chart)
└─ 按状态码分组的 QPS + 按接口分组的 P99 延迟如何落地#
关键 PromQL:
# 当前可用性
sum(rate(http_requests_total{status=~"2..|3.."}[5m])) by (job)
/ sum(rate(http_requests_total[5m])) by (job) * 100
# 1h Burn Rate
(1 - sum(rate(http_requests_total{status=~"2..|3.."}[1h])) by (job)
/ sum(rate(http_requests_total[1h])) by (job)) / (1 - 0.999)
# Error Budget 剩余(%)
(1 - (
sum_over_time(job:slo_errors_per_request:ratio_rate5m[30d:5m])
/ count_over_time(job:slo_errors_per_request:ratio_rate5m[30d:5m])
) / 0.001) * 100颜色编码:
| Burn Rate | Error Budget 剩余 | 颜色 |
|---|---|---|
| < 1x | > 50% | 🟢 绿色(健康) |
| 1x-6x | 25-50% | 🟡 黄色(关注) |
| 6x-14.4x | 10-25% | 🟠 橙色(预警) |
| > 14.4x | < 10% | 🔴 红色(紧急) |
如何验证#
- 对比 Dashboard 数据和实际体验——数据准吗?
- 模拟 Budget 消耗,验证告警是否触发
- 季度回顾:Dashboard 是否帮助做了决策
如何治理#
- Dashboard 对全员公开
- 每月 Error Budget 回顾会基于 Dashboard 数据
- Dashboard 链接到 Runbook、Grafana、Loki 实现一键下钻
13. 设计一套告警治理方案。团队当前每周 40+ 次 page 告警,需要降到 10 次以下。#
参考答案:
需求#
从每周 40+ 次 page 降到 10 次以下,同时不遗漏真故障。
方案#
第一步:告警审计(第 1 周)
从 Alertmanager 导出 30 天告警数据:
- 按 alertname 统计出现次数
- Top 10 最频繁告警逐一 review
- 真阳率统计(真故障 vs 误报)
第二步:Top 10 逐一处理(第 2 周)
| 告警类型 | 处理方式 |
|---|---|
| DiskUsageHigh | 改 ticket 级(扩容不需立刻) |
| PodRestartFrequent | 条件改严(1min > 5 次才 page) |
| HTTP_5xx_high | 改成 SLO burn rate 告警 |
| CertExpirySoon | 90 天提醒,不每天 page |
| NodeCPUHigh | 砍掉,换成 SLO-driven |
| CrashLooping | > 30 分钟才 page |
| ReplicationLag | lag > 30s 才 page |
| MemoryHigh | 改 ticket,自动扩容兜底 |
第三步:三层分流(第 3 周)
| 层级 | 通道 | 响应要求 |
|---|---|---|
| Page | 钉钉+电话 | 5min ack |
| Ticket | Jira | 下个工作日 |
| Log | 团队频道 | 不强制 |
默认所有告警是 ticket,只有满足"立即响应有意义"才升级为 page。
第四步:告警必须有 Runbook(第 4 周)
新增 page 级告警的 PR 必须附 Runbook 链接,否则 review 拒绝。
如何落地#
- 每月告警审计会议(2 小时)
- 新增 page 级告警必须附 runbook
- 告警数量作为团队 KPI
如何验证#
- 告警数:从 40 次/周降到 8 次/周
- 真阳率:从 35% 涨到 75%
- 夜间告警比例:从 29% 降到 8%
- MTTA:从 12 分钟降到 6 分钟
如何治理#
- 季度问卷调查:疲劳度 1-10
- 疲劳度 > 6 → 启动专项治理
- 告警规则进 GitOps
- 每条告警有生命周期(新建 → 试运行 → 评估 → 保留/调整/退役)
14. 设计一套多集群告警合并方案。5 个集群各有 Prometheus,告警散在 6+ 钉钉群。#
参考答案:
需求#
5 个集群、6+ 钉钉群、告警散乱,需要合并到统一入口。
方案#
架构:
5 个集群 Prometheus → 各自 Alertmanager → 统一 Alertmanager(中心收敛)
→ prometheus-webhook-dingtalk → 钉钉主群(prod)+ 钉钉 staging 群
→ healthchecks.io(死机开关)→ 反向告警群关键决策:
- Alertmanager 是唯一收敛点
- prometheus-webhook-dingtalk 是唯一钉钉出口
- Watchdog 永远在线,走独立 receiver
- 反向告警通道独立于主告警通道
Alertmanager 路由:
route:
receiver: webhook-dingtalk-prod
group_by: ['alertname', 'cluster', 'namespace']
routes:
- matchers: [alertname = "Watchdog"]
receiver: dead-mans-switch
- matchers: [severity = "critical"]
receiver: webhook-dingtalk-prod
- matchers: [cluster =~ "sandbox.*|staging.*"]
receiver: webhook-dingtalk-staging如何落地#
实施步骤:
- 导出全部规则做分类审计
- 渠道梳理——列出所有 SNS/Lambda/webhook
- silence 审计——清理长期 silence
- Watchdog 心跳完整实现
- 业务侧 webhook 桥接器(业务告警 → Alertmanager)
- 规则归档 + 周巡检
- 老 Lambda/CMS 渠道退役
如何验证#
- 主动制造一次 firing,验证全链路
- 主动 silence 排除 Watchdog,验证负匹配生效
- 告警数量从分散到收敛
如何治理#
- 所有告警规则进 GitOps
- 每周对账:git 规则数 vs 集群加载规则数
- silence 必须有 endsAt + comment
- 每月告警审计会议
15. 设计一套"可靠性文化"推进方案。研发团队目前不参与 on-call,不写 SLO。#
参考答案:
需求#
研发团队不参与 on-call、不写 SLO,需要推进可靠性文化。
方案#
Phase 1:选痛点最大的服务做试点(1-2 月)
- 选一个事故频发的服务
- SRE 和研发一起建 SLO 体系
- 做出效果(MTTR 下降、事故减少)
- 研发开始信任 SRE 方法论
Phase 2:推广到核心服务线(3-4 月)
- 建标准化模板(SLI 定义模板、Runbook 模板)
- 建可靠性准入清单(新服务上线必须满足)
- SRE 给研发做培训
Phase 3:研发参与 on-call(5-6 月)
- 研发 on-call 自己的服务(应用层)
- SRE on-call 基础设施
- 研发 on-call 前必须培训 + shadow
Phase 4:Error Budget 影响发布决策(7 月+)
- Budget 耗尽 = 冻结发布
- 管理层签字认可
- 文化形成:数据说话,不是 SRE 拦发布
如何落地#
沟通策略:
- 阻力"99.9% 太严格" → 讲 Error Budget("每月允许 43 分钟")
- 阻力"告警太多" → 让研发参与调阈值
- 阻力"功能很重要必须发" → 看 Budget 余额
管理层支持:
- CTO 明确表态:可靠性是工程目标
- on-call 时间算工作时长
- SLO 达标率进团队 OKR
如何验证#
- 研发 on-call 参与率(目标 100%)
- SLO 体系覆盖率(核心服务 100%)
- Postmortem Action Items 完成率(> 80%)
- 研发满意度调查
如何治理#
- 季度可靠性回顾会
- blameless 文化(领导层明确支持)
- 研发 on-call 培训常态化
- 可靠性准入清单作为硬门槛
16. 设计一套 SRE 团队的年度规划框架。SRE 团队 6 人,服务 20+ 微服务。#
参考答案:
需求#
6 人 SRE 团队,20+ 微服务,年度规划框架。
方案#
年度规划维度:
| 维度 | 占比 | 内容 |
|---|---|---|
| 工程投入 | 50% | 自动化、平台建设、SLO 体系 |
| 运维响应 | 30% | On-call、事件响应、Postmortem |
| 主动可靠性 | 15% | 混沌工程、容量规划、压测 |
| 学习成长 | 5% | 培训、会议、技术分享 |
季度目标示例:
Q1: 基础建设
- 所有核心服务建 SLO 体系
- 告警治理(page 告警 < 5 次/周)
- Postmortem 流程规范化
Q2: 平台化
- 可观测性平台升级(三信号关联)
- 自动化发布平台(金丝雀 + 自动回滚)
- 容量规划平台
Q3: 韧性验证
- 混沌工程推行(staging 全覆盖)
- 自愈系统建设(HPA + PDB + 自动 failover)
- 跨集群灾备演练
Q4: 文化推广
- 研发参与 on-call
- 可靠性准入清单落地
- SRE 文化培训
如何落地#
每月 review:
- 工程时间占比(目标 > 50%)
- OKR 进度
- Toil 比例(目标 < 50%)
季度 review:
- 目标达成率
- 事故趋势(次数、MTTR)
- 团队疲劳度
如何验证#
- SLO 体系覆盖率(核心服务 100%)
- 平均 MTTR(趋势下降)
- on-call 疲劳度(< 5/10)
- 工程时间占比(> 50%)
如何治理#
- 年度规划对齐业务目标
- 季度 OKR 进绩效
- 团队成员轮换(防止单点知识)
- 持续招聘(bus factor > 1)
方案设计题答题技巧:先画出架构思路(分层/分阶段),每一层讲清楚选什么 + 为什么。面试官最在意的是你的决策逻辑,而不是具体工具名。展示你能在多个方案之间做权衡(trade-off),比背一个方案有价值得多。框架:需求 → 方案 → 如何落地 → 如何验证 → 如何治理。