173. 双 11 前一周,负责人要做哪些准备(大促保障)
【考察内容】容量工程与保障体系
【题目】双 11 还有一周,你是技术负责人。从容量评估、压测、预案、监控、值班、回滚方案几个角度,列出你一周内必须完成的事项清单,并说明每项的验收标准。
【参考答案】
容量评估与压测:预估峰值流量(历史数据×增长系数),全链路压测找瓶颈(DB/缓存/网关/下游),验证容量达标;不达标的扩容/优化;
缓存预热:热点商品/数据提前加载缓存(多级缓存预热),配置 TTL 错峰;
限流降级预案:网关/应用限流阈值配置;降级清单(哪些功能可关、降级顺序);熔断阈值调整;
架构保障:核心链路检查(无单点、主从/集群就绪、MQ 容量、DB 连接池/线程池参数);秒杀等专项预案(URL 动态化、库存预扣);
数据保障:数据库备份验证、binlog 保留、对账任务就绪;
监控与值班:告警阈值设置(RT/错误率/积压/GC)、监控大盘、值班排班、应急预案文档(SOP:每个场景的处理步骤+联系人); 每项都要写可核验的验收判据(题干的第二问),示例:缓存预热=热点 Key 命中率≥95% 且 TTL 已加 ±10% 抖动;限流预案=阈值取压测水位的 70–80%、网关与应用均已下发并演练触发过一次;降级开关=逐个开关现场拨过一次并留截图;值班=凌晨故障能在 10 分钟内按 SOP 联系到所有角色;回滚方案=上一次版本可一键回退且真回退过一次。
演练:故障演练(缓存挂/DB 慢/下游故障)、预案演练(限流触发/降级切换),确保预案可用;
上线窗口:大促前冻结发版(避免新代码风险)。
容量估算(大促准备): 按预估峰值 QPS 做压测:压测流量≥目标峰值×1.2–1.5;容量=单机能力×机器数×0.7(留安全水位)。核心接口 RT 预算、DB QPS、Redis QPS、MQ 吞吐都要有数。预案矩阵:每个依赖挂了怎么办(限流阈值、降级开关、扩容机器数)。演练项:全链路压测、故障注入、切换演练、回滚演练各至少 1 次——其中回滚/切换演练必须先于发版冻结完成(演练本身要发版,冻结后就做不了);
失败与降级: 大促当天值班表+升级路径;预置开关:非核心页静态化、推荐/评论降级、写路径排队;限流阈值按分层配置(网关/应用/用户)。出问题优先保:下单、支付、登录;可弃:营销活动页、非核心推荐。
【原理溯源】
为什么大促核心是“供需+故障面”双准备? 峰值是确定的高负载,故障是概率事件。容量工程解决“扛不扛得住”,预案演练解决“扛不住时怎么活”。只压测不演练,等于有灭火器但没人会用。
为什么要缓存预热? 大促开始瞬间热点数据全量回源会打穿 DB(缓存雪崩)。预热把加载成本前移;TTL 错峰避免大量 key 同时过期。
为什么冻结发版? 新代码是最大不确定因素。大促窗口以稳为主,任何变更(代码/配置)都可能引入新故障面。冻结用制度把“变更风险”清零。
为什么预案必须文档化 SOP? 故障时人处于高压,靠记忆容易漏步骤。SOP 把“谁、在什么信号下、做什么、找谁”写死,值班可照做。验收标准是“演练能按 SOP 完成”。
限流阈值怎么定? 压测得到的系统安全水位 × 安全系数(如 80%)。网关先限,应用兜底。降级清单按“核心交易 > 展示 > 推荐/通知”排序,先关低价值功能。
元理论对应: 原理 3「故障是分布式系统的默认输入」+原理 7「对抗理性与可观测的认识论」(题群见《核心考点与元理论》§3.7+§7.7)
【选型判断树】
大促准备,按时间与风险排:
├─ D-7:容量评估 + 全链路压测 → 不达标先优化/扩容
├─ D-6:故障演练 + 预案演练 + 切换/回滚演练(必须真演练;回滚演练本身要发一次版,所以必须排在冻结之前)
├─ D-5:预案编写 + 限流降级阈值 + 监控告警
├─ D-5 起:发版冻结(大促前 3–7 天,见【关键数字】;冻结后只做开关验证与桌面推演,不再发版)
├─ D-1:缓存预热 + 确认冻结已生效 + 值班就位 + 备份确认
└─ 大促中:值班 SOP;异常按限流→降级→扩容顺序判断口诀: 先压测定容量,再演练定预案,最后冻结降变更。
【口述骨架】(5 分钟;框架 A,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “大促=容量工程+故障工程,一周按 D-7 到 D-1 排” |
| 0:30–2:00 | 容量线 | 评估、压测、预热、扩容 |
| 2:00–3:30 | 故障线 | 限流降级、监控、SOP、演练 |
| 3:30–4:30 | 变更控制 | 冻结发版、配置审批 |
| 4:30–5:00 | 收尾 | “压测保证扛得住,演练保证扛不住时能活” |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 峰值预估 | 历史峰值 × 增长系数(1.5–3) | 按业务 |
| 限流阈值 | 压测水位的 70–80% | 留缓冲 |
| 告警 | RT/错误率/队列/GC/连接池 | 80% 线 |
| 演练 | 至少覆盖缓存挂/DB慢/下游故障 | 预案可用性 |
| 发版冻结 | 大促前 3–7 天 | 以稳为主 |
| 降级顺序 | 非核心功能先关 | 保交易 |
【追问链】(三层)
L1|“压测发现不达标怎么办?” → 顺序:① 优化瓶颈(慢SQL/缓存/参数);② 扩容(实例/DB/缓存);③ 限流保护(保核心)。不要只靠加机器掩盖架构问题。
L2|“为什么只压测不演练不够?” → 压测证明容量,演练证明“故障时人与系统能切换”。很多事故不是没容量,而是预案没人会用、降级开关失效、联系人找不到。
L3|“大促中错误率上升,先限流还是先降级?” → 若是过载:先限流挡住新流量,再降级非核心释放资源,最后扩容。若明确是某功能故障:先降级/关闭该功能。总原则是先保核心链路可用。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 能列压测、扩容、监控几项 |
| 80 分 | 有时间线清单(预热/预案/值班/冻结);有验收标准意识 |
| 95 分 | 容量+故障双线;强调演练与 SOP;限流阈值有依据;冻结发版的理由 |
【关联题】
【自测】
- 大促前为什么必须冻结发版? 参考答案:新代码是最大不确定因素,冻结用制度清零变更风险,大促以稳为主。
- 限流阈值如何确定? 参考答案:压测得到安全水位后乘以安全系数(如 70–80%),网关先限应用兜底。
- 判断:压测通过就等于大促准备完成。 参考答案:错。还需预案演练、监控告警、值班 SOP、缓存预热、发版冻结。
174. 刚发布新版本,线上错误率飙升(发布事故处置)
【考察内容】发布工程与故障处置
【题目】下午 3 点发布新版本,3:05 监控显示错误率从 0.1% 飙到 20%。第一反应该做什么?回滚还是热修复?回滚怎么执行最快?如何确认回滚后恢复?事后怎么定位根因?
【参考答案】
第一动作:回滚止血(回滚本身就是止血手段里最快的一个):立即回滚到上一个稳定版本(发布系统的快速回滚能力是关键)——比在线上“修代码”快且安全;
同时定位:看新版本变更点(代码 diff)、错误日志/调用链/监控(错误类型:异常、超时、OOM);
如果无法快速回滚(DB 结构变更等):评估灰度下线(新实例摘流量,旧实例顶流量)或功能开关关闭新逻辑;
复盘:事故原因分类——
- 代码缺陷(空指针、并发问题、缓存键变更);
- 依赖变更(下游接口变动、配置错误);
- 数据问题(存量数据不兼容新逻辑);
- 容量(新逻辑引入额外消耗);
恢复后:全量回归验证 → 修复缺陷 → 小流量灰度再发布(按本题第 7 条的 1%→5%→20%→50%→100%)→ 观察指标;
制度保障:发布系统必备——灰度发布、快速回滚、发布前后自动化检查(健康检查/冒烟测试)、变更审批与审计。
容量估算与分诊阈值: 错误率基线通常 <0.1%;发布后 5 分钟内错误率>1% 或核心接口失败率>5% → 立即回滚,不等“再观察一下”。灰度比例经验:1% → 5% → 20% → 50% → 100%,每档观察 5–15 分钟(看是否有延迟暴露)。回滚目标时间:<5 分钟完成全量回滚(依赖制品库秒级切换)。
失败与降级: 第一动作回滚止血;回滚不可用(无版本可退、有兼容数据)时才改用限流/降级/摘流止血;第三动作留现场(日志、版本、diff、监控)。禁止在故障中“热改生产”。回滚后若仍异常,说明不是本次发布或有兼容数据问题——切预案。
【原理溯源】
为什么“回滚优先”而不是热修? 热修需要定位+改代码+测试+再发布,时间不可控;回滚是已验证过的旧版本,分钟级恢复。故障中时间×影响面是核心代价,回滚最小化两者。
为什么错误率 20% 而不是 100%? 可能是:部分实例已发布、部分代码路径才触发、特定数据才炸、灰度批次。这也提示回滚时要确认全部实例是否都回退。
回滚的风险边界在哪? ① DB 结构变更(加列可回滚代码,删列不可);② 数据格式不兼容(新代码写了旧代码读不懂的数据);③ 配置/开关与代码强耦合。所以发布规范要求:DB 变更前向兼容、配置与代码解耦、可回滚设计。
灰度为什么是 1%→5%→20%→50%→100%? 小流量先暴露问题,限制爆炸半径。每档要卡点观察(错误率/RT/业务指标),异常立即停。没有卡点的灰度只是慢速全量。
为什么错误类型要先分类? 空指针/断言=代码逻辑;连接超时=依赖;OOM=资源;数据校验失败=不兼容存量。分类直接指向 diff 中该看哪块。
【选型判断树】
发布后错误率飙升:
├─ 能快速回滚(无破坏性 DB/数据变更)
│ → 立刻全量回滚 → 再定位根因
├─ 不能直接回滚
│ ├─ 新旧实例可并存 → 新实例摘流量,旧实例接
│ └─ 有功能开关 → 关闭新逻辑
└─ 回滚后仍错误
→ 可能配置/数据/下游问题,不是本次代码
→ 查变更清单(含配置、依赖版本)判断口诀: 先问能不能回滚;能回就回,不能回就摘流量或关开关。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “发布事故第一原则:回滚优先止血” |
| 0:30–1:30 | 为什么回滚 | 时间可控、版本已验证 |
| 1:30–2:30 | 回滚边界 | DB/数据/配置兼容性 |
| 2:30–3:30 | 不能回滚时 | 摘流量、关开关 |
| 3:30–4:30 | 根因与再发布 | diff 分类、灰度卡点 |
| 4:30–5:00 | 制度 | 发布系统:灰度/回滚/检查 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 决策窗口 | 发现后 5 分钟内应完成回滚决策 | 时间就是影响 |
| 灰度批次 | 1% → 5% → 20% → 50% → 100% | 每档卡点观察 5–15 分钟 |
| 观察指标 | 错误率、RT、业务量、GC | 与基线对比 |
| 回滚确认 | 全部实例版本一致 + 指标回落 | 防残留 |
| DB 原则 | 结构变更前向兼容 | 保证可回滚 |
【追问链】(三层)
L1|“回滚也有风险怎么办?” → 发布前设计可回滚:DB 只加不删、双写兼容、配置开关、数据格式版本化。不可回滚的变更必须单独审批+更严格灰度。
L2|“灰度怎么分批?” → 按实例比例、按用户、按地域。每批设置最小观察时间(如 5–15 分钟)和自动卡点(错误率超阈值停止放量)。不要无观察连续放量。
L3|“回滚后错误率没降,说明什么?” → 根因可能不在本次代码:配置被改、依赖服务故障、数据已被污染、基础设施问题。要拉完整变更清单(代码+配置+依赖+数据)对照排查。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道回滚 |
| 80 分 | 回滚优先的理由;会说灰度再发布 |
| 95 分 | 回滚边界(DB/数据);不能回滚的替代方案;发布系统能力清单;根因分类 |
【关联题】
【自测】
- 发布后错误率飙升,第一动作是什么? 参考答案:评估能否快速回滚,能则立刻回滚止血,再定位。
- 什么情况下不能简单代码回滚? 参考答案:破坏性 DB 变更、新旧数据格式不兼容、配置与代码强耦合且已下发。
- 灰度发布为什么要有卡点? 参考答案:限制爆炸半径。每批观察错误率/RT,异常立即停,避免慢速全量故障。
175. 应用启动从 30 秒变成 5 分钟,甚至起不来(启动问题)
【考察内容】应用生命周期治理
【题目】应用之前 30 秒启动完,最近变成 5 分钟,有时直接启动失败。可能的原因(依赖服务不可用、数据库连接慢、初始化任务重、配置错误、端口冲突)?怎么排查?启动顺序与依赖检查怎么设计?
【参考答案】
启动阶段拆解:进程启动 → 加载配置(配置中心拉取)→ 连接依赖(DB/Redis/MQ/注册中心)→ Bean 初始化 → 完成启动;
慢的常见原因:
- 依赖连接超时重试:DB/Redis/MQ 不可达,启动时反复重试(配置连接超时短一点+快速失败);
- 注册中心:拉取大量服务列表/配置(网络慢);
- 初始化逻辑重:启动时加载大量数据/预热缓存/建连接池(建议异步化/懒加载);
- 大 jar 加载/类扫描(组件扫描路径过大);
- 容器环境:资源限制(CPU/内存不足)、磁盘慢;
启动失败:
- 看启动日志第一个异常(配置错误、Bean 创建失败、端口占用、依赖连不上);
- 常见:端口被占、数据库连接失败、配置缺失、版本不兼容;
启动顺序与依赖检查怎么设计(题干直问,不能只答「怎么变快」):分层启动=① 先做依赖探测(配置中心/DB/Redis/MQ 连通性,带短超时)→ ② 核心依赖不可达就 fail-fast,日志里明确写出是哪个依赖(不要静默重试到 5 分钟)→ ③ 非核心依赖改 @Lazy/异步初始化,失败则降级启动并记 warn(不阻塞进程)→ ④ 预热/建池/加载字典这类初始化任务挪到依赖就绪之后异步跑 → ⑤ 只有 readiness 通过才注册到注册中心、才接流量(否则半初始化的实例被上游当成可用,故障面更大)。配套手段:依赖快速失败(连接超时短)、懒加载非核心 Bean(@Lazy)、启动预热异步化、配置检查(启动自检)、健康检查(readiness 探针)、K8s
startupProbe必须大于最慢启动时间;监控:启动耗时指标、失败告警。
容量估算: 启动健康基线:Spring Boot 单体 30s 内正常,>2 分钟需排查,>5 分钟基本异常。常见耗时:DB/Redis 连接与建表校验、Nacos/ZK 注册、健康检查聚合、懒加载被触发、证书/网络超时(各客户端默认值不一:MySQL 驱动
connectTimeout默认 0=不限、Redis 客户端常见 2–10s,乘上依赖数与重试次数就放大成分钟级)。K8s 场景注意startupProbe的容忍窗口(failureThreshold × periodSeconds)必须大于最慢启动时间——配了 startupProbe 时 liveness/readiness 在它成功前不会执行,所以“启动-被杀”循环是 startupProbe 自己判杀的;只有没配 startupProbe 的老配置才靠放宽 liveness 的initialDelaySeconds兜。失败与降级: 发布中启动过慢:拉长就绪超时/放宽 probe 是缓解不是根治;紧急时回滚上一版本。将重依赖改为启动后异步预热;健康检查区分 liveness/readiness,避免未就绪就接流量。
【原理溯源】
为什么启动变慢常是“依赖重试”? 连接超时设太长(如 30s×多个依赖×重试次数)会把启动时间线性放大。应:连接超时设短(1–3s)、重试有上限、非核心依赖快速失败。
为什么要拆启动阶段打点? 不打点只知道“总耗时 5 分钟”,不知道卡在哪段。在配置拉取、各依赖连接、Bean 初始化前后打点,才能指向根因。
懒加载为什么有效? 默认 Spring 容器启动时实例化所有 Bean。
@Lazy把非核心 Bean 推迟到首次使用,减少启动关键路径。代价是首次请求变慢,需权衡。readiness 和 liveness 在启动期怎么用? 启动未完成时 readiness 失败,K8s 不把流量打进来;liveness 太灵敏会在启动慢时误杀进程。启动期防误杀首选配
startupProbe(它成功前 liveness/readiness 都不执行);只有没配 startupProbe 时才放宽 liveness 的 initialDelay(见第 6 条)。端口冲突/配置错误为什么表现为“起不来”? 启动是串行失败点:任一关键依赖失败即整体失败。看日志要找第一个 ERROR/Exception,后面往往是连锁反应。
【选型判断树】
启动慢/失败,先分"慢"还是"失败":
├─ 失败:看日志第一个异常
│ ├─ 端口占用 → 换端口/杀残留进程
│ ├─ 配置错误/缺失 → 校验配置中心
│ └─ 依赖连不上 → 网络/账号/依赖是否可用
└─ 慢:分阶段打点
├─ 配置拉取慢 → 配置中心/网络
├─ 依赖连接慢 → 超时太长/重试过多
├─ Bean 初始化慢 → 同步预热/全量加载 → 改异步/@Lazy
└─ 类扫描慢 → 缩小扫描包路径判断口诀: 失败看首异常;慢就分阶段打点。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “启动问题拆阶段,失败看首异常,慢看点位” |
| 0:30–1:30 | 阶段拆解 | 配置→依赖→Bean→就绪 |
| 1:30–2:30 | 常见慢因 | 依赖超时重试、同步预热、类扫描 |
| 2:30–3:30 | 失败因 | 端口、配置、依赖、版本 |
| 3:30–4:30 | 优化 | 懒加载、异步预热、快速失败 |
| 4:30–5:00 | 探针 | readiness/liveness 启动期配置 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 依赖连接超时 | 1–3s | 避免启动被拉长 |
| 重试次数(启动期依赖探测) | 有限次(如 3) | 快速失败,别让启动被重试拖成分钟级 |
| 分阶段打点 | 配置/DB/Redis/Bean | 定位慢点 |
| @Lazy | 非核心 Bean | 推迟初始化 |
| liveness | 首选配 startupProbe(failureThreshold×periodSeconds > 最慢启动时间);没配时才放宽 initialDelay | 防启动期误杀 |
| 目标 | 启动时间稳定可预期 | 监控告警 |
【追问链】(三层)
L1|“健康检查和就绪探针区别?” → liveness:进程是否活着,失败则重启容器;readiness:是否可接流量,失败则摘除。启动慢时 readiness 可失败(不接流量);防误杀首选配 startupProbe——它成功前 liveness/readiness 都不执行,放宽 liveness initialDelay 只是没配 startupProbe 时的兜法(见第 6 条)。
L2|“预热缓存放启动里还是异步?” → 小而关键的可同步(确保接流量前就绪);大而全的异步,否则启动被拖长。更好的做法是独立预热任务或流量灰度渐进预热。
L3|“容器里启动特别慢,怎么排查?” → 看 CPU limit 是否 throttle、内存是否吃紧、镜像拉取时间、emptyDir 磁盘、节点负载。应用内打点 + 容器指标对照。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道看启动日志 |
| 80 分 | 能拆阶段;说出依赖超时重试、懒加载 |
| 95 分 | 分阶段打点方法论;readiness/liveness;容器资源限制;预热策略权衡 |
【关联题】
- 同一知识簇: 第 172 题(Hang)、配置中心、K8s 探针
- 优化: 懒加载、异步初始化
- 预防: 启动耗时监控
【自测】
- 启动失败时日志应该重点看什么? 参考答案:第一个 ERROR/Exception,后面多为连锁反应。
- 为什么依赖连接超时设很长会拖慢启动? 参考答案:多个依赖×长超时×重试次数,时间线性叠加。应短超时、有限重试、快速失败。
- liveness 和 readiness 在启动慢场景如何配置? 参考答案:先配
startupProbe(failureThreshold×periodSeconds 大于最慢启动时间),它成功前 liveness/readiness 不执行;readiness 在就绪前失败以免过早接流量;只有没配 startupProbe 的老配置才靠放宽 liveness 的 initialDelay 兜(见第 6 条)。
176. 排查问题时发现关键日志缺失,或日志把磁盘打满(日志问题)
【考察内容】日志治理与可观测性
【题目】两个问题:①线上排查问题时发现关键日志缺失(日志框架异步丢、级别配错、buffer 丢失);②某服务日志量异常把磁盘打满。分别怎么排查和治理?日志规范(分级、采样、脱敏)怎么定?
【参考答案】
日志缺失排查:
- 日志级别(logback 动态调级别:线上 ERROR 会滤掉 INFO——确认是否级别问题);
- 异步日志丢失(AsyncAppender 队列满丢弃——确认是否队列溢出);
- 多实例只查了单台(日志在各自机器,需集中采集——确认是否采集链路问题);
- 代码没打日志(无日志=没发生?还是没记录?结合监控指标佐证);
- 日志被截断/轮转覆盖;
日志打满磁盘:见 171 题——日志级别、轮转(logrotate/Logback RollingFileAppender 按大小+保留份数)、采样(高 QPS 降采样)、集中采集到日志平台(本地少留);
最佳实践:
- 关键路径必须打日志(入参出参、异常堆栈、耗时);
- 日志格式统一(JSON+TraceID,便于检索与链路关联);
- 日志分级:ERROR 必打,业务关键节点 INFO,调试用 DEBUG(线上关闭);
- 日志平台(ELK)集中存储检索,本地只保留短期;
监控:日志采集延迟、本地磁盘告警、ERROR 量告警。
容量估算: 日志量经验:单应用 INFO 混打可达数十 GB/天;按“每请求日志字节×QPS×86400”估算。磁盘预留:日志分区只放日志,保留 ≥30% 空间;采集带宽与索引存储单独估算。采样策略:debug 不上生产常态,异常时动态打开短窗口(如 10 分钟)。
失败与降级: 日志打满磁盘:立刻调级+清理+外投;日志缺失:从网关 access、Trace、MQ、审计日志交叉重建时间线。业务降级不应依赖“日志一定在”,关键路径要有监控指标替代日志。
【原理溯源】
异步日志为什么会丢? AsyncAppender 有界队列,写入速度跟不上时按策略丢弃(默认丢 TRACE/DEBUG/INFO)。高峰期关键日志可能被丢。解法:队列调大只缓解;关键日志用同步或单独 Appender;监控丢弃计数。
为什么线上常只留 ERROR? 控制量与磁盘,但会丢失业务上下文。更好:关键业务节点 INFO 必打 + 高频路径采样 + 异步但监控丢弃。级别是“量与可排查性”的权衡。
TraceID 为什么是日志治理核心? 分布式一次请求跨多服务,没有统一 TraceID 无法串起链路。JSON 结构化 + TraceID 让日志可检索、可关联 APM,从“翻文件”变成“查链路”。
为什么 ERROR 也要限流/聚合? 异常风暴(同一堆栈每秒上万条)会打满磁盘、拖慢日志写入、淹没真正的新错误。应:相同异常合并计数、限流采样、聚合告警。
脱敏为什么必须做? 日志里手机号/身份证/银行卡/token 是合规红线。在日志框架层统一脱敏,而不是靠开发者自觉。
【选型判断树】
日志问题,先分缺失还是爆盘:
├─ 缺失
│ ├─ 级别滤掉 → 动态调级或补关键 INFO
│ ├─ 异步丢弃 → 查队列与丢弃计数;关键日志同步
│ ├─ 只查单机 → 上日志平台按 TraceID 查
│ └─ 轮转覆盖 → 调整保留策略/上平台
└─ 爆盘
├─ 无轮转 → logrotate / RollingFileAppender
├─ 量太大 → 降级采样、关 DEBUG、聚合异常
└─ 本地留太久 → 集中采集,本地只留短期判断口诀: 缺失查级别/异步/采集;爆盘查轮转/采样/集中化。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “日志问题两面:缺失影响排障,爆盘影响可用” |
| 0:30–2:00 | 缺失五因 | 级别、异步丢、单机、没打、轮转覆盖 |
| 2:00–3:00 | 爆盘治理 | 轮转、采样、集中 |
| 3:00–4:00 | 规范 | 分级、JSON+TraceID、脱敏 |
| 4:00–5:00 | 收尾 | “关键路径可追、量可控、敏感信息合规” |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 轮转 | 单文件切片 100–500MB 或按天 | 保留 7–30 份——只有按天切时「份」才等于天,按大小切时 7–30 份可能只覆盖几小时 |
| 本地保留 | 3–7 天(按级别分流、本地只留 ERROR 之后的量) | 其余上 ELK/平台 |
| 级别 | 线上关 DEBUG | 关键节点 INFO |
| 异步队列 | 监控丢弃次数 | 不能默默丢 |
| TraceID | 全链路必须带 | 关联 APM |
| 脱敏 | 手机号/身份证/token | 框架层统一 |
【追问链】(三层)
L1|“为什么关键日志用异步可能反而找不到?” → 高峰期队列满会丢弃低级别日志;若关键信息打在 INFO 且未保护,会被丢。关键路径可同步,或用单独高优先级 Appender,并监控丢弃。
L2|“日志都打 INFO 全量行不行?” → 不行。高 QPS 下磁盘与 IO 打满,还增加应用开销。应分级+采样:错误与关键节点全量,高频成功路径采样或聚合。
L3|“如何验证日志治理有效?” → 演练制造故障,检查:能否按 TraceID 拉全链路、磁盘是否稳定、丢弃计数是否为 0、敏感字段是否已脱敏。用“故障可排查”作为验收,而不是“日志文件存在”。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道调级别、配轮转 |
| 80 分 | 缺失五因分类(含轮转覆盖);轮转+采样+集中 |
| 95 分 | 异步丢弃机制;TraceID 与结构化;ERROR 聚合限流;脱敏合规;用演练验收 |
【关联题】
- 同一知识簇: 第 171 题(磁盘)、可观测性(指标/日志/追踪)
- 规范: TraceID、JSON 日志、脱敏
- 平台: ELK/Loki
【自测】
- 线上日志级别是 ERROR,排查时看不到 INFO,这是丢失吗? 参考答案:不是物理丢失,是级别过滤。可动态调级或事后补关键业务 INFO。
- 异步日志在什么情况下会丢日志? 参考答案:AsyncAppender 有界队列写满时按策略丢弃低级别日志。需监控丢弃并保护关键日志。
- 日志打满磁盘的三大治理手段? 参考答案:轮转限量、采样降量、集中采集本地少留。
177. 主从延迟涨到分钟级,用户看到旧数据(主从延迟事故)
【考察内容】主从架构故障治理
【题目】数据库主从延迟从毫秒级涨到分钟级,读库严重滞后:用户下单后查订单是旧的、库存显示不对。什么原因会导致延迟暴涨(大事务、DDL、从库性能)?应急怎么处理?长期怎么治理?
【参考答案】
确认延迟:
SHOW REPLICA STATUS(列名Seconds_Behind_Source;8.0.22 前是SHOW SLAVE STATUS与Seconds_Behind_Master,MySQL 8.4 起这一组旧语法已不再支持,老版本仍用旧写法)或监控平台;确认是“单从”还是“所有从”(单从=该从库问题;全从=主库压力大/大事务);常见根因:
- 主库大事务(大批量更新/删数据)——从库单线程重放慢(即使并行复制也受限);
- 主库写入压力大(QPS 高);
- 从库硬件弱/磁盘慢;
- 网络带宽/延迟;
- 长事务/无主键表(row 格式复制效率低);
- 从库回放 DDL(大表加索引/改字段)——DDL 在从库基本串行执行,一条跑几分钟就把延迟顶到分钟级,且并行复制也救不了它;处置:DDL 走 gh-ost/pt-osc 并放低峰窗口,延迟告警期间禁止再发 DDL。
应急:
- 关键读切主:只把「该用户这笔写后读」切回主库,不做关键读整体切主(整体切主=读写分离白做,见第 216 题与本题第 7 条);
- 临时摘除延迟严重的从库流量;
- 大事务场景:先 kill/等待大事务完成,减少后续影响;
根治:
- 拆大事务(批量分小批);
- 并行复制:MySQL 8.0.27 起
replica_parallel_workers默认 4(从库回放默认就是多线程,8.4 里把 0 当设置值已属废弃),slave_parallel_workers只是已废弃别名;5.7 与 8.0 早期才需要手动调; - 主库拆分/读写分离扩容(多个从库分担);
- 半同步复制/MGR 组复制:注意这是 RPO(丢数据)项,不缩短从库回放延迟,还给主库提交加一个网络往返——治延迟靠上面两条(与【选型判断树】、第 8 条同口径);
- 监控告警:延迟超过阈值(如 10s)告警;
业务层兜底:写后读走主库策略+缓存补偿(见 46/59 题)。
容量估算: 主从延迟可接受阈值:一般业务秒级;读己之写场景要求用户关键路径走主库或强制路由。延迟=主库写入耗时+网络+从库回放瓶颈;大事务/DDL 是分钟级延迟主因。监控:
Seconds_Behind_Source、从库线程状态、回放 TPS 对比主库。经验:批量导入时延迟可冲到分钟级,应错峰。失败与降级: 用户可感知的读(下单后查订单、支付状态)读主库或读缓存+版本号;「切回主」要限定范围:只把「写后短窗口内该用户的这笔关键读」路由回主库,不做「关键读整体切主」——本块第 1 项已判「全员读主=读写分离白做」,而题干里主库常常正是根因(写入风暴/大事务),9:1 的读写比下整体切主会把主库压力放大约 10 倍;延迟达阈值时优先动态把写后窗口拉长到当前延迟 P99、配异步补推与前端「稍后刷新」提示(宁可读到稍旧也不压垮主库),主库确实有余量时才按接口维度小比例回主并限流保护。禁止延迟期间做重分析查询打从库。极端时停从库只读业务,优先保写入与主库读。
【原理溯源】
为什么大事务是延迟头号杀手? 主库一个大事务在 binlog 里可能只需写一次,但从库要完整重放(更新 100 万行=重放 100 万行)。主库“一次性付出”,从库“顺序重放”,延迟被放大。
为什么“单从延迟、其他正常”指向该从库? 若所有从都延迟,根因在主库(大事务/写入风暴)或网络;只有一从延迟,查该从库磁盘/CPU/并行复制配置/大查询。
并行复制为什么能缓解? 传统单线程重放 binlog。并行复制按库/表/行冲突检测让多 worker 同时重放,提高吞吐。但单表热点大事务仍难并行。
半同步的代价与收益? 收益:至少一个从库确认收到 binlog 才提交,降丢数据风险。代价:提交延迟增加(多一次网络往返),极端时从库全挂会阻塞主库(取决于超时退化策略)。
业务为什么要“写后读主”? 复制是异步的,存在延迟窗口。下单后立刻查订单若走从库,可能读到旧状态。写后短窗口强制读主,或用缓存/版本号做会话一致性。
元理论对应: 原理 4「时间差、多副本视图与一致性窗口」+原理 7「对抗理性与可观测的认识论」(题群见《核心考点与元理论》§4.7+§7.7)
【选型判断树】
主从延迟暴涨:
├─ 看 Seconds_Behind_Source + 单从还是全从
│ ├─ 全从延迟 → 主库大事务/写入风暴 → kill/拆事务
│ └─ 单从延迟 → 该从库:磁盘/并行复制/大查询
├─ 应急
│ ├─ 写后读 → 只把「写后短窗口内该用户的这笔关键读」路由回主(关键读整体切主是被禁止的:主库常正是根因)
│ ├─ 延迟从库 → 摘流量
│ └─ 正在执行的大事务 → 评估 kill
└─ 根治
├─ 拆大事务、并行复制
├─ 扩从库;半同步/MGR 另列为 RPO 项(不减回放延迟,还会加主库提交延迟)
└─ 业务:写后读主 + 延迟告警判断口诀: 先看单从还是全从,再查大事务,应急拉长写后窗口、只回该用户这笔读(不是整体切主)。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “延迟先看单从还是全从,指向不同根因” |
| 0:30–1:30 | 大事务机制 | 主库一次、从库重放放大 |
| 1:30–2:30 | 其他根因 | 从库硬件、网络、无主键 |
| 2:30–3:30 | 应急 | 写后短窗口内该用户读主(+主库限流)、摘流量、处理大事务 |
| 3:30–4:30 | 根治 | 拆大事务、并行复制、从库扩容;半同步属 RPO 项,不缩短回放延迟 |
| 4:30–5:00 | 业务兜底 | 写后读主、缓存、延迟告警 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 健康延迟 | 通常 <1s | 业务相关 |
| 告警阈值 | >10s 常见 | 按业务 |
| 复制状态命令 | SHOW REPLICA STATUS 的 Seconds_Behind_Source | 8.4 起旧语法与旧列名不可用 |
| 并行复制 | replica_parallel_workers(8.0.27 起默认 4) | 按核数配 |
| 大事务 | 避免单事务 >1万行 | 分批提交 |
| 半同步 | 至少一个从确认 | 降丢数风险 |
【追问链】(三层)
L1|“并行复制为什么快?” → 多 worker 并行重放不同库/表或无冲突事务,突破单线程重放瓶颈。热点单表大事务仍受限,所以还要拆事务。
L2|“能不能重启从库解决延迟?” → 不优先。重启有丢位点/主从断开风险,且根因(大事务/硬件)还在。应先处理大事务、摘流量、查从库资源。重启是最后手段且要确认 GTID/位点。
L3|“写后读主会不会把主库打爆?” → 只对“写后短窗口关键读”强制主库,不是所有读。可结合缓存写后失效、会话粘滞、版本号。全量读主会失去读写分离意义。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道有主从延迟,看监控 |
| 80 分 | 大事务是主因;应急只回「写后短窗口的这笔读」并限流保护主库(不是关键读整体切主);并行复制 |
| 95 分 | 单从 vs 全从判断;重放放大机制;半同步代价;业务写后读主策略 |
【关联题】
- 同一知识簇: 主从延迟业务方案(46/59)、半同步/MGR
- 联动: 第 183 题(误操作与 binlog)
- 监控: Seconds_Behind_Source 告警
【自测】
- 所有从库都延迟,最可能的原因是? 参考答案:主库大事务或写入压力,而不是单个从库问题。
- 为什么大事务会造成分钟级延迟? 参考答案:从库需完整串行/有限并行重放该事务,耗时与事务大小成正比,延迟被放大。
- 写后读为什么要可能走主库? 参考答案:异步复制有延迟窗口,写后立刻读从库可能读到旧数据;短窗口强制读主保证会话一致性。
178. 大促期间错误率从 0.1% 涨到 30%(错误率飙升分诊)
【考察内容】错误率分诊是 SRE/后端高频场景题
【题目】大促进行中,核心接口错误率从 0.1% 突然涨到 30%。怎么快速分诊:先看哪类错误(超时/5xx/业务异常)、按错误码聚合、按机房/实例拆分、按参数/用户群拆分?怎么在 10 分钟内给出结论?
【参考答案】“先分类再定位”:
看错误类型分布(监控/日志聚合):
- 超时类(连接超时/读超时):下游变慢或连接池耗尽;
- 5xx/异常类(Exception/HTTP 500):代码异常(空指针/数据问题)或依赖返回错误;
- 连接拒绝/资源类(Too many connections/线程池拒绝):容量打满;
- 限流熔断类(被限流/被熔断):保护机制触发(说明上游或自身过载);
按分布缩小范围:
- 全接口 vs 单接口(单接口=该接口逻辑/依赖问题);
- 全实例 vs 单实例(单实例=该机器问题);
- 全用户 vs 特定用户(特定用户=数据/权限问题);
- 按请求参数/业务号聚合找公共入参(「按参数拆分」是第 4 个维度,只拆接口×实例×用户会漏):把报错请求按入参维度 group by——商品 ID/商户 ID/渠道/城市/客户端版本/是否携带某字段,若 30% 错误集中在某个 itemId 或某个参数组合,就是数据或热点问题(脏数据、热点 key、某渠道超长参数),不是容量问题;
结合发布记录:是否刚发布(回滚)?是否配置变更?
工具:错误日志(Exception 堆栈聚合)、调用链(失败 Span)、APM 错误率、GC/CPU 联动;
处置:止血(回滚/扩容/限流/降级)→ 根因修复 → 验证。
容量估算与分诊: 错误率 0.1%→30% 是数量级跳变,不是缓慢劣化,优先查:发布、配置、依赖挂了、流量攻击/爬虫、DB/Redis 故障。分诊树按影响面:全接口 vs 单接口;全实例 vs 单实例/单机房;全部用户 vs 单渠道。时间对齐:把错误开始时刻与发布/配置/扩缩容/依赖事件对齐(±2 分钟)。
失败与降级: 分诊同时降级:核心接口限流保成功率,非核心熔断;DB 故障则只读/排队;错误风暴时网关返回统一兜底页,避免重试风暴。每 5 分钟同步影响面与决策。
【原理溯源】
为什么要先按错误类型分? 不同类型指向不同层:超时=依赖/容量;5xx=代码/数据;拒绝=池/线程;限流=保护已触发。10 分钟分诊的本质是用分类排除 80% 错误方向。
限流导致的错误算故障吗? 算保护性响应。说明容量不足或阈值不合理。要区分“限流在保核心”还是“限流误伤核心”。前者找容量,后者调规则。
为什么要按实例/机房拆? 单实例错误=该机问题(坏盘、宿主机、本地配置);单机房=机房网络/基础设施。全量=代码/依赖/容量。维度拆分是分诊最快路径。
和发布时间对齐为什么重要? 变更是故障最大来源。错误开始时刻与发布/配置变更对齐,优先验证回滚是否恢复,可以跳过大量盲查。
10 分钟分诊节奏: 0–2min 看类型分布;2–5min 按接口/实例/用户/请求参数四维拆;5–8min 对变更与依赖;8–10min 给出止血动作与初步根因假设。
元理论对应: 原理 2「过载动力学与雪崩正反馈」+原理 7「对抗理性与可观测的认识论」(题群见《核心考点与元理论》§2.7+§7.7)
【选型判断树】
错误率飙升:
├─ 先看错误类型
│ ├─ 超时 → 下游/池/GC/网络
│ ├─ 5xx 异常 → 代码/数据/依赖返回错
│ ├─ 连接拒绝 → 容量打满
│ └─ 限流熔断 → 过载保护,查容量与规则
├─ 再看分布
│ ├─ 单接口 → 该接口
│ ├─ 单实例 → 该机器
│ ├─ 单用户群 → 数据/权限
│ ├─ 按参数/业务号聚合 → 公共入参(itemId/商户/渠道/版本)=脏数据或热点
│ └─ 全局 → 发布/配置/公共依赖
└─ 对齐变更 → 有则优先回滚验证判断口诀: 类型→分布→变更,三步缩到可行动结论。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “错误率分诊=先分类再定位,10 分钟出结论” |
| 0:30–2:00 | 四类错误 | 超时/5xx/拒绝/限流各自含义 |
| 2:00–3:00 | 四维拆分 | 接口 × 实例/机房 × 用户 × 请求参数/业务号(第四个维度) |
| 3:00–4:00 | 变更对齐 | 发布/配置优先验证 |
| 4:00–5:00 | 处置 | 止血→根因→验证 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 分诊目标 | 10 分钟内初步结论 | 先止血 |
| 观察粒度 | 1 分钟曲线 | 看拐点 |
| 错误聚合 | 按异常类型/错误码 | TopN |
| 变更窗口 | 错误开始时间对齐发布时刻 | 高相关 |
| 止血顺序 | 回滚/限流/降级/扩容 | 按场景 |
【追问链】(三层)
L1|“超时类错误首先查什么?” → 调用链看哪个 Span 超时;再查连接池、下游 RT、GC。超时是“慢”不是“错”,根因常在依赖或容量。
L2|“全实例都错,说明什么?” → 更可能是代码、配置、公共依赖、DB/缓存等全局因素,而不是单机问题。优先查变更与公共组件。
L3|“怎么防止错误率告警噪声?” → 基线+同比/环比,区分绝对阈值与突增;按接口分级;错误类型聚合;抑制已知瞬时抖动。目标是“真故障必报、噪声不吵人”。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 看日志、看监控 |
| 80 分 | 能按错误类型、实例/接口、用户群、请求参数/业务号四个维度拆分 |
| 95 分 | 四类错误含义;变更对齐;限流是否算故障;10 分钟节奏;止血优先 |
【关联题】
【自测】
- 错误类型是“连接被拒绝/线程池拒绝”,首先说明什么? 参考答案:容量或资源打满(池/线程/连接数),而不是单纯代码逻辑错误。
- 单实例错误率高、其他正常,优先查什么? 参考答案:该实例:宿主机、磁盘、本地配置、坏节点,考虑摘除。
- 限流触发导致错误率上升,算不算事故? 参考答案:算保护性事件。说明过载,需评估容量与限流规则是否合理,避免误伤核心。
179. 凌晨 3 点 QPS 暴涨 10 倍,值班工程师怎么办(突发流量应急)
【考察内容】值班应急是综合场景题
【题目】凌晨 3 点被告警叫醒:QPS 暴涨 10 倍(疑似热点事件),错误率开始上升。值班工程师的处理顺序是什么?先保什么(限流/降级/扩容)?怎么判断要不要叫醒负责人?事后怎么复盘?
【参考答案】按“保可用→止血→定位→根治”:
确认影响:看监控(QPS、RT、错误率、GC、连接池)判断严重程度(P0/P1);确认流量来源(哪个接口/页面);
止血(按序):
- 接入层限流(Nginx/网关限流阈值调低,保护系统);
- 降级非核心功能(推荐/通知/积分关闭,保核心链路);
- 热点数据本地缓存/预热;
- 扩容(如果基础设施支持,加实例);
- 数据库保护(限流、慢 SQL kill、连接池保护);
定位根因:是真实用户热点(正常流量,需扩容+优化)还是攻击(限流+风控);热点 Key/接口定位(监控 TopN);
根治与跟进:优化热点链路(缓存/异步)、沉淀预案(下次自动触发)、复盘记录; 4.5 要不要叫醒负责人(题干第三问):出现 P0(全站不可用/资金错误/数据丢失)、影响面仍在扩大、需要跨团队资源、或处置超出 SOP 授权范围——立刻叫,不用先定位完。叫醒是换资源与决策权,不是推卸执行;反过来,能按 SOP 止血的先止血再同步。
值班纪律:先恢复再排查(用户可感知的故障优先止血)、按 SOP 操作、同步信息到群、事后复盘。
容量估算: QPS×10 时先判断是真实流量还是攻击/重试/爬虫。真实扩容需求:机器数≈当前机器数×10×(单机当前实际承载 QPS ÷ 单机压测安全容量),但 DB/Redis/下游往往先到瓶颈,扩容应用可能无效甚至放大下游压力。限流阈值建议:先限到压测得到的系统安全水位(压测容量的 70–80%,与第 173 题同口径);“昨天同时段×1.5”只能当需求侧参照,不是容量上限,再逐步试探。带宽与连接数同样要算。
失败与降级: 第一步限流+屏蔽非核心;第二步扩容有状态风险要评估;第三步对爬虫/攻击启用防护(WAF、验证码)。降级顺序:推荐/营销 → 非核心写 → 只读模式 → 排队。保下单支付登录链路。
【原理溯源】
为什么止血顺序是限流→降级→扩容? 限流最快(配置级),立刻减少进入系统的压力;降级释放资源给核心链路;扩容要时间(拉起实例、预热)。先用秒级动作稳住,再用分钟级动作扩容量。
为什么要区分真实热点还是攻击? 真实热点:业务成功,应扩容+优化热点链路;攻击:无业务价值,应限流+风控+封禁。处置策略完全不同,误判要么放大损失,要么赶走真实用户。
为什么“先恢复再排查”? 用户可感知故障每分钟都在损失。根因分析可以事后做,止血必须立刻做。这是值班与开发思维的关键差异。
热点为什么容易凌晨炸? 热点事件(热搜、事故、营销)不受作息限制;且凌晨值班人力少、部分任务(批处理、备份)可能叠加。监控必须 7×24,不能依赖人工发现。
叫醒负责人的判断标准? P0(全站不可用/资金错误/数据丢失)立刻叫;影响面扩大、需要跨团队资源、超出 SOP 授权时叫。叫醒是为了资源与决策,不是推卸执行。
元理论对应: 原理 2「过载动力学与雪崩正反馈」+原理 7「对抗理性与可观测的认识论」(题群见《核心考点与元理论》§2.7+§7.7)
【选型判断树】
QPS 暴涨:
├─ 先判断影响级别
│ ├─ 核心交易受损 / 全站 → P0,立刻限流+叫负责人
│ └─ 非核心接口 → 按 SOP 降级处理
├─ 止血动作
│ ├─ 秒级:网关限流阈值下调
│ ├─ 秒级:关闭非核心功能
│ ├─ 分钟级:扩容、热点缓存
│ └─ 保护 DB:限流、kill 慢SQL
└─ 定位
├─ TopN 接口/热点 Key
├─ 来源:用户 vs 攻击 IP
└─ 是否与定时任务/发布重叠判断口诀: 先保核心,限流降级最快;再扩容;最后归因优化。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “值班应急:先恢复再排查” |
| 0:30–1:30 | 确认影响 | 监控判断 P0/P1,看流量来源 |
| 1:30–3:00 | 止血顺序 | 限流→降级→扩容→护 DB |
| 3:00–4:00 | 归因 | 真实热点 vs 攻击 |
| 4:00–5:00 | 升级与复盘 | 何时叫负责人;事后沉淀预案 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 止血优先级 | 限流 > 降级 > 扩容 | 越快越好 |
| 限流 | 网关先限,应用兜底 | 阈值可动态调 |
| 降级清单 | 推荐/通知/积分等非核心 | 保交易 |
| 扩容 | 有状态预热,无状态快 | 有预案 |
| 升级 | P0 立刻叫;超出 SOP 也叫 | 资源决策 |
| 复盘 | 沉淀自动触发条件 | 下次不用人肉 |
【追问链】(三层)
L1|“如何区分攻击和热点?” → 来源分布(IP/UA 集中=攻击)、行为特征(无登录/无转化/固定频率)、与历史流量对比、业务是否产生真实交易。可叠加风控与验证码。
L2|“限流把真实用户也挡了怎么办?” → 分层限流:网关粗限保护系统;应用按用户/接口细限;核心链路高优先级。监控被限用户比例,动态调阈值。宁可短暂影响部分用户,也不全站雪崩。
L3|“值班能不能直接改生产配置限流?” → 按授权与 SOP。预授权的动态阈值可调;重大变更需记录+事后审批。关键是可审计、可回滚,而不是完全不能动。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道限流或扩容 |
| 80 分 | 有止血顺序;会区分热点与攻击 |
| 95 分 | 先恢复再排查纪律;升级标准;降级清单思维;预案自动化沉淀 |
【关联题】
【自测】
- 凌晨 QPS 暴涨,止血第一动作通常是什么? 参考答案:接入层限流(网关阈值下调),最快减少系统压力。
- 为什么要区分真实热点和攻击? 参考答案:真实热点要扩容优化保业务;攻击要限流封禁止损。策略相反。
- 什么情况应该叫醒负责人? 参考答案:P0 全站/资金/数据事故;影响扩大;需要跨团队资源;超出值班 SOP 授权。
180. 配置中心一个开关配错,全量用户受影响(配置事故)
【考察内容】配置治理与事故响应
【题目】有人在配置中心把某个功能开关从 true 改成 false,配置实时推送后全量用户受影响。怎么快速止血?配置中心支持回滚吗?怎么避免这类事故(灰度发布、审批、预览、变更审计)?
【参考答案】
立即回滚配置:配置中心一键回滚到上一个正确版本(动态刷新,无需重启)——这是配置事故的第一动作;
确认影响面:受影响的实例/流量范围(是否已全量生效)、业务影响(功能不可用/数据错误);
评估数据影响:如果配置错误导致脏数据(如错误的价格/折扣)——评估是否需要数据修复(对账/补偿),先冻结相关操作;
根治:
- 配置变更流程:灰度发布(先小范围实例/用户验证)→ 全量;
- 配置校验:发布前自动化校验(类型/范围/正则/前后对比);
- 配置审计:变更记录(谁、何时、改了什么)+审批;
- 监控:配置生效后关键指标(错误率/业务量)自动比对告警;
复盘:更新配置操作 SOP、紧急回滚演练。
容量估算与流程: 配置变更爆炸半径:全量配置 vs 灰度配置;单开关影响面应能在变更单里写清楚。灰度阶梯要按变更类型分两套,别混用:① 代码发布(换制品、回滚要重切流量)→ 1% → 5% → 20% → 50% → 100%,每档观察 5–15 分钟(与第 174 题同口径),因为代码缺陷要靠时间和流量形态才暴露;② 配置/开关变更(秒级可回滚、推送后全集群同时生效)→ 先 1 个实例灰度推送 → 1% → 10% → 50% → 全量,每档 3–10 分钟即可,理由是可回滚成本极低、拖长窗口只是延长风险暴露时间;③ 高危参数(限流阈值、资金开关、风控规则)不做按用户比例放量,改走「按实例灰度 + 取值范围校验 + 双人审批」——同一用户在不同实例上拿到不同阈值本身就是故障。配置中心可用性:配置读取应有本地快照,中心挂了还能用上次配置。审计:谁改的、改了什么、何时生效、回滚版本号。
失败与降级: 一发现配错:立即回滚配置(秒级),比改代码快;必要时摘流对应功能。对“错误开关打开导致打挂下游”:同时对下游熔断。事后:配置变更强制双人复核+自动 diff+影响面检查。
【原理溯源】
为什么配置事故比代码事故更快? 配置动态推送秒级全量生效,爆炸半径大且快;代码还要构建部署。所以配置必须有同等甚至更严的灰度与审批,不能因为“只是改个开关”就放松。
为什么第一动作是回滚配置而不是分析? 和发布事故同理:止血优先。配置中心若有历史版本,一键回滚秒级恢复。先恢复再分析为什么改错。
配置灰度怎么做? 按实例分组下发,或配置值内嵌生效条件(用户尾号、地域、白名单)——仅限普通配置;限流阈值、资金开关、风控规则这类高危参数不做按用户放量,只按实例灰度(见第 6 条)。阶梯起点是 1 个实例,验证指标后再按 1%→5%→20%→50%→100% 放量。
为什么要“前后对比”校验? 防止误把生产值改错、类型从 boolean 变 string、数值少一个数量级。发布前展示 diff + 自动规则校验。
脏数据为什么要先冻结? 若错误配置已产生错误订单/价格,继续写会扩大污染。先冻结相关写入,再评估对账补偿,顺序不能反。
【选型判断树】
配置事故:
├─ 第一动作:一键回滚上一版本(动态生效)
├─ 确认影响面:实例范围、用户范围、是否有脏数据
│ ├─ 仅功能不可用 → 回滚后验证指标恢复
│ └─ 产生脏数据 → 冻结写入 + 对账/补偿
└─ 根治
├─ 灰度下发、发布前 diff+校验
├─ 审批与审计
└─ 生效后指标自动比对告警判断口诀: 回滚第一;有脏数据先冻结;再补灰度与校验。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “配置动态推送=快速全量,事故处置回滚优先” |
| 0:30–1:30 | 止血 | 一键回滚、确认生效 |
| 1:30–2:30 | 影响评估 | 功能 vs 脏数据,脏数据要冻结 |
| 2:30–3:30 | 根治 | 灰度、校验、审计 |
| 3:30–4:30 | 监控 | 生效后指标比对 |
| 4:30–5:00 | 收尾 | “配置与代码同级管控” |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 回滚 | 秒级动态生效 | 第一动作 |
| 灰度阶梯 | 代码发布:1%→5%→20%→50%→100%,每档 5–15 分钟;配置/开关:1 实例→1%→10%→50%→全量,每档 3–10 分钟 | 按变更类型分两套,别混用;高危参数不做比例放量,改按实例灰度+取值范围校验+双人审批 |
| 校验 | 类型/范围/diff | 发布前 |
| 审计 | 谁/何时/改了什么 | 必留痕 |
| 指标比对 | 错误率、业务量 | 自动告警 |
【追问链】(三层)
L1|“配置回滚后没生效怎么办?” → 确认推送是否成功、实例是否全部拉到新版本、有无本地缓存配置。必要时重启实例强拉。同时看变更是否涉及需要重启才能生效的项。
L2|“配置灰度和代码灰度一样吗?” → 目标一样(限爆炸半径),实现不同。配置可按实例分组动态生效,通常比代码灰度更灵活更快,但仍要卡点观察。「按用户规则放量」对普通配置可用;对高危参数(风控阈值、利率、限额)不能这么做——同一用户在不同实例上拿到不同阈值本身就是故障,这类只按实例灰度+取值范围校验+双人审批。
L3|“如何防止有人在配置中心直接改生产?” → 权限最小化 + 双人复核 + 高危配置模板锁定 + 紧急变更通道留痕。技术手段拦不住所有误操作,制度与审计要补位。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道改回去 |
| 80 分 | 一键回滚;会说灰度 |
| 95 分 | 配置与代码同级管控;脏数据冻结;校验+审计+指标比对;误操作制度 |
【关联题】
- 同一知识簇: 第 174 题(发布事故)、配置中心架构
- 治理: 灰度、审批、审计
- 数据: 对账补偿
【自测】
- 配置中心改错,第一动作是什么? 参考答案:立即一键回滚到上一个正确版本,动态生效止血。
- 为什么配置变更也需要灰度? 参考答案:动态推送会秒级全量生效,爆炸半径大。灰度限制影响面并允许指标验证。
- 错误配置已经产生脏数据,处置顺序? 参考答案:先冻结相关写入,再评估对账/补偿,不要边污染边修。
181. 堆内存从 2G 涨到 4G,不 OOM 但 GC 频繁 RT 变差(内存上涨排查)
【考察内容】内存治理进阶
【题目】服务堆内存缓慢从 2G 涨到 4G(堆上限 8G),虽然没 OOM,但 GC 越来越频繁、RT 越来越差。是泄漏吗?还是缓存/集合在增长?怎么区分?怎么定位增长来源?
【参考答案】
判断性质:GC 后是否回落(回落=对象潮汐,正常但容量不足;不回落=疑似泄漏);
堆内排查:
- jmap -histo 看对象分布(哪个类对象多);
- 本地缓存/静态集合(Caffeine 容量配置是否合理、Map 无界);
- ThreadLocal 堆积(线程池线程多,值不清理);
- 大集合(一次查询加载海量数据进内存);
- dump+MAT(持续增长对象,见泄漏题);
堆外排查(堆没涨但内存涨):
- 直接内存(DirectByteBuffer/NIO 未释放);
- 线程数暴涨(每线程栈内存);
- 元空间(类加载泄漏,-XX:MaxMetaspaceSize);
- 压缩类空间;
解决:修根因(缓存淘汰/集合分批/资源释放)→ 调参(-Xmx、GC 策略)→ 监控(堆、GC、线程数、堆外)告警;
预防:压测观察内存曲线基线、定期 dump 分析、容量规划。
容量估算: 堆 2G→4G:先看是稳定水位抬升还是缓慢爬升。Full GC 后水位稳定在 3.5G 说明存活对象真的变多(缓存/泄漏/流量上涨导致 in-flight 变多)。GC 频率经验值:Young GC 秒级可接受,Full GC 小时级以内视堆而定,分钟级必查。调优前先算分配速率:
jstat -gcutil看 YGC 次数与耗时。失败与降级: RT 变差时先限流减负;可临时扩堆止血,但要设定观察期限(如 24h)内必须定位。关闭可疑大缓存/同步任务。若为流量上涨导致的合理内存增加,走扩容而非“修泄漏”。
【原理溯源】
“不 OOM 但 GC 频繁”为什么更危险? OOM 是硬失败易发现;GC 频繁是慢性性能病,RT 变差、吞吐下降,用户体感差但告警可能不响。可用性已经在受损。
为什么看 GC 后回落? 同 167 题:回落=合法对象潮汐;不回落=强引用持有。这是区分“容量不足/缓存增长”与“泄漏”的最快判据。
堆和 RSS 为什么要分开看? 进程 RSS 含堆、元空间、直接内存、线程栈、native。堆没涨而 RSS 涨,要查堆外。只盯 -Xmx 会漏掉 Netty 直接内存、线程暴涨。
线程数为什么吃内存? 每线程默认栈约 1MB(-Xss)。1000 线程≈1GB。线程池无界或每请求一线程会把内存吃光,且不是堆内,-Xmx 管不到。
缓存“合法增长”也要治理吗? 要。即使不是泄漏,无上限缓存会挤压堆、增加 GC 成本。必须设 maximumSize/expire,把增长变成可预期的稳态。
【选型判断树】
内存缓慢上涨、GC 频繁、未 OOM:
├─ 先分堆内 vs 进程 RSS
│ ├─ 堆内涨
│ │ ├─ GC 后回落 → 缓存/潮汐/容量;设上限或扩堆
│ │ └─ 不回落 → 泄漏路径(167 题双 dump)
│ └─ RSS 涨但堆稳定 → 堆外
│ ├─ NMT 看线程/直接内存/元空间
│ └─ 线程数、Netty 池、类加载
└─ 处置:修根因优先,调参其次,监控兜底判断口诀: 先分堆内堆外,再问 GC 后回不回落。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “慢性 GC 问题:先分堆内/堆外,再分泄漏/潮汐” |
| 0:30–1:30 | 危害 | 不 OOM 但 RT 变差,可用性受损 |
| 1:30–3:00 | 堆内 | histo、缓存、ThreadLocal、大集合 |
| 3:00–4:00 | 堆外 | 直接内存、线程栈、元空间 |
| 4:00–5:00 | 收尾 | “修根因+有界缓存+监控基线” |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| jmap -histo | 低开销看对象计数 | 先粗定位 |
| 线程栈 | 默认 ~1MB/线程 | 1000 线程≈1GB |
| NMT | Native Memory Tracking | 查堆外 |
| 缓存 | 必须 maximumSize/expire | 有界 |
| 告警 | GC 频率、堆低点抬升、线程数 | 基线对比 |
| 大查询 | 分批/流式 | 避免全量进内存 |
【追问链】(三层)
L1|“直接内存泄漏怎么查?” → 开启 NMT;监控 DirectByteBuffer;排查 Netty/ NIO 池未 release;调 -XX:MaxDirectMemorySize 并观察。
L2|“线程数暴涨为什么吃内存?” → 每线程独立栈,默认约 1MB。线程数失控时内存被栈吃掉,且发生在堆外,调 -Xmx 无效。要限线程池与每请求线程模型。
L3|“调大堆能缓解 GC 频繁吗?” → 若是分配过快且对象合法,调大可降低频率但增加单次成本;若是泄漏或无界缓存,只是推迟问题。先定位增长源,再决定扩容堆还是改代码。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道看堆内存、可能要 dump |
| 80 分 | 分堆内/堆外;会用 histo;知道有界缓存 |
| 95 分 | GC 后回落判据;线程栈与 NMT;慢性 GC 的可用性危害;监控基线 |
【关联题】
【自测】
- 堆没涨但进程内存涨,先查什么? 参考答案:堆外——直接内存、线程数/栈、元空间;可用 NMT。
- 如何区分缓存正常增长和泄漏? 参考答案:Full GC 后是否回落。回落=潮汐/容量;不回落且低点抬升=泄漏。
- 判断:没 OOM 就不用管内存上涨。 参考答案:错。GC 频繁已导致 RT 变差、吞吐下降,是慢性可用性损伤。
182. 大部分时间正常,每天某时段偶发超时(间歇性抖动)
【考察内容】间歇性故障的排查方法论
【题目】接口平时很正常,但每天固定几个时段(比如 10 点、14 点)会偶发一批超时,几分钟后自己恢复。可能是定时任务、其他业务高峰、GC、依赖方定时任务等原因。怎么用监控数据定位?
【参考答案】
先找规律:按时间(定时任务时段?整点?)、按请求特征(特定用户/特定参数)、按实例(特定机器);
常见“间歇性”根因:
- 定时任务与大流量重叠:整点批处理任务(对账/归档/报表)与业务高峰抢资源——看定时任务执行时间;
- GC 停顿:偶发 Full GC(对象潮汐)——GC 日志与超时时间点对齐;
- 缓存过期潮:大量 key 同时过期导致回源 DB(雪崩)——看缓存 TTL 分布;
- 大请求污染:单个大请求(大查询/大对象)占住线程/带宽,拖慢其他请求(长尾)——按耗时分布看 P99 与单请求;
- JIT 编译(启动初期);
- 外部依赖抖动:下游/网络偶发;
- 资源竞争:磁盘 IO 突刺(备份/日志刷盘);
定位工具:调用链按时间段聚合(哪个时段慢在哪一环)、监控曲线叠加(GC/IO/定时任务时间轴对齐)、抓现场(Arthas 持续观测);
解决:错峰定时任务、TTL 随机化、大查询拆分限流、GC 调优、依赖超时重试。
容量估算: 间歇性问题定位法:把时间轴拉长 7–30 天,对齐定时任务(Job、日切、对账)、流量峰谷、缓存过期点、证书/Token 续期、批处理。抖动预算:若某时段每天固定 X 点超时,优先查同时间任务。监控粒度:1 分钟可能掩盖尖刺,关键接口上 10s/30s 桶。
失败与降级: 业务可接受时对该时段任务错峰/降速;核心接口与批处理资源隔离(独立线程池/集群)。用户侧对抖动接口加重试与超时退避,减少放大。
【原理溯源】
间歇性故障为什么难? 常态监控看不到,必须“时间对齐”。把 GC、定时任务、备份、缓存过期、下游任务的曲线叠在同一时间轴,重叠即嫌疑。
定时任务为什么爱在整点? cron 默认整点/整分。多个系统同时启动批处理,造成资源尖峰。解法:错峰(加随机延迟)、降优先级、资源隔离。
缓存过期潮是什么? 大量 key 在同一时刻写入,TTL 相同→同时过期→瞬间回源 DB。解法:TTL 加随机抖动(如 30min±10%)。
大请求污染机制? 大查询占住连接/线程/CPU/带宽,其他请求被拖慢。表现为“一批超时”而非全挂。要按请求大小/类型拆分限流。
怎么证明是 GC? GC 停顿时间点与超时点毫秒级重叠,且停顿期间所有线程 STW。用 GC 日志与业务超时日志对齐。
【选型判断树】
间歇性超时:
├─ 先固定维度:时间点、请求特征、实例
├─ 时间对齐叠曲线
│ ├─ 与定时任务重叠 → 错峰/资源隔离
│ ├─ 与 GC 停顿重叠 → 调优/查分配
│ ├─ 与缓存 TTL 批量过期重叠 → TTL 随机化
│ └─ 与备份/IO 突刺重叠 → 任务调度
└─ 请求特征对齐
├─ 大查询/大报文 → 拆分限流
└─ 特定用户/参数 → 数据/业务逻辑判断口诀: 找规律 → 叠时间轴 → 对齐后治标治本。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “间歇性故障靠时间对齐,不靠瞎猜” |
| 0:30–1:30 | 找规律 | 时间/请求/实例三维 |
| 1:30–3:00 | 常见根因 | 定时任务、GC、缓存过期潮、大请求 |
| 3:00–4:00 | 对齐方法 | 多曲线同时间轴 |
| 4:00–5:00 | 治理 | 错峰、TTL 抖动、拆分、调优 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 时间对齐 | 1 分钟或更细粒度 | 看重叠 |
| TTL 抖动 | ±10%–20% | 防过期潮 |
| 定时任务 | 避开整点,加随机延迟 | 削峰 |
| 观察窗口 | 至少连续数天同时间段 | 确认规律 |
| 大查询 | 分页/流式 | 防污染 |
【追问链】(三层)
L1|“怎么证明是 GC 导致?” → GC 日志停顿时刻与超时时刻重叠(毫秒级),且 GC 期间所有业务线程 STW。曲线对齐 + 堆/GC 指标突变。
L2|“定时任务为什么不能和业务高峰重叠?” → CPU/IO/连接/锁被批处理抢占,业务 RT 拔高。应错峰、限流、资源隔离(独立线程池/从库执行)。
L3|“抓不到现场怎么办?” → 靠历史监控曲线规律复盘;下次复现前布置:Arthas 持续观测、更细日志、dump 策略。间歇性问题往往“监控比现场更有用”。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 猜定时任务或 GC |
| 80 分 | 会说时间对齐、TTL 随机化 |
| 95 分 | 多曲线叠加方法论;大请求污染;错峰与资源隔离;用监控复盘 |
【关联题】
【自测】
- 每天固定时段超时,最先建立的分析习惯是? 参考答案:把 GC、定时任务、备份、缓存指标叠在同一时间轴上看重叠。
- 缓存过期潮如何预防? 参考答案:TTL 加随机抖动,避免同批 key 同时过期回源。
- 判断:间歇性故障因为难复现,只能等下次再抓现场。 参考答案:错。用历史监控曲线做时间对齐往往能定位;同时可预置观测等待复现。
183. 一条 UPDATE 忘加 WHERE,全表数据被改(数据误操作恢复)
【考察内容】误操作恢复是数据库运维最高频事故题
【题目】同事执行 UPDATE 忘了加 WHERE,整表数据被改(或 DELETE 全删)。怎么恢复?前提条件是什么(binlog、备份策略)?恢复步骤怎么走?怎么防止此类事故再发生(规范、审计、备份演练)?
【参考答案】
立即止血:确认影响范围(哪些表/库),必要时冻结相关写入(防止新数据污染恢复);
恢复手段(按可用性排序):
- binlog 恢复:用 binlog2sql 这类闪回工具(解析 binlog 生成反向 SQL——把 UPDATE 转成原值恢复、DELETE 转 INSERT;注意美团原仓已下架、现存社区版最后提交停在 2022 年且是 Python 2,先在测试库验一遍,或用平台自带的 SQL 闪回);前提:binlog 开启且格式为 ROW(必须平时就开启);
- 备份恢复:最近全量备份 + binlog 增量重放到误操作前的时间点(mysqlbinlog --stop-datetime 或 --stop-position)——恢复到临时实例,核对后导回;
- 延迟从库:配置了延迟复制(如延迟 1 小时)的从库,直接从延迟点取数据;
流程:定位误操作时间点/位点 → 用备份+binlog 恢复到临时库 → 数据校验(行数/抽样/checksum)→ 确认无误再导回线上;
预防(根本):
- 生产账号最小权限(DML 权限受控,高危操作需审批);
- 高危 SQL 拦截:平台审核(goInception/Yearning)强制 WHERE 条件、UPDATE/DELETE 不带 WHERE 拒绝;
- 延迟从库(重要系统标配);
- 备份恢复定期演练(确保备份可用);
复盘:操作流程规范(变更窗口、双人复核)、权限最小化。
容量估算(恢复窗口): 误操作恢复时间取决于备份粒度:有 binlog → 按位点/时间点恢复,小时级;只有日备 → 最多丢 1 天,需评估业务是否可接受;没有备份 → 只能从从库/缓存/下游系统拼数据,风险极高。影响行数:先
SELECT COUNT评估爆炸半径,再决定全量回滚 vs 按条件逆操作。失败与降级: 立即停止相关写入;评估是否切只读;通知业务与 DBA 双人操作。恢复过程禁止在生产“试 SQL”。事后强制:生产执行 SQL 走平台+审核+备份检查。
【原理溯源】
为什么必须 ROW 格式 binlog? ROW 记录行变更前后镜像,才能反向生成修复 SQL。STATEMENT 只记语句,重放可能再次产生错误结果或无法精确定位行。误操作恢复对 binlog 格式有硬依赖。
binlog2sql 反向 SQL 原理? 解析 ROW 事件中的 before/after 镜像:UPDATE 改回 before;DELETE 变 INSERT(before);INSERT 变 DELETE。本质是用日志做时间反演。
为什么先冻结写入? 恢复期间新写入会与恢复数据冲突或覆盖,扩大不一致。先停写→恢复到临时库→校验→再导回→解冻。
为什么恢复到临时库而不是直接覆盖生产? 直接覆盖风险高(恢复错误、部分成功)。临时库校验行数、抽样、checksum,确认后再导回,符合“可验证再切换”。
延迟从库为什么是杀手锏? 配置延迟 N 分钟复制的从库,误操作后从库尚未执行到该点,可直接取“事故前”数据。简单可靠,重要系统标配。
【选型判断树】
误操作:
├─ 立刻:确认范围 + 冻结相关写入
├─ 恢复路径
│ ├─ 有 ROW binlog → binlog2sql 反向 SQL(最快)
│ ├─ 有全量备份+binlog → 恢复到时间点/临时库
│ └─ 有延迟从库 → 直接取延迟点数据
├─ 流程:临时库 → 校验 → 导回 → 解冻
└─ 预防:最小权限、SQL 审核拦截、延迟从库、备份演练判断口诀: 先冻结,再选恢复路径,校验后导回,最后上拦截。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “误操作:止血冻结→恢复→校验→导回” |
| 0:30–1:30 | 前提 | ROW binlog、备份、延迟从库 |
| 1:30–3:00 | 三板斧 | binlog2sql、备份+时间点、延迟从库 |
| 3:00–4:00 | 流程纪律 | 临时库校验,不直接覆盖生产 |
| 4:00–5:00 | 预防 | 权限、审核拦截、演练 |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| binlog | 必须 ROW | 反向恢复前提 |
| 延迟从库 | 如延迟 60 分钟 | 按 RPO |
| 恢复点 | --stop-datetime / position | 精确到事故前 |
| 校验 | 行数+抽样+checksum | 确认后再导回 |
| 拦截 | 无 WHERE 的 UPDATE/DELETE 拒绝 | 平台强制 |
| 备份演练 | 定期 | 确保可用 |
【追问链】(三层)
L1|“没有 ROW binlog 还能恢复吗?” → 很难精确反演。只能靠更早全量备份整体回退(丢失误操作后的合法写入),或业务层补偿。所以 ROW binlog 是生产标配,不是可选项。
L2|“DELETE 误删怎么恢复?” → binlog2sql 生成 INSERT 反向语句;或闪回工具。同样依赖 ROW binlog。恢复前仍要冻结写入。
L3|“为什么备份恢复要先到临时库?” → 避免直接覆盖生产造成二次事故;临时库可校验完整性与一致性;确认无误再导回,符合变更安全流程。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道有备份可以恢复 |
| 80 分 | 会说 binlog 恢复与时间点 |
| 95 分 | ROW 格式前提;binlog2sql 反向原理;冻结写入;临时库校验;权限与拦截预防 |
【关联题】
- 同一知识簇: 第 177 题(主从/binlog)、备份恢复、SQL 审核平台
- 预防: 最小权限、高危操作审批
- 演练: 定期恢复演练
【自测】
- 误 UPDATE 后恢复最关键的平时配置是什么? 参考答案:binlog 开启且格式为 ROW;并有可用备份/延迟从库。
- 恢复时为什么要先冻结写入? 参考答案:防止新数据与恢复数据冲突,扩大不一致。
- 高危 SQL 拦截主要拦什么? 参考答案:无 WHERE 的 UPDATE/DELETE、全表 DDL 等;平台审核强制拦截。
184. 一次大事故处理完了,复盘会怎么开(故障复盘)
【考察内容】复盘方法论是高级工程师/负责人必考题
【题目】一次造成 30 分钟不可用的事故处理完了,你要组织复盘会并写复盘报告。复盘的目的是什么(不追责、找根因、防复发)?报告要包含哪些部分(时间线、根因、影响、改进项)?怎么确保改进项落地?
【参考答案】
复盘目标:不是追责,是找到系统性根因并改进(防止同类事故);
报告结构(标准模板):
- 事故概况:时间线(发现→响应→恢复)、影响范围(用户/业务/时长)、严重级别(P0/P1);
- 根因分析:直接原因 + 深层原因(5 Whys 追问:为什么没被监控发现→为什么没有告警→为什么预案缺失……);
- 处理过程:谁、何时、做了什么(止血动作是否及时有效);
- 改进项(Action Items):每项带负责人+截止时间——监控补全、预案编写、代码修复、流程优化;
- 验证与跟进:改进项验收、定期演练;
复盘会要点:
- 无责备文化(人都会犯错,问题在系统缺失);
- 关注“为什么防线没拦住”(监控、告警、评审、灰度、回滚、演练哪层失效);
- 区分“人为失误”与“机制缺失”——机制缺失是改进重点;
长期:事故库沉淀(同类事故检索)、SLO 复盘(可用性目标达成)、混沌演练。
容量估算(复盘材料): 复盘必须有数:影响时长、影响用户数、错误率峰值、资金/订单影响、MTTR(发现/定位/止血/恢复分段)。时间线精度到分钟。改进项应可验收:如“回滚<5 分钟”“错误率告警<2 分钟触达”“压测覆盖峰值×1.2”。
失败与降级(复盘中的技术债): 把“没有降级预案”“超时未配置”“单点依赖”列为行动项并排期。复盘文化:对事不对人,否则隐瞒会导致下次更晚发现。
【原理溯源】
为什么复盘不能变成追责会? 追责会导致隐瞒、缩小描述、不敢暴露真实过程,根因永远找不到。无责备才能换来完整时间线与真话。改进对象是系统与机制,不是某个人。
5 Whys 为什么有效? 单层原因停在“某人改错了”。连续问为什么,会落到“为什么能改错/为什么没拦住/为什么没监控”——即机制层。机制改进才能防复发。
为什么每条改进项必须有负责人和 deadline? 没有 owner 的 action item 会流于形式。可跟踪、可验收、可追责到事项(不是人),这是复盘落地的关键。
为什么要看“层层防线为何失效”? 好的系统有多层防线:评审、灰度、监控、告警、回滚、演练。事故说明多层同时失效。复盘要逐层检查,而不是只补最外层。
SLO 与复盘的关系? SLO 定义“多少错误预算”。超预算的事故必须复盘并改进。用错误预算驱动改进优先级,避免“每次都说重要、永远没排期”。
【选型判断树】
复盘会怎么开:
├─ 会前:收集时间线、日志、监控、聊天记录
├─ 会中
│ ├─ 先陈述事实时间线(不评价人)
│ ├─ 5 Whys 挖到机制层
│ ├─ 检查各道防线为何没拦住
│ └─ 产出 Action Items:负责人+截止时间
└─ 会后
├─ 跟踪验收改进项
├─ 事故入库便于检索
└─ 必要时演练验证判断口诀: 事实→机制→防线→可跟踪改进项。
【口述骨架】(5 分钟;框架 D,骨架共性见文首第二节,本题只写特定内容)
| 时间 | 任务 | 内容 |
|---|---|---|
| 0:00–0:30 | 定性 | “复盘目标是防复发,不是追责” |
| 0:30–1:30 | 报告结构 | 时间线、影响、根因、处理、改进项 |
| 1:30–2:30 | 5 Whys | 从直接原因挖到机制 |
| 2:30–3:30 | 防线检查 | 评审/灰度/监控/告警/回滚/演练 |
| 3:30–4:30 | 落地 | 负责人+deadline+验收 |
| 4:30–5:00 | 文化 | 无责备、事故库、SLO |
【关键数字】
| 参数 | 经验值 | 说明 |
|---|---|---|
| 时间线 | 精确到分钟 | 发现→响应→恢复 |
| 5 Whys | 通常 3–5 层到机制 | 不停在人 |
| Action | 必须 owner + 截止时间 | 可跟踪 |
| 跟进 | 定期检查未完成项 | 防烂尾 |
| SLO | 错误预算驱动优先级 | 超预算必复盘 |
| 事故库 | 可检索同类历史 | 组织记忆 |
【追问链】(三层)
L1|“5 Whys 举例?” → 订单重复:为什么重复→回调重试;为什么没幂等→设计缺幂等规范;为什么没人发现→无对账;为什么无对账→资源未排期……层层到机制与排期,而不是停在“开发写错了”。
L2|“改进项总是不落地怎么办?” → 进入迭代看板、与错误预算/SLO 挂钩、定期 review 未完成项、超期升级。没有制度压力,改进会被业务需求挤掉。
L3|“复盘报告要不要公开?” → 在安全范围内尽量公开(脱敏后),沉淀组织记忆。越公开越能避免其他团队重蹈覆辙。敏感细节可收敛,机制教训必须传播。
【评分标准】
| 档位 | 答案特征 |
|---|---|
| 60 分 | 知道写时间线和原因 |
| 80 分 | 有报告模板;会说 5 Whys |
| 95 分 | 无责备文化;防线失效分析;Action 可跟踪验收;SLO/事故库长期机制 |
【关联题】
【自测】
- 复盘的首要目标是什么? 参考答案:找到系统性根因并改进,防止同类事故,而不是追责个人。
- 改进项如何保证落地? 参考答案:每项指定负责人和截止时间,纳入看板跟踪与验收,定期 review。
- 5 Whys 要挖到哪一层才停? 参考答案:挖到流程/机制/设计缺失层,而不是停在“某人操作失误”。