分布式系统与微服务综合面试题库
本册用于把
01至07的机制、边界、工程治理和项目证据组织成可追问、可验证的综合口述。每道题固定按“结论、约束、机制链、失败边界、项目证据、验证闭环”展开;机制定义仍以对应分册为准,本册不复制分册正文。
1. 使用边界与七条追问树
本册不把“用了微服务”当作结论。面试回答必须先给业务目标和不能牺牲的约束,再解释机制如何工作、在哪些窗口失效,最后落到项目数据、观测证据和恢复验证。涉及版本、配置、消息、数据库与安全的事实,均沿相对链接回到 01 至 07 的权威分册。
| 追问树 | 第一问 | 深挖方向 | 收口证据 |
|---|---|---|---|
| 是否拆服务 | 为什么拆或不拆 | 变更耦合、团队边界、调用成本、回迁条件 | 交付周期、故障半径、跨服务变更率 |
| 边界所有权 | 谁拥有规则和数据 | 限界上下文、聚合、读模型、跨域写入 | Schema(模式)变更记录、越权写入审计 |
| 一致性脑裂 | 分区时哪一侧能写 | Quorum(法定人数)、任期、栅栏、冲突收敛 | 任期号、提交索引、冲突与补偿记录 |
| 事务选型 | 为什么选本地事务、Saga(长事务补偿)或消息方案 | 原子边界、未知结果、补偿语义、人工出口 | 状态年龄、差异单、对账闭环 |
| 治理雪崩 | 一次慢调用怎样扩散 | 预算、重试、隔离、熔断、恢复放量 | 放大倍数、线程池、分位延迟、恢复曲线 |
| 发布安全 | 新旧版本如何共存和回滚 | Expand/Contract(扩展/收缩)、灰度、配置、消息兼容 | 灰度指标、兼容矩阵、回滚演练 |
| 项目事故 | 如何证明根因而非猜测 | 时间线、变更、指标、日志、Trace(链路追踪) | 止血、修复、回归、长期防复发 |
图一:七条追问树总览
flowchart LR
A[业务目标与约束] --> B{架构决策}
B --> C[是否拆服务]
B --> D[边界与所有权]
B --> E[一致性与事务]
C --> F[治理与发布]
D --> F
E --> F
F --> G[项目事故证据]
G --> H[验证闭环]数据演绎一:拆分收益必须覆盖分布式税
某 WMS(仓储管理系统)模块每月 18 次发布,其中 11 次需要库存与波次代码同时改动;拆分前发布准备中位数 35min,拆分后若仍有 61% 的跨服务联改,同时新增每次 12min 的契约验证和观测检查,则期望准备时间约为 35 × (1 - 0.61) + 12 = 25.65min。节省不足 10min,却增加网络与一致性失败面,此时先清理模块依赖通常比立刻拆服务更合理。
1.1 回答结构与证据等级
综合题不是把术语串成一段话,而是建立可反驳的决策链。结论要说明“在什么前提下选择什么”;约束至少覆盖正确性、时延、容量、组织和合规;机制链解释状态如何推进;失败边界列出超时、分区、重复、乱序和回滚中间态;项目证据给基线、峰值、指标和样本;验证闭环说明如何证明恢复、如何发现复发。证据优先级按权威数据、跨信号关联、单一日志、经验猜测递减。
| 六字段 | 必答内容 | 常见失分 |
|---|---|---|
| 结论 | 带前提的选择与不选方案 | 只报技术名词 |
| 约束 | 业务不变量和资源上限 | 只说高并发 |
| 机制链 | 状态、调用、消息、数据推进顺序 | 组件清单代替因果 |
| 失败边界 | 未知结果、部分成功和恢复窗口 | 只讲成功路径 |
| 项目证据 | 基线、变化、时间线和可追溯样本 | 编造漂亮数字 |
| 验证闭环 | 指标、对账、演练、人工出口 | 上线即结束 |
热门面试题
问题:为什么综合回答必须先说约束再说方案?
- 考点:决策前提、方案比较、业务不变量。
- 回答思路:同一机制在不同损失函数下结论相反。库存宁可拒绝不确定写,物流轨迹可先接收后收敛;先说约束才能判断选择是否成立。
- 详细答案:面试官不给场景时,主动声明峰值、容忍窗口和权威源是假设,不把假设冒充事实。
- 进阶追问:WMS(仓储管理系统)库存以不超卖为硬约束,IoT(物联网)报警以保护接入能力为首要约束。
- 进阶回答:问“数字从哪来”,回答应给监控区间、样本口径和上线前后对比,不给无法证实的精确数。
问题:项目证据怎样避免成为结果包装?
- 考点:基线、反事实、时间窗口、证据关联。
- 回答思路:保留变更前基线,固定统计口径,同时观察收益与副作用,并以事件标识把指标、日志和状态记录串起来。
- 详细答案:若历史埋点缺失,只能说明可确认事实与推断边界,再通过回放或压测补证。
- 进阶追问:Runner(执行器)调度以重复领取率、积压年龄和恢复耗时共同验收。
- 进阶回答:问“相关是否等于因果”,回答通过灰度对照、回滚复现和故障注入增强因果证据。
问题:失败边界为什么要包含人工处理?
- 考点:自动化上限、未知状态、合规审计。
- 回答思路:外部系统长期不可用、金额冲突或补偿重试耗尽时,自动化继续推进可能扩大损失,必须冻结状态并生成可审计工单。
- 详细答案:人工入口本身积压时,按金额、状态年龄和用户影响分级,并设置升级阈值。
- 进阶追问:支付资金一致性中,渠道与本地账务不符进入差错队列,禁止自动发货。
- 进阶回答:问“人工是否破坏幂等”,回答人工动作同样使用命令标识、条件更新与双人复核。
2. 知识型综合问答
2.1 是否拆服务与可逆演进
拆分是为获得独立变更、独立扩缩容或故障隔离,不是为了获得“微服务”标签。判断时把业务凝聚度、跨边界事务、团队认知负担、运行成熟度和回迁成本一起量化。优先通过模块化单体建立清晰依赖;只有边界在多次真实变更中稳定,且收益持续高于远程调用、数据同步、发布治理与值班成本,才迁出独立服务。
图二:是否拆服务追问树
flowchart TD
A[变更或容量痛点] --> B{模块边界稳定吗}
B -- 否 --> C[模块化单体整治]
B -- 是 --> D{需要独立发布或扩容吗}
D -- 否 --> C
D -- 是 --> E{跨边界强事务频繁吗}
E -- 是 --> F[重画边界或保留同进程]
E -- 否 --> G[小流量迁出]
G --> H{收益覆盖分布式税吗}
H -- 否 --> I[回迁或合并]
H -- 是 --> J[固化服务边界]数据演绎二:独立扩容的经济性
跨境物流轨迹解析占应用 68% 的 CPU(中央处理器),请求接口只占 19%。单体为扛 4 倍轨迹峰值需从 12 扩到 40 个实例;拆出解析服务后,接口维持 12 个实例,解析服务从 8 扩到 30 个实例,总计 42 个,看似未省实例。但解析实例可使用低内存规格,按单位成本 0.55 计算,总成本从 40 降到 12 + 30 × 0.55 = 28.5,并把解析崩溃与下单接口隔离,拆分才有可验证收益。
热门面试题
问题:什么情况下应坚持模块化单体?
- 考点:边界稳定性、团队规模、事务密度。
- 回答思路:需求仍高速探索、团队较小、跨模块强事务频繁且没有成熟可观测与发布能力时,模块化单体更利于保持原子性和调试效率。
- 详细答案:单进程局部热点可先异步化、做线程池隔离或单模块垂直扩容,不把所有性能问题都归因于单体。
- 进阶追问:WMS(仓储管理系统)早期波次与库存规则共同变化,先以模块边界和接口测试约束依赖。
- 进阶回答:问“何时再评估”,回答以连续多个迭代的跨模块变更率、资源曲线和故障记录为触发器。
问题:拆分后怎样保留回迁能力?
- 考点:可逆决策、端口抽象、数据迁移。
- 回答思路:调用方依赖业务端口而非网络细节,迁移阶段保留可切换路由,数据权威源唯一,并设计双读校验而非长期双写。
- 详细答案:发现跨服务调用暴增时,先冻结继续拆分,通过调用图和变更图判断合并,而不是继续加缓存掩盖错误边界。
- 进阶追问:Runner(执行器)调度先从任务业务中抽离领取端口,再决定是否独立部署。
- 进阶回答:问“回迁是否等于失败”,回答架构决策应随约束变化,低成本回迁本身是成熟度证据。
问题:如何识别拆分过细?
- 考点:聊天式调用、共同发布、数据耦合。
- 回答思路:若一次业务动作需要多次同步往返,多数发布必须结伴,服务没有独立不变量和数据所有权,说明边界更像代码层而非业务能力。
- 详细答案:少量跨服务调用不等于过细,要结合调用频率、失败传播与共同变更率判断。
- 进阶追问:订单状态与履约编排若每步都回查同一订单行,应考虑把编排与状态机放回同一边界。
- 进阶回答:问“判断阈值”,回答阈值来自团队基线,可用同步链深度、共同发布占比和故障关联度建立趋势门禁。
2.2 边界、数据所有权与跨域协作
服务边界、事务边界和数据所有权互相关联但不等价。边界从业务语言、不变量和变更原因推导;数据所有权回答谁能解释字段、校验写入和决定演进;跨域协作通过命令、事件、查询模型或防腐层完成。每服务一库的关键不是物理库数量,而是禁止旁路写和未经契约的表级耦合。读模型可以复制数据以优化查询,但不能反向成为业务权威。
| 协作方式 | 适用条件 | 主要风险 | 验证证据 |
|---|---|---|---|
| 同步命令 | 调用方需要即时业务判定 | 延迟耦合、未知结果 | 截止时间、幂等记录、权威查询 |
| 领域事件 | 已发生事实通知多个订阅方 | 重复、乱序、语义漂移 | 事件标识、版本、消费水位 |
| Read Model(读模型) | 跨域列表与统计 | 陈旧、重建、误作权威 | 水位、延迟、回源规则 |
| ACL(防腐层) | 外部或遗留模型不可控 | 映射遗漏、错误吞并 | 映射测试、原始报文、差异队列 |
图三:边界与所有权追问树
flowchart TD
A[业务术语或规则冲突] --> B[识别不变量与变更原因]
B --> C{同一聚合内必须原子吗}
C -- 是 --> D[同一事务与所有权边界]
C -- 否 --> E{需要即时判定吗}
E -- 是 --> F[同步命令与超时预算]
E -- 否 --> G[领域事件与收敛窗口]
F --> H[禁止旁路写]
G --> H
H --> I[契约与审计验证]图四:跨服务查询的权威回源
sequenceDiagram
participant U as 用户
participant W as 工作台
participant R as Read Model(读模型)
participant S as 库存权威服务
U->>W: 查询订单与库存摘要
W->>R: 读取投影与水位
R-->>W: 摘要和最后事件版本
alt 仅用于浏览
W-->>U: 展示可能延迟的摘要
else 即将取消或发货
W->>S: 按业务键回源校验
S-->>W: 当前权威状态
W-->>U: 返回可执行结果
end数据演绎三:共享表写权限收口
原有 6 个服务直接更新库存表,月均出现 17 次字段语义冲突,43% 的库存变更无法从业务接口审计。第一阶段保留共享物理库但把写入收口到库存模块,旁路写告警从每天 26 次降到 2 次;第二阶段再迁移独立存储。结论是逻辑所有权先于物理拆库,否则只是把隐式表耦合换成不稳定的双写。
数据演绎四:读模型的陈旧窗口
订单工作台峰值每次页面扇出 5 个服务,单服务超时率均为 0.6%,粗略独立假设下页面至少一次失败概率为 1 - 0.994^5 ≈ 2.96%。改读模型后页面失败率降到 0.4%,但投影 P99(99 分位响应时间) 延迟为 18s。因此浏览可接受摘要,取消和发货必须回源,不能用可用性收益掩盖关键动作读旧值。
热门面试题
问题:每服务一库是否意味着必须一服务一个数据库实例?
- 考点:逻辑所有权、物理部署、旁路写。
- 回答思路:核心是单一写入权威和契约化访问,可阶段性共享实例但分模式、账号和权限,禁止其他服务直接修改所属数据。
- 详细答案:报表、迁移工具和紧急修复也必须使用受审计通道,不能以运维便利绕过所有权。
- 进阶追问:库存表先收口写权限,再按仓迁移,避免切库与改语义同时发生。
- 进阶回答:问“联表怎么办”,回答用读副本、Read Model(读模型)或离线数仓,并标明时效和权威边界。
问题:怎样判断一个字段属于订单还是履约?
- 考点:语义、生命周期、修改权。
- 回答思路:看谁定义字段含义、谁维护不变量、谁因业务变化而修改;同名“完成”在交易、仓内履约和物流签收中可能是三个事实。
- 详细答案:短期兼容字段可双读,但必须指定权威字段、迁移水位和删除时间,禁止永久双主。
- 进阶追问:订单成交状态不由物流回调直接改写,物流只发布签收事实,由订单策略决定是否推进。
- 进阶回答:问“组织归属决定边界吗”,回答组织是信号不是证明,仍需用业务不变量和变更记录校验。
问题:跨服务查询为什么不能全部实时接口聚合?
- 考点:扇出可用性、读模型、水位。
- 回答思路:实时聚合会叠加延迟和失败概率;高频列表可用事件构建 Read Model(读模型),关键动作再回权威服务校验。
- 详细答案:投影落后或重建期间必须显示陈旧标记、降级字段,并禁止依赖旧值的不可逆操作。
- 进阶追问:跨境物流工作台以投影展示轨迹摘要,理赔判定回原始事件和当前规则版本。
- 进阶回答:问“投影错了怎么办”,回答保留事件水位、可重放原始事实和逐条差异校验。
2.3 一致性、Quorum(法定人数)、时钟与脑裂
一致性讨论必须指出客户端可观察语义、复制确认点和分区时的写入资格。W + R > N 只说明读写集合在固定成员集下相交,不自动提供线性一致,因为仍有并发写、读修复、旧主、滑动成员集和失败检测问题。物理时钟适合展示和审计,单调时钟适合计算时长;租约只能限定时间窗口,Fencing Token(栅栏令牌)才让下游拒绝旧所有者。
| 问题 | 错误捷径 | 正确决策依据 |
|---|---|---|
| 网络分区 | 给系统贴 CP(一致性和分区容错)或 AP(可用性和分区容错)永久标签 | 按具体读写操作选择拒绝、降级或冲突收敛 |
| Quorum(法定人数) | 只验算 W + R > N | 固定成员、版本顺序、读写协议与故障恢复共同验证 |
| 超时 | 直接判定失败并换键重试 | 先按原幂等键查询权威结果 |
| 租约 | 过期即认为旧执行者停止 | 下游比较 Fencing Token(栅栏令牌) |
| 时钟 | 能回答的问题 | 不能单独证明 |
|---|---|---|
| 物理时钟 | 人类时间、审计区间 | 严格因果与唯一版本顺序 |
| 单调时钟 | 本进程经过时长、超时 | 跨进程先后关系 |
| Lamport Clock(兰伯特时钟) | 若甲导致乙则甲值更小 | 两事件是否并发 |
| 向量时钟 | 因果与并发关系 | 低成本无限扩容 |
图五:一致性与脑裂追问树
flowchart TD
A[出现超时或副本差异] --> B{证据表明网络分区吗}
B -- 否 --> C[区分慢、宕机与复制延迟]
B -- 是 --> D{操作能接受冲突吗}
D -- 否 --> E[仅多数派或单一任期可写]
D -- 是 --> F[两侧接收并记录版本]
E --> G[租约加栅栏拒绝旧主]
F --> H[按业务规则合并或补偿]
G --> I[恢复后对账验证]
H --> I图六:脑裂恢复顺序
sequenceDiagram
participant C as 客户端
participant A as 旧主
participant B as 新主
participant D as 权威存储
C->>A: 写入,栅栏值 41
Note over A,B: 分区后 B 获得新任期
C->>B: 写入,栅栏值 42
B->>D: 条件提交 42
D-->>B: 接受
A->>D: 延迟提交 41
D-->>A: 拒绝旧栅栏
Note over A,D: 恢复后隔离旧主并核对分叉日志数据演绎五:法定人数的交集与代价
副本数 N=5,若 W=3、R=3,固定成员下任意读写集合至少相交 1 个副本,但一次写最多容忍 2 个副本不可用,读写都需跨节点等待。若为降低读延迟改成 R=1,即使 W=3,仍不能仅凭最新时间戳保证读到最新提交;客户端要携带版本水位或走领导者读。参数选择必须同时看读写比例、故障域和语义,而不是只算不等式。
数据演绎六:时钟回拨如何误判租约
Runner(执行器)甲在物理时间 10:00:00 获得 30s 租约,执行中宿主时间回拨 45s。若用墙上时间判断,甲可能多运行 45s,而乙已在权威存储获得更高代次。使用单调时钟可避免本进程时长回拨,但仍不能阻止暂停后恢复的旧甲写入;下游必须比较代次 102 > 101 并拒绝旧写。
热门面试题
- 问题:为什么
W + R > N不等于线性一致?
- 考点:集合交集、版本协议、并发写。
- 回答思路:交集只保证可能看到共同副本;若成员集变化、旧值响应更快、并发写无统一顺序或读不做版本判定,仍会读旧或冲突。
- 详细答案:网络分区恢复后不能让旧主直接提供读写,需先校验任期、提交位置和分叉数据。
- 进阶追问:库存写采用单一权威与条件版本,轨迹接入则允许多点收集后按事件规则收敛。
- 进阶回答:问“怎样做线性读”,回答按实现选择领导者读、读屏障或携带已提交水位,并核对具体协议。
- 问题:系统时间回拨会影响哪些机制?
- 考点:时钟用途、租约、最后写入胜出。
- 回答思路:会影响墙上时间超时、基于时间戳的冲突覆盖和审计排序;经过时长应用单调时钟,版本顺序用数据库版本或逻辑代次。
- 详细答案:单调时钟只在本进程有意义,进程重启或跨机比较不能直接延续。
- 进阶追问:物流保留设备时间、接收时间和处理时间,规则排序不盲信设备时钟。
- 进阶回答:问“能否彻底同步时钟”,回答时钟同步缩小偏差但不能建立严格因果,协议仍要容忍偏差和回拨。
- 问题:脑裂恢复为什么不能简单保留时间戳较大的记录?
- 考点:分叉历史、业务不变量、旧主隔离。
- 回答思路:大时间戳可能来自时钟偏差,且两侧操作可能有不可合并副作用;先冻结旧主,确认合法任期,再按业务流水补偿或人工裁决。
- 详细答案:若外部支付已发生,不能靠覆盖数据库状态撤销资金事实,必须查渠道并走退款或冲正流程。
- 进阶追问:库存双写分叉按预占流水、订单状态和仓内作业证据逐笔核对。
- 进阶回答:问“如何证明脑裂”,回答关联任期、成员视图、网络监控、双写时间窗和冲突键,不凭一条错误日志定性。
2.4 分布式事务选型与未知结果
事务选型从原子边界、资源可控性、业务可补偿性和一致时限出发。本地事务守住单服务不变量;XA(扩展架构事务)与 2PC(两阶段提交)适合参与资源明确且能承受协调阻塞的窄场景;TCC(Try Confirm Cancel,尝试确认取消)要求业务显式预留与释放;Saga(长事务补偿)适合长流程但补偿不是时间倒流;Outbox(发件箱)把业务提交和待发布事实合并,消费者仍需 Inbox(收件箱)或业务幂等。外部支付、物流和设备副作用必须用查询、补偿、对账和人工闭环收敛。
| 方案 | 原子范围 | 主要失败边界 | 合适场景 |
|---|---|---|---|
| 本地事务 | 单资源或同库资源 | 提交结果未知、进程崩溃 | 聚合内不变量 |
| XA(扩展架构事务) | 支持协议的多个资源 | 协调阻塞、资源占用 | 短事务且资源受控 |
| TCC(Try Confirm Cancel,尝试确认取消) | 业务预留状态 | 空回滚、悬挂、重复确认 | 库存名额等可预留资源 |
| Saga(长事务补偿) | 多个本地事务 | 补偿失败、不可逆副作用 | 长流程与可补偿动作 |
| Outbox(发件箱) | 业务数据与待发事件 | 发布重复、积压 | 数据变更驱动事件 |
图七:事务选型追问树
flowchart TD
A[跨边界业务动作] --> B{能收回同一原子边界吗}
B -- 是 --> C[本地事务]
B -- 否 --> D{资源都受控且事务很短吗}
D -- 是 --> E[评估 XA(扩展架构事务)]
D -- 否 --> F{资源可显式预留吗}
F -- 是 --> G[TCC(Try Confirm Cancel,尝试确认取消)]
F -- 否 --> H{动作可业务补偿吗}
H -- 是 --> I[Saga(长事务补偿)]
H -- 否 --> J[状态机加查询对账与人工]
C --> K[失败演练]
E --> K
G --> K
I --> K
J --> K图八:Outbox(发件箱)未知窗口闭环
sequenceDiagram
participant B as 业务服务
participant DB as 业务库
participant P as 发布器
participant M as MQ(消息队列)
participant C as 消费者
B->>DB: 同一事务写业务与 Outbox(发件箱)
DB-->>B: 提交成功
P->>DB: 锁定待发布记录
P->>M: 发布事件
M-->>P: 确认可能丢失
P->>M: 使用同一事件标识重发
M->>C: 至少一次投递
C->>C: Inbox(收件箱)去重并推进状态数据演绎七:事务模式必须计入锁持有时间
库存预占接口平均 35ms(毫秒),外部支付单创建 P99(99 分位响应时间) 为 1.8s。若把两者放入 XA(扩展架构事务)并在等待外部调用时持锁,300 QPS(每秒查询率) 下按 Little’s Law(利特尔定律)估算在途约 300 × 1.8 = 540 个,连接池和热点行会先耗尽。改为本地预占提交后创建支付单,未知结果进入查询状态,牺牲瞬时一致换取可恢复性和资源上限。
数据演绎八:补偿积压决定最终一致是否可信
一次渠道故障产生 48,000 条待查支付,修复后查询能力为 220 QPS(每秒查询率),正常新增未知单仍有 20 QPS(每秒查询率),净消化能力为 200 QPS(每秒查询率),理论清空需 240s。若渠道限流只允许 80 QPS(每秒查询率),净能力变为 60 QPS(每秒查询率),则需 800s。恢复计划必须按真实限流安排分级查询,不能宣称服务恢复就已一致。
热门面试题
- 问题:为什么分布式事务不能默认选强一致方案?
- 考点:资源前提、阻塞、外部副作用。
- 回答思路:强一致协议要求参与者可协调并承担锁与阻塞,支付渠道、物流和设备通常不受本系统控制,无法被数据库协议回滚。
- 详细答案:即使资源支持 XA(扩展架构事务),也要演练协调器故障、超时和恢复期间的资源占用。
- 进阶追问:支付创建采用本地状态机与渠道查单,不把渠道调用包进数据库事务。
- 进阶回答:问“资金必须强一致怎么办”,回答本地账务守恒强约束,跨机构状态通过流水、对账和差错处理收敛。
- 问题:TCC(Try Confirm Cancel,尝试确认取消)如何处理空回滚和悬挂?
- 考点:阶段记录、幂等、防悬挂。
- 回答思路:分支以全局事务号和分支号持久化阶段;Cancel(取消)先到时记录已取消,后到 Try(尝试)必须拒绝,Confirm(确认)和 Cancel(取消)都幂等。
- 详细答案:预留已被人工释放或资源过期时不能继续确认,应转异常状态并核对业务事实。
- 进阶追问:库存名额预留用状态与版本推进,不用删除记录掩盖执行历史。
- 进阶回答:问“超时自动取消即可吗”,回答旧请求可能迟到,必须有阶段防悬挂和下游条件写。
- 问题:Outbox(发件箱)能否保证消息只发送一次?
- 考点:本地原子、发布未知、消费幂等。
- 回答思路:不能。它保证业务数据与待发布意图同事务落库;确认丢失会重发,消费者要按稳定事件标识去重并重放既有结果。
- 详细答案:发布器积压、毒事件或模式不兼容时要隔离并保留水位,不能跳过后假装完成。
- 进阶追问:订单状态与履约事件同事务写入,履约按事件标识和订单版本幂等消费。
- 进阶回答:问“去重表会增长吗”,回答按业务保留期分区归档,但清理窗口必须覆盖最大重放和对账周期。
2.5 超时、重试、隔离与治理雪崩
治理的目标是让有限容量在故障时可预测退化。截止时间从入口向下传播,重试只能发生在幂等、剩余预算充足且下游可能恢复的边界;隔离切断线程、连接和队列传染;限流保护已知容量;熔断阻止持续施压并以少量探测恢复;背压让上游看到处理能力;降级必须诚实说明数据时效和能力缺失。多个组件不是越多越安全,组合顺序错误会把一次慢调用放大为全链路雪崩。
| 控制手段 | 解决的问题 | 不能替代 |
|---|---|---|
| 超时预算 | 工作何时已无价值 | 取消传播和幂等 |
| 重试 | 短暂且可恢复的失败 | 容量扩展与结果查证 |
| 隔离 | 资源池相互传染 | 单池容量治理 |
| 熔断 | 已知故障持续施压 | 初始限流与业务降级 |
| 背压 | 下游显式反馈速度 | 无界堆积后的清理 |
图九:治理雪崩追问树
flowchart TD
A[下游延迟升高] --> B[在途请求增加]
B --> C[线程与连接耗尽]
C --> D[排队时间挤占截止预算]
D --> E[多层超时重试]
E --> F[流量再次放大]
F --> B
A --> G[传播截止时间]
G --> H[隔离与负载卸除]
H --> I[熔断并小流量探测]
I --> J[阶梯恢复和验证]数据演绎九:重试放大不是简单加一倍
入口为 800 QPS(每秒查询率),网关、订单、库存三层都配置最多 3 次尝试。最坏尝试量是 800 × 3 × 3 × 3 = 21,600 QPS(每秒查询率),为原流量 27 倍。即使每层只有 30% 请求触发下一次,额外流量也会叠加在已变慢的下游上。应把重试收敛到最了解幂等和剩余预算的一层,采用退避、抖动和重试配额。
数据演绎十:恢复放量同样可能造成二次故障
库存服务修复时积压 120,000 个请求,稳定处理能力为 2,000 QPS(每秒查询率),正常新流量 1,500 QPS(每秒查询率),净清理能力仅 500 QPS(每秒查询率),至少需 240s。若熔断器一恢复就同时释放全部等待流量,连接建立和缓存未热会再次过载。应按 5% -> 20% -> 50% -> 100% 阶梯放量,每档观察错误率、延迟和资源水位。
热门面试题
- 问题:超时、熔断和降级有什么区别?
- 考点:请求边界、跨请求状态、业务替代。
- 回答思路:超时终止单次等待,熔断根据近期失败阻止新调用,降级决定不可用时向用户提供什么受限能力;三者协作但语义不同。
- 详细答案:超时后任务未取消仍会占资源,熔断恢复过快会二次冲击,降级旧数据可能误导关键操作。
- 进阶追问:WMS(仓储管理系统)库存不可确认时拒绝出库,物流轨迹页可展示带水位的旧摘要。
- 进阶回答:问“阈值怎么定”,回答从容量压测、历史分位和业务损失设初值,再以灰度和故障演练校准。
- 问题:怎样选择重试层级?
- 考点:幂等、预算、放大倍数。
- 回答思路:让最了解业务幂等键、结果查询和剩余截止时间的一层重试,其他层禁用或只做连接级快速切换。
- 详细答案:客户端断开不代表服务端停止,涉及扣款与扣库存时先查询同一业务键结果。
- 进阶追问:支付超时由支付域复用商户请求号查单,网关不换标识重放请求。
- 进阶回答:问“读请求都能重试吗”,回答读也可能昂贵或触发副作用,仍需看语义、预算与容量。
- 问题:服务恢复后为什么不能立即全量放开?
- 考点:积压、冷缓存、连接风暴、恢复验证。
- 回答思路:故障期间形成的积压与正常流量会叠加,缓存和连接池尚未稳定;应探测、阶梯放量并设置自动回退门槛。
- 详细答案:恢复指标只看平均延迟会漏掉热点和尾部失败,应同时看分位、错误类型、队列年龄和下游压力。
- 进阶追问:IoT(物联网)通知恢复先发聚合摘要,再按优先级消化明细,保护原始事件接入。
- 进阶回答:问“积压多久清完”,回答用净处理能力计算,并把外部限流与重试成本纳入。
2.6 发布安全、配置、多租户与安全边界
发布安全的本质是让新旧代码、数据库模式、事件模式和配置在每个中间态可共存。数据库先 Expand(扩展)再迁移数据,最后 Contract(收缩);事件先新增可选字段,消费者容忍未知字段,确认旧版本退出后再收紧;配置变更也要校验、灰度、审计和回滚。多租户不能依赖客户端传入的租户号,服务端必须从可信身份推导,并在查询、缓存、队列、限流、密钥和审计全链路强制隔离。
| 变更面 | 向前兼容 | 向后兼容 | 回滚中间态 |
|---|---|---|---|
| API(应用程序接口) | 新服务接受旧请求 | 旧服务忽略可选新字段 | 路由可回切,副作用可识别 |
| 数据库 | 新代码兼容旧列和空值 | 旧代码不依赖新约束 | 双读校验,禁止立即删列 |
| 事件 | 新消费者接受旧版本 | 旧消费者忽略未知可选字段 | 在途消息仍可消费 |
| 配置 | 新版本有默认与校验 | 旧版本不读取不认识的键 | 旧值、版本和审计可恢复 |
| 租户隔离层 | 强制措施 | 典型串扰证据 |
|---|---|---|
| 身份 | 服务端验证令牌并推导租户 | 请求租户与身份租户不一致 |
| 数据 | 查询条件、行级策略或独立库 | 无租户谓词的慢查询与审计 |
| 缓存 | 租户进入键与失效范围 | 不同租户命中同一缓存键 |
| 队列 | 消息携带可信租户上下文 | 消费日志租户与载荷不符 |
| 运维 | 权限最小化、操作双审计 | 跨租户导出或批处理记录 |
图十:发布安全追问树
flowchart TD
A[准备发布变更] --> B{新旧版本能共存吗}
B -- 否 --> C[先做兼容扩展]
B -- 是 --> D[灰度到内部与低风险租户]
C --> D
D --> E{技术与业务指标正常吗}
E -- 否 --> F[停流并回滚路由]
E -- 是 --> G[逐级扩大流量]
F --> H[处理已产生副作用]
G --> I[确认旧版本退出]
I --> J[收缩旧字段与旧协议]
H --> K[复核一致性后再发布]图十一:租户身份到数据的纵深校验
sequenceDiagram
participant U as 调用方
participant G as Gateway(网关)
participant S as 领域服务
participant C as 缓存
participant D as 数据库
U->>G: 令牌和请求
G->>G: 验签并生成可信租户上下文
G->>S: 签名上下文
S->>S: 业务授权再次校验
S->>C: tenantId(租户标识)加业务键
C-->>S: 租户内缓存结果
S->>D: 强制租户谓词与权限账号
D-->>S: 租户内数据数据演绎十一:灰度门禁必须观察业务差异
新版本先放 5% 流量,技术错误率从 0.20% 到 0.22%,看似正常;但库存预占成功率从 98.7% 降到 97.9%,每小时多失败约 0.8% × 50,000 = 400 单。若只看 HTTP(超文本传输协议)错误会漏报,因为程序把版本冲突错误映射成正常响应。灰度门禁必须同时比较状态分布、金额守恒、租户差异和尾部延迟。
热门面试题
- 问题:数据库字段变更如何支持随时回滚?
- 考点:Expand/Contract(扩展/收缩)、双读校验、中间态。
- 回答思路:先加兼容列并让新旧代码都可工作,再回填和比对,切换权威读后观察,确认旧版本退出才删旧列或收紧约束。
- 详细答案:回滚代码不等于回滚数据,灰度期间产生的新格式数据必须能被旧代码忽略、降级读取或经迁移处理。
- 进阶追问:库存可用量拆字段时先保留旧总量,逐仓比对守恒后再切换计算路径。
- 进阶回答:问“双写多久”,回答只在有明确水位、差异监控和退出条件的迁移窗口内使用。
- 问题:为什么 Gateway(网关)鉴权后服务仍要授权?
- 考点:信任边界、横向调用、业务权限。
- 回答思路:网关只能证明入口身份和粗粒度权限,内部绕行、消息消费或错误透传仍可能发生;领域服务掌握资源归属与动作规则,必须终局授权。
- 详细答案:内部服务不能盲信普通请求头,应验证由可信组件签名且有短有效期的上下文,或重新校验令牌。
- 进阶追问:WMS(仓储管理系统)出库动作由仓库、货主、角色和订单状态共同授权。
- 进阶回答:问“重复校验影响性能吗”,回答缓存公钥和权限摘要,但不缓存可变业务归属的最终判断。
- 问题:多租户最容易在哪些非数据库环节串扰?
- 考点:缓存键、队列、限流、日志和批任务。
- 回答思路:共享缓存遗漏租户前缀、消息重试丢上下文、全局限流互相挤占、导出文件路径冲突和日志泄露都可串扰,需全路径建模。
- 详细答案:修复单点后仍要追溯已泄露数据、错误通知和缓存污染,安全事故不能只以“接口已恢复”收口。
- 进阶追问:跨境物流按客户租户隔离轨迹缓存、通知队列和导出对象存储路径。
- 进阶回答:问“如何测试”,回答构造两个租户相同业务键并发读写,覆盖同步、异步、重试、导出和运维路径。
2.7 项目事故决策与证据闭环
事故回答按事实时间线组织:先界定用户和资金影响,冻结高风险写或配置,保留证据;再用变更、指标、日志、Trace(链路追踪)和业务审计交叉定位;修复后回放差异、阶梯恢复、验证守恒;最后补门禁、演练和责任清晰的长期措施。重启、扩容和回滚都是动作,不是根因。项目表述中未知事实必须明确为假设,数据必须给统计口径。
| 阶段 | 决策问题 | 产物 |
|---|---|---|
| 定界 | 谁受影响、是否继续扩大 | 影响面、开始时间、风险等级 |
| 止血 | 先停什么、保什么核心能力 | 限流、熔断、冻结、降级记录 |
| 定位 | 哪个假设有跨信号证据 | 时间线、变更、关联标识 |
| 修复 | 如何处理已产生副作用 | 补偿、对账、数据修复脚本审计 |
| 验证 | 怎样证明恢复且无遗漏 | 守恒、回放、灰度与观察窗口 |
图十二:项目事故追问树
flowchart TD
A[告警或用户反馈] --> B[确认影响与风险]
B --> C{资金、库存或租户安全受损吗}
C -- 是 --> D[冻结高风险写并保留审计]
C -- 否 --> E[限流降级保护核心链路]
D --> F[建立分钟级时间线]
E --> F
F --> G[关联变更、指标、日志和链路]
G --> H[最小修复与小流量验证]
H --> I[对账和回放历史差异]
I --> J[门禁、演练和复盘验收]数据演绎十二:报警风暴先保事实再保通知
IoT(物联网)平台平时接收 3,000 EPS(每秒事件数),故障时升到 45,000 EPS(每秒事件数),通知下游只能处理 1,200 QPS(每秒查询率)。若每条事件同步通知,积压每秒增加 43,800 条,五分钟达 13,140,000 条。方案应先以稳定事件标识持久化原始事实,再按设备、规则和时间窗聚合成摘要,通知失败只影响时效,不丢审计事实;恢复后按风险等级重放。
热门面试题
- 问题:事故中为什么先定界和止血,而不是立刻找根因?
- 考点:损失控制、证据保全、并行处置。
- 回答思路:根因分析需要时间,故障仍在扩大时先冻结危险动作、保护核心链路和保留现场;定位可由另一组并行推进。
- 详细答案:止血动作可能改变现场,因此执行前记录时间、配置、流量和关键指标,并优先使用可逆开关。
- 进阶追问:支付未知结果上升时暂停自动发货,保留收款与查单能力。
- 进阶回答:问“回滚是否总是首选”,回答数据库、消息和外部副作用可能已产生,需先判断回滚兼容和副作用处理。
- 问题:怎样区分根因、触发器和放大器?
- 考点:因果链、系统韧性、长期措施。
- 回答思路:配置误推可能是触发器,无上限重试是放大器,缺少字段校验与灰度门禁是系统性根因;三层分别修复才能防复发。
- 详细答案:不能因为回滚配置后恢复就停止分析,还要验证为何错误能全量进入、为何告警未提前发现。
- 进阶追问:库存慢查询触发延迟,三层重试放大连接耗尽,缺少截止时间传播使故障扩散。
- 进阶回答:问“如何证实”,回答故障注入单变量复现,并比较禁用放大器前后的资源曲线。
- 问题:事故修复后如何验证历史数据没有遗漏?
- 考点:权威源、守恒、差异回放、人工闭环。
- 回答思路:按事故时间窗导出业务键,以权威流水重算目标状态,比较状态、金额、数量和事件水位;自动修复不可判定项转人工。
- 详细答案:只抽样不能证明资金与库存全量正确,高风险域应做全量守恒或分区逐批核对。
- 进阶追问:库存核对初始量、入库、预占、扣减、释放与当前量;支付核对渠道流水、支付单和账务分录。
- 进阶回答:问“修复脚本安全吗”,回答先只读预演、生成差异清单、双人审批、分批执行并保留可逆记录。
2.8 可观测性、审计与验证闭环
Metrics(指标)说明规模和趋势,Logs(日志)解释离散事件,Trace(链路追踪)连接调用过程,业务审计证明状态事实。采样 Trace(链路追踪)不能证明“没有发生”,高基数标签不能无限进入 Metrics(指标),日志也不能替代资金与库存流水。验证闭环必须同时覆盖技术健康、业务不变量、恢复积压与用户体验,并让每个结论能沿关联标识回到请求、事件、任务和状态变更。
| 证据 | 擅长回答 | 边界 |
|---|---|---|
| Metrics(指标) | 何时、多少、趋势是否异常 | 不解释单个业务事实 |
| Logs(日志) | 某次分支和错误上下文 | 可能缺失、重复或泄露敏感信息 |
| Trace(链路追踪) | 调用经过哪些节点、耗时在哪 | 采样且不等于业务审计 |
| 业务流水 | 状态为何改变、金额是否守恒 | 需要额外遥测解释性能根因 |
图十三:从告警到业务验证的证据链
flowchart LR
A[Metrics(指标)发现异常] --> B[按时间和版本缩小范围]
B --> C[Trace(链路追踪)定位慢节点]
C --> D[Logs(日志)确认分支与错误]
D --> E[业务流水核对状态事实]
E --> F[修复与历史回放]
F --> G[技术指标恢复]
F --> H[业务守恒恢复]
G --> I[观察窗口关闭]
H --> I数据演绎十三:采样结论的置信边界
支付异常率为 0.05%,Trace(链路追踪)采样率 1%,每小时 200,000 笔支付,异常约 100 笔,期望采到异常仅 1 笔,甚至可能为零。不能因链路样本无异常就否定用户投诉;应通过全量业务流水定位异常键,再对错误、长延迟和特定租户启用尾部或规则采样,同时控制敏感字段。
热门面试题
- 问题:为什么 Trace(链路追踪)不能替代业务审计?
- 考点:采样、事实证明、数据保留。
- 回答思路:链路通常采样且关注调用过程,业务审计需全量记录谁在何种前提下把状态从什么改到什么,并满足更长保留和防篡改要求。
- 详细答案:链路上下文丢失时仍应能用业务键串起流水,审计不能依赖一次请求始终在线。
- 进阶追问:支付以商户订单号、渠道流水和账务事件关联,Trace(链路追踪)只辅助定位回调慢在哪里。
- 进阶回答:问“日志可否做审计”,回答需结构化、权限隔离、防篡改和完整性保证,普通应用日志通常不满足。
- 问题:高基数标签为什么会拖垮监控?
- 考点:时间序列规模、标签设计、下钻路径。
- 回答思路:订单号、用户号进入 Metrics(指标)会为每个组合创建时间序列,放大内存、存储和查询成本;指标保留聚合维度,单键下钻交给日志和审计。
- 详细答案:租户维度也可能很高,可按重点租户、分层分组或独立业务报表治理,不直接无限打标签。
- 进阶追问:IoT(物联网)按区域和规则聚合指标,设备标识进入可检索日志与事件存储。
- 进阶回答:问“如何关联”,回答在告警中带时间窗、服务、版本和示例关联标识,再跳转查询明细。
- 问题:验证恢复为什么要同时看积压年龄和流量?
- 考点:表面恢复、存量债务、净处理能力。
- 回答思路:错误率下降可能只是入口流量被限,旧任务仍在老化;需同时看新增量、完成量、最老年龄和失败重试分布。
- 详细答案:平均年龄会被大量新任务稀释,应看最大值和分位,并按优先级队列拆分。
- 进阶追问:Runner(执行器)恢复以最老任务年龄回落、重复执行率和业务完成率共同验收。
- 进阶回答:问“何时关闭事故”,回答核心指标稳定、历史差异闭环、积压回基线且观察窗口内无复发后关闭。
2.9 综合决策演练与复习门禁
临场回答应在两分钟内先给结论和约束,再根据追问展开机制与失败边界。任何方案至少比较一个替代项,并给出切换或回迁条件;任何事故至少给止血、证据、修复和验证;任何项目数字都要能说明统计窗口与来源。复习不以“看过”完成,而以能够从业务不变量出发,走完七条追问树并链接到 01 至 07 权威章节为完成。
| 自检门禁 | 通过标准 | 不通过时回看 |
|---|---|---|
| 拆分 | 能给不拆、拆和回迁条件 | 01 演进与成本 |
| 边界 | 能说权威源与禁止旁路写 | 02 数据所有权 |
| 一致性 | 能区分分区、超时、复制延迟 | 03 一致性与脑裂 |
| 治理 | 能算预算与重试放大 | 04 服务治理 |
| 事务 | 能说未知结果和人工出口 | 05 事务与补偿 |
| 发布安全 | 能处理新旧共存和租户隔离 | 06 发布与安全 |
| 项目事故 | 能给时间线与验证证据 | 07 项目案例 |
图十四:从题目到验证闭环的口述路径
flowchart LR
A[题目场景] --> B[结论]
B --> C[约束]
C --> D[机制链]
D --> E[失败边界]
E --> F[项目证据]
F --> G[验证闭环]
G --> H{有替代与退出条件吗}
H -- 否 --> C
H -- 是 --> I[接受追问]数据演绎十四:两分钟回答的时间预算
一段 120s 的首轮口述可分为结论与约束 20s、机制链 35s、失败边界 25s、项目证据 25s、验证闭环 15s。若前 70s 都在解释术语,项目证据和失败处理只能被压缩成口号。训练时记录每段耗时,先保证六段完整,再根据追问扩展细节;这也是本册长题统一采用六段式而非百科式答案的原因。
热门面试题
- 问题:面试官只问“你们用了哪些微服务组件”时怎么回答?
- 考点:从组件回到问题、选型证据、版本边界。
- 回答思路:先说明业务痛点和约束,再说组件承担的具体职责、失败模式与替代方案;具体默认值只按项目实际版本回答。
- 详细答案:不清楚历史版本时明确说一般机制和待核对项,不编造配置键或默认行为。
- 进阶追问:注册中心解决实例目录,不承担库存一致性;消息系统解耦履约,不替消费者幂等。
- 进阶回答:问“为什么不用另一个产品”,回答比较协议、团队经验、运维成本和迁移风险,不做品牌式评价。
- 问题:怎样把一个项目讲出高级工程师深度?
- 考点:决策、权衡、失败、数据与复盘。
- 回答思路:从不变量与基线开始,解释为何选当前边界和机制,给一个真实失败窗口、关键数据、验证方法及未解决限制。
- 详细答案:没有线上事故可讲压测、演练和灰度中发现的问题,但必须区分生产事实与实验结果。
- 进阶追问:库存案例同时讲条件扣减、预占状态机、支付未知、释放补偿、对账和人工差错。
- 进阶回答:问“你的贡献”,回答自己做出的判断、推动的证据和验收,不把团队成果全部据为己有。
- 问题:如何处理面试题中缺失的容量和一致性前提?
- 考点:澄清问题、显式假设、分支回答。
- 回答思路:先问正确性和时延能牺牲什么;若无法追问,就声明两组典型约束并分别给方案,说明结论随前提变化。
- 详细答案:不要用过多假设拖延回答,应先给最常见场景结论,再指出改变结论的关键变量。
- 进阶追问:库存扣减默认强不变量,物流轨迹默认可接受分钟级投影延迟,二者方案不会相同。
- 进阶回答:问“最终选哪个”,回答依据损失、峰值、团队成熟度和演练证据,在明确前提下做单一决策。
2.10 综合题库过渡(非知识型)
以上知识节用于建立统一决策语言;以下综合题只训练跨章节口述、连续追问和证据闭环,不重复章节型六字段题。
3. 跨章节综合口述题
以下 45 道题用于完整口述训练。前 25 道保留迁移账本的稳定标识,后 20 道新增一致性、Quorum(法定人数)、时钟、数据所有权、安全、多租户与事故决策场景。每题答案都按六段决策链组织,并提供 3–5 个追问直答与至少一个真实分册链接。
问题(综合题):为什么从单体演进到微服务,什么情况下你会明确反对拆分?
口述答案:结论:我不会把微服务当技术升级,而把它视为用分布式成本换取独立变更、独立扩缩容和故障隔离的组织性选择;收益不能覆盖成本时,我会反对拆。约束:先看团队是否能端到端拥有服务,平台是否具备自动发布、监控、追踪、容量与值班能力,再看业务边界是否经过多次变更验证;需求仍在探索、团队只有数人、跨模块强事务密集时,模块化单体通常更稳。机制链:先在单体内按领域端口隔离依赖,用变更图和调用图寻找长期共同变化的模块;对确需独立扩容或发布的能力,以 Strangler Fig Pattern(绞杀者模式)旁路小流量,建立单一数据权威、兼容契约和回迁开关,再逐步切流。失败边界:拆后同步链变长、跨库事务增多、共同发布率不降或值班认知碎片化,说明边界或时机错误;此时应合并服务,而不是用缓存和重试继续掩盖。项目证据:跨境轨迹解析占大部分 CPU(中央处理器)且峰值独立,把它从订单接口拆出可用低规格实例弹性扩容;WMS(仓储管理系统)早期库存与波次规则频繁联改,则先保持同进程。验证闭环:比较拆分前后交付周期、共同变更率、故障半径、端到端延迟、机器成本和值班事件,连续多个迭代无收益就触发回迁评审。评审还要保留“继续模块化”的对照成本,并记录切流期间的双读差异、回退耗时和用户影响,防止只统计拆分后的局部性能收益。补充验收时,我还会保留继续模块化单体的对照组,记录切流中的双读差异、回退耗时、用户影响和团队值班负担;只有业务、组织和运行三类证据都改善,才确认拆分有效。
- 追问 1:单体一定不能独立扩容吗?直接回答:可以整体扩容或做内部异步隔离,只是不能按模块独立配置资源。
- 追问 2:拆分成功的第一指标是什么?直接回答:目标能力的独立变更或容量收益真实出现,而不是服务数量增加。
- 追问 3:回迁是否意味着架构失败?直接回答:不是,可逆和基于新证据调整本来就是架构治理的一部分。
- 关联专题:演进与成本模型
问题(综合题):微服务有哪些常被低估的缺点,怎样在项目中量化这些成本?
口述答案:结论:微服务最昂贵的部分通常不是多几台机器,而是网络不可靠、数据不再同事务、部署组合爆炸、观测与值班面扩大,以及团队跨边界协调;不量化这些成本,就无法证明拆分值得。约束:成本模型要覆盖运行时、研发、组织和风险四类,并以当前团队成熟度为基线,不能照搬大厂经验。机制链:一次本地函数调用变成序列化、服务发现、连接、超时、重试和鉴权;一次数据库事务变成状态机、消息、补偿与对账;一次发布变成接口、数据库、事件和配置的兼容矩阵;一个故障还要跨日志、Metrics(指标)和 Trace(链路追踪)定位。失败边界:调用跳数增加会吃掉用户截止时间,多层重试放大流量,共享库旁路写破坏自治,服务过多使每个团队无法理解和运营;若只关注平均延迟与主机费用,会漏掉尾部延迟、人工差错和事故恢复成本。项目证据:例如每次跨服务发布新增契约验证
12min,月均共同发布20次,就是显性协调成本;支付差错多一个跨边界状态,便新增对账、工单与审计负担。验证闭环:建立 TCO(总拥有成本)台账,持续记录服务数、告警数、发布失败率、跨服务变更占比、平均恢复时间、值班工时和资源费用;每季度按业务收益复盘,成本上升但交付和隔离没有改善时冻结继续拆分。台账还应把夜间值班、跨团队会议、演练和数据修复折算为工时,并按一次业务旅程而非单服务口径计算故障损失。成本复盘还要把夜间值班、跨团队会议、契约维护、演练与数据修复折算成工时,并按完整用户旅程统计损失;否则单服务账单下降会掩盖全链路成本上升。- 追问 1:网络调用成本只有延迟吗?直接回答:还包括部分失败、结果未知、重试重复和链路安全。
- 追问 2:平台能消除分布式成本吗?直接回答:只能标准化和降低操作成本,不能消除业务一致性与所有权决策。
- 追问 3:服务越少越好吗?直接回答:也不是,边界应匹配业务与团队,目标是总成本最低而非数量极端。
- 关联专题:TCO(总拥有成本)与组织成本
问题(综合题):你会怎样拆服务,如何证明边界不是按数据库表或技术分层拍出来的?
口述答案:结论:服务按业务能力、统一语言、核心不变量和变更原因划分,表、控制器或技术层只能作为实现线索,不能直接成为边界。约束:一个聚合内需要即时守住的不变量应尽量留在同一事务;跨边界交互必须允许网络失败并有明确所有权;团队要能独立开发、发布和运营。机制链:我先通过 Event(事件) Storming(事件风暴)梳理命令、事实、规则和外部系统,找出同一术语在不同上下文的含义冲突;再画 Context(上下文) Map(映射接口),确定上游、下游与 ACL(防腐层);随后用历史变更记录验证哪些规则总是共同变化,以数据写权限明确唯一权威。查询需求通过 API(应用程序接口)聚合或 Read Model(读模型)解决,不为一个页面强行合并写模型。失败边界:按表拆会把一个业务动作分散到多个服务,产生聊天式调用;按团队现状硬切可能固化错误组织;为追求“每服务一库”提前双写会形成双主。项目证据:WMS(仓储管理系统)中订单成交、库存预占、仓内履约与支付入账的“完成”语义不同,应由各自边界维护;工作台只复制摘要,不直接更新库存。验证闭环:以跨服务同步调用深度、共同发布率、旁路写审计、跨域事务数和需求变更落点复核;若长期高耦合且没有独立不变量,启动合并或重画边界。边界评审还要抽取真实需求,让不同团队分别指出规则修改位置和故障责任;若答案总是跨越相同几处,说明纸面上下文并未形成自治。边界评审会抽取最近真实需求,让各团队指出规则修改位置、数据写入者和故障责任;若答案总跨越同一组模块,就说明纸面限界上下文尚未形成自治。
- 追问 1:服务边界等于限界上下文吗?直接回答:不必一一对应,部署可因规模调整,但语义与所有权不能混乱。
- 追问 2:共享库一定错误吗?直接回答:迁移期可共享物理实例,但要分权限并保持单一逻辑写所有者。
- 追问 3:页面联表怎么办?直接回答:用读模型、聚合接口或离线数仓,并标明陈旧窗口与回源条件。
- 关联专题:DDD(领域驱动设计)与数据所有权
问题(综合题):请解释 CAP(一致性、可用性、分区容错),并给出库存与物流轨迹的不同决策。
口述答案:结论:CAP(一致性、可用性、分区容错)不是系统日常永久“三选二”,而是在网络 Partition(分区)已发生、存活节点无法互通时,对某个操作选择继续返回还是保持单副本实时一致;分区容错不是可关闭的产品开关。约束:要先定义一致性是线性读写语义,而非数据库合法状态或跨服务最终收敛,并区分超时、节点宕机和网络分区。机制链:若库存扣减必须防止两侧同时卖出,无法确认合法领导者或多数派的一侧就拒绝不确定写,并以任期、Quorum(法定人数)和 Fencing Token(栅栏令牌)限制写资格;物流轨迹是可合并事实,可在多接入点继续接收,记录来源版本,恢复后去重、排序和补拉。失败边界:客户端超时可能是请求已提交但响应丢失,换幂等键重试会重复扣减;多数派也不自动解决旧主迟到写,轨迹按最后物理时间覆盖会受设备时钟漂移影响。项目证据:库存侧以条件版本、预占流水和拒绝量证明保守写;轨迹侧以原始事件、版本缺口、收敛年龄证明可用接入。验证闭环:注入跨机房分区,确认少数侧关键写明确失败、查询提示状态;恢复后隔离旧主、核对分叉流水,并检查库存守恒及轨迹最终版本,不以“节点都在线”作为结束。演练报告还要分别统计被拒写数量、继续接收事件数量、分叉键和最终收敛时长,从而证明取舍与事先承诺一致。演练报告还应分别统计少数侧拒写量、继续接收事件量、分叉业务键和最终收敛时长,并验证客户端提示,避免技术上拒写正确、用户却误认为订单已经完成。
- 追问 1:缓存旧值算可用吗?直接回答:是业务降级意义的可服务,但不满足线性一致读,必须标出水位。
- 追问 2:没有分区时能同时有一致和可用吗?直接回答:通常可以做得很好,但仍受延迟、容量与普通故障约束。
- 追问 3:超时就代表发生分区吗?直接回答:不代表,还可能是排队、停顿、丢响应或节点故障。
- 关联专题:CAP(一致性、可用性、分区容错)边界
问题(综合题):BASE(基本可用、软状态、最终一致)怎样落成可以验收的工程承诺?
口述答案:结论:BASE(基本可用、软状态、最终一致)放宽跨边界立即可见,不等于放弃正确性;任何“最终会一致”都必须写出权威源、合法中间态、收敛时限、补偿和人工出口。约束:不同业务允许的窗口不同,支付和库存需要分钟内发现未知状态,物流摘要可能容忍更长;基本可用也不是统一返回成功,而是明确保留和牺牲哪些能力。机制链:本地事务先固化权威状态与待处理意图,消息或扫描推进下游;每步按业务键幂等,以条件状态机拒绝倒退;短时做有预算的退避重试,中时主动查询权威系统,长时对账并生成差异工单。Soft State(软状态)意味着状态还会被后续事件推动,所以要保存版本、来源和状态年龄。失败边界:消息可能重复、乱序或长期积压,补偿也会失败,外部渠道响应未知时不能猜成功或失败;没有最大时限的自动重试会掩盖永久错误并放大故障。项目证据:支付单保持处理中,复用商户请求号查渠道,确认后唯一入账;库存预占超时通过释放流水反向补偿;轨迹按事件版本收敛。验证闭环:设定例如
99.9%在5min内收敛、超过15min主动查证、超过30min转人工,监控状态年龄分位、差异金额和人工积压;通过停消费者、丢确认和渠道限流演练,确认恢复时间和业务守恒达标。对于超过目标但最终成功的长尾,也要复盘是哪一层积压、查询还是人工处置耗时,持续校准窗口而非删除超时样本。对于超过目标但最终成功的长尾,我会继续拆分消息积压、主动查询和人工处置的耗时,修正容量与时限模型;不能删除超时样本来制造漂亮的一致性数字。- 追问 1:最终一致是否有统一时间?直接回答:没有,必须按业务损失和恢复能力定义服务目标。
- 追问 2:补偿等于回滚吗?直接回答:不等于,它是新的业务动作,可能失败且要留审计。
- 追问 3:何时不能继续自动重试?直接回答:永久业务错误、金额冲突、超过预算或权威状态不明时。
- 关联专题:BASE(基本可用、软状态、最终一致)与收敛
问题(综合题):分布式事务有哪些方案,你会按什么决策链选型?
口述答案:结论:先缩小原子边界,再按资源是否受控、动作能否预留或补偿、一致窗口与阻塞成本选择方案,不存在覆盖所有外部副作用的万能分布式事务。约束:聚合内不变量优先本地事务;所有资源都支持协调协议、事务很短且可承受阻塞时才评估 XA(扩展架构事务)或 2PC(两阶段提交);支付渠道、物流和设备通常不可加入。机制链:可显式冻结资源时用 TCC(Try Confirm Cancel,尝试确认取消)并持久化 Try(尝试)、Confirm(确认)、Cancel(取消)阶段;长流程且动作可反向处理时用 Saga(长事务补偿);业务提交后要可靠发布事件时用 Outbox(发件箱),接收侧用 Inbox(收件箱)或唯一约束幂等;外部结果未知则进入状态机,主动查询和对账。失败边界:协调器故障会阻塞,TCC(Try Confirm Cancel,尝试确认取消)有空回滚和悬挂,Saga(长事务补偿)的退款或释放也可能失败,Outbox(发件箱)会重复发布,任何方案都要人工兜底。项目证据:库存预占可 TCC(Try Confirm Cancel,尝试确认取消)化,但支付扣款不能被本地协调器撤回;支付成功事件用本地事务加 Outbox(发件箱)传播。验证闭环:为每个候选方案制作失败矩阵,注入提交超时、协调器停机、重复消息、补偿失败和外部未知,比较锁时长、恢复时间、差异量与运维复杂度后定案。选型记录还要列出未采用方案、否决前提和未来切换条件,并由值班团队评估恢复复杂度;这样业务量或资源能力变化时可以重新决策,而不是被既有框架锁死。
- 追问 1:强一致一定更安全吗?直接回答:不一定,长时间持锁和阻塞可能让系统更不可用,并扩大故障面。
- 追问 2:Saga(长事务补偿)适合资金吗?直接回答:可编排业务流程,但资金事实要靠独立退款、冲正和账务对账。
- 追问 3:Outbox(发件箱)能保证消费者成功吗?直接回答:不能,只保证发送意图不与业务提交脱节。
- 关联专题:事务方案与失败窗口
问题(综合题):TCC(Try Confirm Cancel,尝试确认取消)适合什么场景,怎样处理悬挂、空回滚和重复调用?
口述答案:结论:TCC(Try Confirm Cancel,尝试确认取消)适合可显式预留、确认和释放的业务资源,例如库存名额、额度或席位,不适合没有预留语义的任意外部接口;正确性来自持久阶段与条件状态机,不来自调用顺序的侥幸。约束:Try(尝试)必须只预留不产生不可逆终局,Confirm(确认)和 Cancel(取消)都可重复,资源有明确过期与人工处理规则;全局事务号和分支号必须稳定。机制链:Try(尝试)先插入分支记录并条件冻结资源;Confirm(确认)只有已 Try(尝试)且未取消时才能提交;Cancel(取消)若先到,记录空回滚墓碑,之后迟到的 Try(尝试)看到已取消就拒绝,从而防悬挂;所有阶段读取已有结果,重复调用不再次增减。失败边界:网络可能让 Cancel(取消)先于 Try(尝试),执行者暂停后旧请求迟到,确认时资源已人工处理,协调器恢复可能重复驱动;只设超时自动释放不能防止旧 Try(尝试)复活。项目证据:WMS(仓储管理系统)库存预占记录保存订单行、数量、阶段和版本,释放写反向流水而非删除历史;支付渠道扣款不采用 TCC(Try Confirm Cancel,尝试确认取消)。验证闭环:排列阶段重复、乱序、进程崩溃和数据库超时,断言每个事务最终只有一个终态、库存守恒、空回滚可审计;长期未决分支进入扫描和人工差异队列。分支记录的保留期必须覆盖最长迟到、协调器恢复和人工争议窗口,清理前确认没有未决重试;否则刚删除空回滚墓碑,迟到的尝试阶段就可能重新冻结资源。
- 追问 1:Try(尝试)成功后资源能一直锁着吗?直接回答:不能,要有业务时限,但过期处理也必须受状态和版本约束。
- 追问 2:空回滚记录可以马上删吗?直接回答:不能,保留期至少覆盖迟到 Try(尝试)和最大重试窗口。
- 追问 3:Confirm(确认)失败怎么办?直接回答:在预算内幂等重试,超限后冻结分支并转人工,不改走 Cancel(取消)猜测。
- 关联专题:TCC(Try Confirm Cancel,尝试确认取消)阶段与异常
问题(综合题):最大努力通知如何设计,为什么它不是“多重试几次”?
口述答案:结论:最大努力通知用于对方不受控、无法加入本地事务且允许延迟收敛的外部通知;它是持久意图、分级重试、主动查询、对账和人工升级的组合,不是进程内循环重发。约束:必须区分通知事实与业务终局,定义对方幂等键、签名、防重放、频率限制、最大时限和最终谁为权威;支付、物流等场景不能因通知失败回滚已经发生的外部事实。机制链:本地事务写业务状态和通知任务,调度器按稳定业务键发送;明确失败按错误类型决定是否重试,超时标记未知并优先查询,不更换幂等键;退避与 Jitter(随机抖动)控制峰值,达到阈值转低频补偿;对方也可按业务键主动查本方,日终或周期对账补齐遗漏。失败边界:永久鉴权错误不应无限重试,响应丢失可能已成功,第三方限流会使积压恶化,通知内容版本变化可能让旧消息无法消费;人工队列积压也需分级。项目证据:支付渠道回调丢失时本地支付单保持处理中,复用商户订单号查单;跨境物流推送失败保留原轨迹事件,按客户配额重试。验证闭环:注入对方超时、成功响应丢失、限流和长期停机,检查重复副作用为零、未知状态按时升级、积压年龄回落;最终通过双方流水数量、状态与金额对账,而不是以 HTTP(超文本传输协议)成功率收口。通知台账还需记录首次失败、最近错误、下次执行与对方查询结果,值班人员才能区分仍在恢复、已永久失败和已由对账补齐。通知台账还需保存首次失败、最近错误、下次执行、对方查询结果与人工动作,才能区分仍在恢复、永久失败和已由对账补齐,并保证人工补发仍复用原业务键。
- 追问 1:为什么超时先查询?直接回答:请求可能已经生效,直接重发会重复副作用。
- 追问 2:通知任务能只放内存吗?直接回答:不能,进程重启会丢意图,至少要有持久台账。
- 追问 3:对账发现差异后怎么做?直接回答:可判定项按审计规则补发或修正,不可判定项进入人工复核。
- 关联专题:最大努力通知与外部未知
问题(综合题):接口幂等怎样设计,为什么“加一把锁”或“返回成功”并不够?
口述答案:结论:幂等是同一业务意图重复到达时重放同一业务结果,而不是简单拒绝第二次请求;正确性依赖稳定业务键、原子状态变更和结果持久化,锁只减少并发窗口。约束:先定义什么叫“同一意图”,支付尝试、退款和补单不能共用订单号;键的作用域、保留期、请求摘要和响应语义必须明确,调用方重试必须复用原键。机制链:服务端先验签和校验关键字段,以“业务类型 + 调用方 + 业务意图号”建立唯一约束;首次请求在本地事务中创建幂等记录并推进业务状态,完成后保存可重放结果;重复请求读取既有状态,处理中返回可查询标识,完成则返回相同结果,参数摘要冲突则报警。外部调用也传递同一键,超时先查结果。失败边界:内存去重会在重启后失效,分布式锁过期后旧请求仍可能提交,先写去重记录再业务提交会留下假完成,保留期过短会让迟到重试再次生效。项目证据:支付回调用渠道流水加商户号唯一入账;库存预占用订单行与动作号唯一写流水;Runner(执行器)步骤用任务号和步骤号重放产物。验证闭环:并发发送相同键、相同键不同参数、事务提交后丢响应、服务重启和超期重放,检查业务只产生一次效果、响应一致、冲突可审计,并监控重复命中率、处理中年龄和唯一冲突。还应测试首次请求永久卡在处理中时的接管规则,确保恢复程序只在租约和状态允许时继续,而不是创建第二个业务事实。还要测试首次请求永久卡在处理中时的接管规则,确保恢复程序只在租约和状态允许时继续;历史幂等记录清理前也要证明所有下游已越过最大重放窗口。
- 追问 1:只对写接口做幂等吗?直接回答:有副作用的读式接口也要做,按真实语义而非 HTTP(超文本传输协议)方法判断。
- 追问 2:唯一索引就足够吗?直接回答:它守住唯一性,但仍需状态机、结果重放和外部副作用处理。
- 追问 3:幂等记录多久清理?直接回答:至少覆盖最大重试、消息重放、对账与争议周期,高风险流水通常长期归档。
- 关联专题:幂等与重试边界
- 问题(综合题):微服务调用超时如何设置,怎样避免超时后工作仍在后台扩散?
口述答案:结论:超时不是每个客户端随便填一个秒数,而是从用户截止时间向内分配的端到端预算;超时到达后还要传播取消、停止无价值工作,并对结果未知做业务查证。约束:预算要覆盖网关、网络、排队、服务处理、下游调用和返回余量,以 P99(99 分位响应时间)和业务服务目标为依据;连接、读取和完整请求可有不同边界,支付与库存不可因超时直接判失败。机制链:入口生成绝对截止时间并透传,下游每一跳用剩余时间决定执行、降级或拒绝;线程池和连接池设置有界排队,已无预算的请求不再发起调用;客户端断开触发取消,服务内部检查取消信号;可幂等的瞬时失败只在剩余预算内由单一层重试。失败边界:仅设置客户端读取超时,服务端可能继续占线程并提交;层层各给 1s 会让总时长远超入口目标;超时立刻换键重试会重复扣款;过短超时则把正常尾部请求误判成故障并触发风暴。项目证据:下单目标 1000ms(毫秒),按网关、订单校验、库存和支付单创建分配预算,入口已耗时 700ms(毫秒) 时转异步处理中而非继续同步等待。验证闭环:注入排队、慢网络和响应丢失,核对截止时间逐跳递减、取消后在途和资源水位下降、未知支付按原键查证;监控超时率、取消成功率、超时后提交量和重试放大倍数。预算评审还要覆盖连接池等待和队列时间,否则只测下游处理耗时会高估可用预算,并在真实峰值下批量超时。预算评审必须显式计入线程池排队、连接池等待和序列化时间,否则只测下游处理耗时会高估剩余预算;峰值复测还要确认取消信号真的释放稀缺资源。
- 追问 1:超时越短越好吗?直接回答:不是,过短会误杀正常尾部并放大重试,要从服务目标和实测分位校准。
- 追问 2:连接超时和读取超时一样吗?直接回答:不一样,前者约束建连,后者约束等待数据,完整请求还需总截止时间。
- 追问 3:取消一定能停止下游吗?直接回答:不能保证,协议、线程和外部接口都要支持,业务仍需幂等与结果查证兜底。
- 关联专题:端到端超时预算
- 问题(综合题):熔断和降级如何配合,恢复时为什么容易发生二次雪崩?
口述答案:结论:熔断是跨请求状态机,用近期失败判断暂时不再施压;降级是业务在依赖不可用时保留何种诚实能力。熔断不能替代限流,降级也不能伪造成功,恢复必须小流量探测和阶梯放量。约束:规则要按调用目标、错误类型和业务操作隔离,库存不足等业务失败不能计为实例故障;阈值来自容量、尾延迟和损失,而非复制默认值;关键写与非关键查询的降级不同。机制链:Closed(关闭)状态正常采样,错误率或慢调用超过门槛进入 Open(打开),快速失败并释放资源;冷却后 Half-Open(半开)只放少量探测,成功稳定才逐级恢复。调用方将快速失败映射为排队、只读、缓存摘要或明确不可操作,并带数据水位。失败边界:恢复瞬间积压、连接重建和冷缓存叠加,会再次压垮下游;全局一个熔断器会让一个租户拖累所有租户;缓存旧库存若允许继续出库会破坏不变量;探测请求无隔离也可能被正常流量淹没。项目证据:物流轨迹页可展示带更新时间的旧摘要,WMS(仓储管理系统)库存权威不可确认时拒绝发货;IoT(物联网)普通通知可延迟,严重告警保留专用预算。验证闭环:故障注入慢调用与错误,检查状态转换、线程和连接释放、用户文案与业务动作;恢复按 5%、20%、50%、100% 放量,观察错误率、积压年龄和下游资源,任何档恶化自动退回。对照实验要分别验证熔断、限流和降级的贡献,避免多个开关同时变化后无法判断究竟哪个机制保护了容量。我会用对照故障分别验证熔断、限流和降级的贡献,避免多个开关同时变化后无法判断保护来源;半开阶段还要观察业务成功而非只看连接成功。
- 追问 1:熔断器能部署在网关统一处理吗?直接回答:入口可粗粒度保护,但最了解下游语义和幂等的调用方仍需细粒度规则。
- 追问 2:半开探测成功一次就恢复吗?直接回答:不应,需足够样本和资源稳定,且要限制恢复速率。
- 追问 3:降级数据要展示什么?直接回答:明确数据时间、水位和受限动作,不能让用户误以为实时完整。
- 关联专题:熔断、降级与恢复
- 问题(综合题):常见限流算法如何选,怎样避免大租户或重请求挤占系统?
口述答案:结论:限流是在已知容量内决定谁现在可以执行,算法只是表达预算的工具;选择要同时考虑突发容忍、时间平滑、分布式一致性、请求成本和公平性。约束:固定窗口简单但边界突刺,滑动窗口更平滑但状态更复杂;Token Bucket(令牌桶)允许受控突发,Leaky Bucket(漏桶)强调稳定输出;集群限流要说明局部额度误差和控制面不可用策略。机制链:先用压测找数据库、线程池、第三方配额和单租户安全上限,将总预算按业务优先级、租户和操作成本分层;入口做粗限流,服务按真实资源做细限流,重请求按权重消耗多个令牌;拒绝返回明确重试时间或排队标识,后台消费根据下游延迟动态降速。失败边界:只按请求数会让一个大导出等价于轻查询,单一全局桶会让大租户挤压小租户,客户端整齐重试会在窗口边界再冲击;限流中心故障时盲目放行可能压垮核心资源,盲目拒绝又会扩大不可用。项目证据:跨境物流按客户配额和轨迹查询成本分桶,支付回调和库存写保留独立预算;IoT(物联网)异常设备先单设备限速,不影响严重告警通道。验证闭环:用均匀、突发、倾斜租户和不同成本请求压测,核对允许量、拒绝公平性、尾延迟与下游水位;演练限流控制面故障,确认本地保守额度和降级策略可执行。上线后还要按拒绝原因区分容量保护和配置错误,持续比较被拒业务价值,防止规则长期过紧却无人发现。上线后需按拒绝原因区分容量保护与规则错误,持续比较被拒业务价值和租户公平性;大促前以目标租户分布重新校准,不能沿用日常均匀流量结论。
- 追问 1:限流和背压有什么区别?直接回答:背压是容量反馈,限流是依据反馈执行拒绝、延迟或降级。
- 追问 2:分布式限流必须绝对精确吗?直接回答:通常不必,保护容量更重要,但资金或配额扣减应由权威事务保证。
- 追问 3:被限流请求都该重试吗?直接回答:不该,需看截止时间、业务价值和服务端建议,避免同步重试风暴。
- 关联专题:限流与容量边界
- 问题(综合题):灰度发布如何做到新旧版本、数据和消息均可回滚?
口述答案:结论:灰度不是把少量流量导向新代码,而是验证新旧代码、数据库、消息和配置在每个中间态兼容,并在副作用已产生时仍有可执行的回退方案。约束:灰度标记必须来自可信路由并全链路透传,样本要覆盖关键租户和业务类型;门禁既看技术指标,也看库存、金额、状态分布等业务指标;回滚代码不能自动撤销数据和外部动作。机制链:数据库遵循 Expand/Contract(扩展/收缩),先加可选字段和兼容读写,再回填、比对、切换,最后收缩;API(应用程序接口)和事件先扩展新字段,旧消费者忽略未知可选字段;配置带版本、校验、审批和灰度范围。流量从内部到低风险租户逐级扩大,每档保留对照组和自动停止门槛。失败边界:共享数据库、缓存和消息会让非灰度用户被新格式污染;旧版本无法读取新数据时简单回流会继续报错;在途消息跨版本到达、配置回滚但副作用已发生,都会形成中间态。项目证据:支付新版本先只处理测试商户,比较渠道金额、支付单和账务事件;库存字段拆分先双读差异,不立刻删旧列。验证闭环:发布前执行兼容矩阵和回滚演练,灰度中按版本、租户观察错误、尾延迟、状态和金额守恒;失败时停新流量、冻结危险动作、处理已产生副作用并全量对账,确认历史差异清零后再继续。门禁记录应保存样本量、对照组、观察时长和停止原因,使下一次发布能复用证据,而不是重新凭感觉选择比例。门禁记录要保存样本量、对照组、观察时长和停止原因,使下一次发布能复用证据;若样本不足,即使暂时无错误也只能继续观察,不能直接扩大到全量。
- 追问 1:灰度为什么影响非灰度用户?直接回答:数据库、缓存、队列和下游通常共享,新版本写出的状态可能被旧版本读取。
- 追问 2:蓝绿发布就能立即回滚吗?直接回答:只能快速切流,数据模式和外部副作用仍需兼容与补偿。
- 追问 3:只看错误率够吗?直接回答:不够,正常响应也可能包含错误业务状态,必须看业务不变量。
- 关联专题:灰度、兼容与回滚
- 问题(综合题):线上慢请求如何从入口定位到根因,并证明不是凭经验猜测?
口述答案:结论:慢请求排查先确认影响范围和时间窗,再把入口分位延迟拆成排队、应用处理、下游等待和资源争用,用 Metrics(指标)、Trace(链路追踪)、Logs(日志)与业务审计交叉证明;平均值和单条日志不足以定性。约束:先保护用户与系统,限制无价值重试和重请求,保留现场;必须区分所有请求变慢、单版本、单租户、单业务键或单实例热点,不把相关变化直接当因果。机制链:从网关 P95(95 分位响应时间)和 P99(99 分位响应时间)按版本、路由、租户下钻;用 Trace(链路追踪)定位耗时跨度,再检查线程池排队、连接池等待、数据库锁和慢查询、外部限流、垃圾回收与网络;日志通过关联标识确认分支,业务流水确认请求是否已提交。失败边界:采样链路可能漏掉低频长尾,高基数标签可能拖垮监控;线程池已满时下游延迟看似不高,因为请求根本尚未发出;超时重试会让根因消失后压力仍持续。项目证据:库存慢查询触发订单等待,多层重试使连接池耗尽,根因链需要同时出现慢查询时间线、重试量和连接等待上升。验证闭环:先以限流或禁重试止血,再最小化修复;用相同流量回放比较各阶段耗时,确认 P99(99 分位响应时间)、队列、错误和业务成功率恢复,并保留观察窗口防止热点复发。复盘时还要解释为何监控未在用户投诉前发现长尾,并补充按版本、租户和业务键的受控下钻能力。复盘还要解释监控为何未在用户投诉前发现长尾,并补齐按版本、租户和业务键的受控下钻能力;修复收益必须在同一流量与数据分布下复测。
- 追问 1:没有 Trace(链路追踪)怎么办?直接回答:用统一关联标识串日志、访问记录、数据库会话和业务流水,先建立可证实时间线。
- 追问 2:重启后恢复说明什么?直接回答:只说明清除了某些状态,不能证明内存、连接、锁或流量放大的根因。
- 追问 3:先查数据库可以吗?直接回答:可以作为假设,但必须从影响分布证明请求确实在数据库阶段耗时。
- 关联专题:项目慢调用与重试事故
- 问题(综合题):MQ(消息队列)在微服务中承担什么作用,又有哪些职责绝不能交给它?
口述答案:结论:MQ(消息队列)提供时间解耦、削峰、广播和可恢复异步推进,使服务不必同步等待所有下游;它不能替代数据所有权、本地事务、消费者幂等、业务状态机和最终对账。约束:只有允许延迟且能定义处理中状态的步骤才适合异步,长期生产速率必须低于有效消费能力;消息产品的顺序、确认和事务能力要按实际版本核对,本册只讨论微服务组合边界。机制链:业务服务在本地事务中写权威状态和 Outbox(发件箱),发布器发送稳定事件;不同消费者按职责独立处理,用 Inbox(收件箱)或唯一约束吸收重复,状态机处理乱序,失败进入有预算重试和差异台账;积压以最老消息年龄和净消费速率治理。失败边界:发送确认丢失会重复,消费提交顺序错误会丢或重放,热点键限制并行,消息积压会把即时故障变成长期延迟;若把库存数只放消息中,无法守住并发不变量。项目证据:订单提交事件驱动履约、通知和分析,但库存预占仍由数据库条件更新;支付成功传播给账务,账务以支付单唯一记账并日终对账。验证闭环:在业务提交后停发布器、消费提交后丢确认、制造乱序和积压,确认事件可补发、重复无副作用、状态不倒退;计算恢复时间并核对订单、库存和金额守恒。容量验收还要模拟一个消费组长期停机,验证保留期、磁盘水位和恢复配额足以支撑重放,且不会压垮在线消费者。容量验收还要模拟一个消费职责长期停机,验证保留期、磁盘水位和恢复配额足以支撑重放,且不会压垮在线消费者;模式升级期间也要重放旧消息。
- 追问 1:用了事务消息还要幂等吗?直接回答:要,事务消息不替消费者提交业务,也可能重复投递。
- 追问 2:队列能无限削峰吗?直接回答:不能,长期超载会耗尽存储并拉长恢复时间。
- 追问 3:消息机制细节去哪里看?直接回答:由 MQ(消息队列)模块负责,本册只解释跨服务职责。
- 关联专题:消息一致性边界、MQ(消息队列)模块
- 问题(综合题):分布式锁能解决什么,为什么有租约仍需要 Fencing Token(栅栏令牌)?
口述答案:结论:分布式锁只能在锁服务所见范围内减少并发持有者,不能证明旧持有者已停止;涉及库存、任务和外部副作用时,最终正确性还要靠数据库约束、幂等与下游校验单调 Fencing Token(栅栏令牌)。约束:先问是否能用单库条件更新、唯一约束或分区串行替代;锁必须有所有者、租期、续租、释放校验和故障语义,不能把 Redis(远程字典服务)锁实现细节跨模块重复。机制链:执行者获得租约时同时取得递增代次,把代次随每次写传给权威存储;下游只接受大于已见代次的请求。执行者暂停超过租期后,新执行者获得更高代次并接管;旧执行者恢复即使仍持本地状态,其低代次写也被拒绝。释放时只删除自己的租约,业务步骤按任务号幂等。失败边界:续租线程正常不代表业务线程存活,进程长暂停可能失租后继续运行,主从切换可能让锁状态丢失,网络超时使获取结果未知;只有自动过期无法阻止旧请求迟到。项目证据:Runner(执行器)任务表保存所有者、到期时间和代次,产物提交比较代次;库存扣减则以条件更新为底线,不依赖锁保证不超卖。验证闭环:暂停旧执行者直至租约过期,让新执行者完成,再恢复旧者,确认旧代次提交被拒;同时注入重复消息、锁服务切换和释放超时,检查业务只产生一个有效结果并保留拒绝审计。若下游无法比较代次,我会把写入代理到可围栏的权威服务,绝不宣称租约已经提供排他正确性;监控还要区分正常锁竞争、续租失败和旧代次拒绝。
- 追问 1:锁续租成功就安全吗?直接回答:不够,业务线程可能停顿或与续租线程失联,下游仍需围栏。
- 追问 2:什么场景无需分布式锁?直接回答:单行条件更新、唯一键或天然按键串行能守住不变量时优先不用。
- 追问 3:代次从哪里生成?直接回答:由权威协调存储原子递增,并由最终写入方持久比较。
- 关联专题:租约与失主写入
- 问题(综合题):如何系统性防止微服务雪崩,而不是堆叠一组治理组件?
口述答案:结论:防雪崩的核心是控制负载、传播截止时间、切断资源传染并受控恢复,而不是把超时、重试、熔断、限流全开;组件组合必须围绕容量模型和业务优先级。约束:先找稀缺资源及安全上限,区分关键写、可降级读和可延迟任务;任何重试必须满足幂等、错误可能恢复、剩余预算充足和重试配额,任何队列必须有界。机制链:入口按租户与业务限流,截止时间逐跳传播;服务用独立线程池、连接池和队列隔离依赖,排队超限即负载卸除;下游变慢时通过背压降低生产,熔断已知故障并快速失败,降级为只读、带水位缓存或处理中;恢复时少量探测、阶梯放量,同时按净处理能力消化积压。失败边界:三层各重试三次可把流量放大 27 倍,无界队列把过载变成内存故障,共享线程池让通知拖垮库存,熔断全开后积压与冷缓存会触发二次雪崩;平均延迟正常也可能尾部已失控。项目证据:库存慢查询时先关闭网关和订单层重复重试,隔离非关键查询,保护预占写;IoT(物联网)风暴中保原始事件接入,普通通知聚合。验证闭环:压测稳定容量并注入慢依赖,记录到达量、有效成功量、在途、队列、重试倍数和 P99(99 分位响应时间);确认关键业务有预算、非关键降级可审计、恢复无二次峰值。还要在单租户、单实例和单业务键倾斜的负载下复测隔离,均匀流量通过并不能证明安全;恢复阶段逐档记录净处理能力,防止积压被新流量掩盖。
- 追问 1:扩容为什么可能无效?直接回答:瓶颈可能在数据库、热点键或外部配额,扩调用方只会增加压力。
- 追问 2:隔离池越多越好吗?直接回答:不是,过细会浪费资源和增加配置负担,应按故障域和业务优先级划分。
- 追问 3:队列能吸收所有突发吗?直接回答:不能,容量与恢复时限有限,接近红线时必须限流或拒绝。
- 关联专题:隔离、背压与负载卸除
- 问题(综合题):链路追踪如何建设和使用,它有哪些不能越过的证据边界?
口述答案:结论:Trace(链路追踪)用于还原一次请求跨服务的调用关系和耗时分布,是定位过程的证据之一;它通常被采样,不能替代全量业务审计,也不能单独证明低频事故没有发生。约束:上下文需跨 HTTP(超文本传输协议)、MQ(消息队列)和异步线程传播,但业务事实不能只存在上下文;采样率、敏感字段、高基数和存储成本必须治理,关联标识应稳定且不泄露密钥与个人信息。机制链:入口生成 TraceId(链路标识)与 SpanId(跨度标识),每个服务记录父子关系、开始结束、状态和受控属性;异步事件把关联上下文作为信封元数据,消费者创建新跨度并保留因果链接;Metrics(指标)先发现异常时间窗,Trace(链路追踪)定位慢跨度,Logs(日志)解释分支,业务流水确认最终状态。失败边界:1% 采样可能漏掉 0.05% 支付异常,线程池或消息中上下文丢失会断链,把订单号作为指标标签会产生高基数;即使链路显示调用成功,也不能证明账务只入了一次。项目证据:支付用商户订单号、渠道流水和账务事件串业务审计,Trace(链路追踪)只定位回调在哪个依赖耗时;Runner(执行器)用任务号关联多次接管。验证闭环:构造同步、异步、重试、跨线程和采样场景,检查上下文连续、敏感字段脱敏、成本可控;再从一条业务差异反查链路,也从链路回到权威流水,确保两类证据互补。采样策略也要验证低频错误、长延迟和重点租户能被规则采集,同时限制敏感字段与存储成本;从审计流水反查不到链路时,应保留缺口而非猜测调用过程。
- 追问 1:采样链路能做全量对账吗?直接回答:不能,对账必须读全量权威业务流水。
- 追问 2:TraceId(链路标识)可以当幂等键吗?直接回答:通常不可以,重试可能产生新链路,而业务意图仍是同一个。
- 追问 3:异步消息如何关联?直接回答:在消息元数据中保留因果上下文,消费者新建跨度并链接生产跨度。
- 关联专题:日志、指标与链路边界
- 问题(综合题):服务降级怎样兼顾用户体验和业务正确性?
口述答案:结论:好的降级不是把异常改成成功,而是在依赖或容量不足时保留最有价值且可诚实交付的能力,明确数据时效、受限动作和恢复路径;正确性不允许牺牲的领域宁可拒绝。约束:先按业务损失区分可陈旧、可排队、可省略和不可降级的功能,并为不同租户与优先级预留预算;降级结果要可识别、可审计,用户不能把旧摘要当实时权威继续不可逆操作。机制链:依赖异常由超时、限流或熔断触发后,查询类可返回带更新时间与水位的缓存,耗时任务返回已排队标识,推荐与通知可暂缓;库存、支付和租户授权不能确认时返回明确处理中或拒绝,并提供查询入口。恢复后按队列年龄和优先级补做,关键动作重新回源校验。失败边界:缓存雪崩时兜底本身也可能不可用,长期降级会形成数据债务,旧库存展示若仍允许发货会超卖;所有错误统一成友好文案会掩盖需要用户重试还是等待的区别。项目证据:跨境轨迹页可展示最近投影并说明更新时间,理赔与签收确认回原始事件;WMS(仓储管理系统)库存权威不可用时暂停出库;IoT(物联网)普通通知聚合但严重告警穿透。验证闭环:演练依赖停机,检查用户看到的状态、禁止动作、排队和恢复通知;统计降级量、持续时间、补做成功率与用户投诉,并在恢复后对账无遗漏。降级开关必须有到期提醒、责任人和恢复条件,避免事故结束后系统长期停留在低质量模式;用户补偿与延迟任务补做也要纳入同一关闭清单。
- 追问 1:降级页面返回
200就好吗?直接回答:状态码只是协议层,响应必须明确能力受限和数据水位。 - 追问 2:缓存兜底可以永久开吗?直接回答:不可以,要有最大陈旧时间和关键动作回源规则。
- 追问 3:谁决定降级优先级?直接回答:业务与技术共同依据损失、合规和容量制定,不由框架默认决定。
- 关联专题:降级与业务诚实
- 问题(综合题):如何理解“每服务一库”,共享库系统怎样安全迁移?
口述答案:结论:“每服务一库”首先是逻辑数据所有权和独立写权限,不要求第一天就为每个服务采购独立实例;迁移顺序应是语义与权限收口、契约化访问、数据校验,最后才是物理搬迁。约束:所属服务负责字段解释、不变量、模式演进和审计,其他服务不得旁路写;查询副本与 Read Model(读模型)可以复制数据,但不能成为反向写入权威。迁移期要避免长期双主,并明确按仓、租户或时间的切换水位。机制链:先盘点表和字段的写入者,以业务规则确定权威服务;创建最小命令接口,把旁路写改为调用并对剩余写入做审计告警;使用独立账号和权限强制边界;随后通过变更日志或事件构建新库,双读比对数量、版本和守恒,按分片切换写权,旧库变只读,观察后下线。失败边界:仅拆物理库但保留双写会产生顺序和部分失败;报表脚本、批处理与运维修数常是隐藏写者;回滚时新库已产生的数据若旧系统不识别,会形成分叉。项目证据:WMS(仓储管理系统)库存先从六个服务直接改表收口到库存域,再按仓迁移,订单工作台消费库存摘要而不改库存。验证闭环:持续扫描账号权限和 SQL(结构化查询语言)审计,核对旁路写为零;迁移逐仓比较初始量、入库、预占、扣减、释放和当前量守恒,故障演练切回前先冻结写并确认水位一致。迁移完成后必须删除旧账号、旧脚本和应急旁路,并周期扫描越权写;否则半年后一次手工修数就可能重新制造隐形双主,破坏已经建立的所有权。
- 追问 1:跨库事务怎么办?直接回答:先检查边界是否错误,确需跨域则用状态机、事件、补偿和对账。
- 追问 2:物理共库能独立发布吗?直接回答:可以一定程度独立,但模式变更与资源争用仍需治理。
- 追问 3:只读报表能直接查吗?直接回答:可走受控副本或数仓,标明时效并禁止演变为写入口。
- 关联专题:数据所有权与共享库边界
- 问题(综合题):跨服务查询有哪些方案,怎样在可用性、实时性和所有权之间取舍?
口述答案:结论:跨服务查询没有统一方案,低频且需要最新判定可用 API(应用程序接口) Composition(接口聚合),高频列表与统计更适合事件构建 Read Model(读模型)或 CQRS(命令查询职责分离);任何副本都要声明水位,关键动作回权威源。约束:先区分浏览、运营分析和不可逆命令前校验,设定可接受陈旧时间、扇出数量、失败策略与隐私范围;查询便利不能成为跨域写权限或把领域规则复制到聚合层。机制链:接口聚合并行调用有限服务,传播截止时间,对可选字段局部降级;读模型订阅各域事实,以事件版本和消费水位幂等更新,支持重建和差异校验;动作提交前携带用户看到的版本回权威服务条件校验,防止基于旧视图操作。失败边界:五个依赖每个失败率 0.6%,页面至少一次失败概率会接近 3%;读模型可能积压、乱序或规则升级,接口聚合也会形成 N+1(逐条查询放大)和重试风暴;把投影当权威会造成旧库存发货。项目证据:订单工作台用投影展示订单、库存和物流摘要,取消和出库操作分别回订单、库存域验证;跨境轨迹报表可接受分钟延迟。验证闭环:监控扇出延迟、局部失败、投影水位和重建耗时;停消费者后确认页面标记陈旧、关键动作被权威版本拦截,恢复后逐键比对投影与源数据。读模型重建演练应覆盖模式升级后的全量回放、消费水位恢复和关键动作回源,证明新投影可复现;不能依赖一份来源与规则都无法解释的历史快照。
- 追问 1:GraphQL(图查询语言)能解决跨服务查询吗?直接回答:它改善查询表达,不自动解决扇出、权限、缓存和一致性。
- 追问 2:读模型更新失败怎么办?直接回答:保留事件水位和原始事实,隔离毒事件并支持重放重建。
- 追问 3:CQRS(命令查询职责分离)一定要两套库吗?直接回答:不一定,核心是模型职责分离,物理部署按规模决定。
- 关联专题:跨服务查询与读模型
- 问题(综合题):配置中心怎样治理动态配置,如何处理错误配置已产生的业务副作用?
口述答案:结论:配置是能改变运行逻辑的生产代码,动态下发必须经过类型与语义校验、审批、灰度、版本化、审计和可验证回滚;回滚配置只停止继续扩散,不能自动撤销已生成的数据、消息和外部动作。约束:区分启动配置、可动态刷新配置和必须随版本发布的结构性配置;密钥不以明文普通配置传播;客户端断开控制面时使用最后已知良好版本还是拒绝启动,要按风险定义。机制链:配置以模式约束类型、范围和依赖关系,发布生成不可变版本并记录操作者与原因;先在测试实例和低风险租户灰度,服务加载前本地校验,原子切换并上报实际生效版本;业务和技术指标通过门禁后扩大。异常时停止发布、回滚到明确版本、隔离仍未同步的实例,并根据版本和时间窗找出受影响业务键。失败边界:配置中心可用不代表所有实例已一致,监听丢失会形成混合版本,错误阈值可能把正常业务拒绝,回滚后在途消息仍按旧规则处理;共享租户配置若权限错误会成为安全事故。项目证据:库存阈值配置误推后先停止新出库,按配置版本筛选已拒绝或误放行订单;IoT(物联网)规则变化保留规则版本,以便重算告警。验证闭环:演练非法值、部分实例断联、灰度异常和回滚,检查生效版本分布、业务差异、审计链和副作用补偿;定期验证最后良好版本可恢复,且配置权限最小化。每个实例还要上报配置内容摘要、加载来源和生效时间,而不只是版本号,防止本地覆盖或加载失败造成同版本不同值,并让排障能精确圈定影响窗口。
- 追问 1:所有配置都能热更新吗?直接回答:不能,影响数据结构、线程模型或安全边界的配置通常应随发布验证。
- 追问 2:配置回滚后为何仍报错?直接回答:实例可能未同步,在途请求和已生成消息也仍携带旧规则结果。
- 追问 3:配置中心故障业务要停吗?直接回答:按配置风险决定,通常保留最后良好版本,但高风险首次启动可拒绝。
- 关联专题:动态配置发布与回滚
- 问题(综合题):订单履约跨多个服务时,如何设计补偿避免状态互相覆盖?
口述答案:结论:订单履约应由可审计状态机和事实事件推进,每个服务只修改自己的权威状态;补偿是带业务语义的新命令,不是把所有库字段改回旧值。约束:先定义订单、库存、仓内履约、支付和物流各自终态与可逆窗口,明确取消、释放、退款和拦截的前置条件;所有命令有稳定幂等键,跨域不直接改表。机制链:订单确认后发布履约意图,库存条件预占并回传结果,仓内创建作业,支付按独立状态机确认;取消时编排器根据当前事实发出释放库存、取消作业或退款命令,每个服务用期望旧状态和版本裁决,执行结果再作为事实回传。超时只触发查询或补偿评估,不直接假定失败;Outbox(发件箱)保证意图可补发,对账扫描长期中间态。失败边界:释放可能先于预占消息到达,仓库已拣货时不能简单取消,支付成功但库存过期需要重新预占或退款,重复补偿可能多退金额;编排器也可能重启或持有旧视图。项目证据:WMS(仓储管理系统)以预占流水和出库任务为权威,订单只展示汇总;跨境物流拦截失败则转人工处置而非伪造已取消。验证闭环:排列成功、重复、乱序、超时和补偿失败,检查状态迁移合法、库存与金额守恒、每个命令结果可重放;超过状态年龄阈值进入差异队列并由人工闭环。人工补偿命令也必须经过相同的状态校验、幂等记录和审批,不能借管理员权限越过领域规则;否则第一次事故尚未闭环,修复动作又会制造第二次不一致。
- 追问 1:编排和协同怎么选?直接回答:长流程和复杂补偿用编排更清晰,简单事实传播可协同,但都要避免中心改他域数据。
- 追问 2:订单能否直接改库存状态?直接回答:不能,应向库存域发命令,由库存不变量决定是否执行。
- 追问 3:退款失败怎么办?直接回答:保留退款处理中,按同一退款号查证重试并对账,超限转人工。
- 关联专题:订单履约事故案例、Saga(长事务补偿)边界
- 问题(综合题):服务拆分过细有哪些信号,怎样决定合并而不是继续治理?
口述答案:结论:当服务没有独立业务不变量、不能独立变更和运营,却让一次请求频繁同步往返、共同发布和跨库事务成为常态时,拆分已经过细;合并是降低总成本的正式架构动作。约束:不能仅凭服务小或调用多就下结论,要结合历史变更、故障传播、数据所有权、团队认知和容量需求;某些专用高负载小服务即使代码少也可能有价值。机制链:从 Trace(链路追踪)统计同步链深度与聊天式调用,从版本库分析共同变更和联合发布,从数据库审计识别旁路写,从事故复盘观察是否总是一起故障;再检查能否重画为同一限界上下文和事务边界。合并前保留调用端口,把远程实现切成本地实现,确认单一权威后迁移数据,先双读校验再停止旧写和下线网络路径。失败边界:用缓存批量和重试可能暂时降低延迟却固化错误边界;贸然合并不同容量和合规域会放大故障半径;长期双写会造成分叉,回迁也需兼容发布。项目证据:订单状态与履约编排如果每一步都往返读取同一订单、每次发布都同行,应考虑同边界;轨迹解析有独立峰值和故障域则保持拆分。验证闭环:比较合并前后端到端延迟、跨边界事务、共同发布、资源利用和事故恢复,确保业务不变量与权限未弱化;收益不达标则保留可切换端口重新评估。合并后仍要保留模块依赖测试、数据权限和明确负责人,避免减少部署数量的同时重新形成无边界大模块;经过两个发布周期再比较维护成本,防止短期迁移波动误判。
- 追问 1:服务代码少就是过细吗?直接回答:不是,独立容量、合规或变更收益可以支撑小服务。
- 追问 2:合并要不要改领域模型?直接回答:若边界本就错误应重整模型;若只是部署合并,可先保留模块隔离。
- 追问 3:如何避免再次拆错?直接回答:先在模块化单体中验证变更和所有权,再渐进迁出。
- 关联专题:合并回迁条件
- 问题(综合题):你如何评价一个微服务体系是否健康,而不是只看服务可用率?
口述答案:结论:微服务健康度应同时衡量业务正确、交付自治、运行韧性、数据边界和总拥有成本;单服务 99.9% 可用并不代表端到端订单成功,也不代表架构值得。约束:指标要按用户旅程和业务不变量建立,避免平均值掩盖尾部与重点租户;健康评价必须与拆分目标绑定,例如独立发布、故障隔离或弹性成本,否则服务数量和调用成功率没有意义。机制链:业务层看订单成功、库存负数、金额差异、状态收敛年龄;架构层看跨服务同步深度、共同发布率、旁路写与契约变更;运行层看 P99(99 分位响应时间)、错误预算、重试放大、积压年龄、恢复时间和演练结果;组织层看每个服务是否有明确所有者、值班能力和认知负荷;成本层记录机器、平台、告警与协调工时。失败边界:可用率可能把降级和错误业务响应算成功,告警少可能只是缺监控,服务独立发布但每次仍需多人协调也不自治;追求单项指标会诱发隐藏失败或拒绝流量。项目证据:WMS(仓储管理系统)同时看库存守恒、出库时延和联合发布;支付看渠道、支付单、账务、订单四方差异;Runner(执行器)看任务年龄和旧栅栏拒绝。验证闭环:季度按目标做健康评审和故障演练,列出红线、趋势与责任人;若长期无独立收益且成本升高,触发合并、平台补强或边界重构,而非继续扩服务。健康评审结论要绑定下一季度的责任人、可验证动作和退出阈值,并抽查仪表盘背后的原始证据;否则指标会成为无人负责的展示,无法驱动合并或补强决策。
- 追问 1:服务可用率还有价值吗?直接回答:有,但只是局部信号,必须与用户旅程和业务正确性关联。
- 追问 2:共同发布率高一定要合并吗?直接回答:不一定,还要看合规、容量与边界;它是强烈复核信号。
- 追问 3:错误预算怎样使用?直接回答:把可靠性消耗与发布速度绑定,预算耗尽时优先修复韧性。
- 关联专题:微服务成本与回迁、项目验证指标
- 问题(综合题):
N=5,W=3,R=3为什么仍可能读旧,扩缩容时怎样保护 Quorum(法定人数)交集?
口述答案:结论:W + R > N 只在固定成员集合和正确读写协议下保证集合相交,不自动提供线性一致;读旧还可能来自并发写、旧主响应、读取未比较版本和成员配置切换。约束:必须明确 N 是哪个配置纪元的成员、成功写的确认点、版本如何排序、读是否等待足够副本,以及故障时是否允许滑动 Quorum(法定人数)。机制链:正常写把值和单调版本提交到当前配置多数,读收集当前配置多数并按协议选择已提交版本;成员变更采用联合配置,让旧集合和新集合的多数都确认过渡项,再切换到新配置,避免两个不相交多数各自写入。客户端若要求读己之写,可携带已见提交水位并在落后节点等待或转领导者。失败边界:把故障节点临时替换为任意节点形成滑动集合,可能让读写集合不相交;新节点尚未追平就计入多数会缩弱安全;按物理时间选最大值受时钟偏差影响;网络恢复后旧配置节点不能直接服务。项目证据:Runner(执行器)所有权使用权威代次而不是仅靠三个副本“多数”,库存关键写只在合法任期提交。验证闭环:在持续读写中执行加节点、移节点、分区与领导切换,记录配置纪元、确认集合和提交索引,检查单调读、已确认写不丢;发现旧配置请求必须拒绝并审计。成员变更还要演练新节点追平前故障和旧配置请求迟到,确认联合阶段不会出现两个合法写集合;运维手册必须禁止为恢复可用性而临时拼出滑动多数。配置切换证据需长期归档备查。
- 追问 1:
R=1能做到强一致读吗?直接回答:可以走合法领导者或读屏障,但不能任意读一个副本。 - 追问 2:副本越多越安全吗?直接回答:故障域更丰富,但确认延迟、成本和恢复时间也增加,协议错误仍不安全。
- 追问 3:联合配置解决什么?直接回答:让成员切换期间新旧多数有受控交集,避免双重合法配置。
- 关联专题:Quorum(法定人数)边界
- 问题(综合题):线性一致、单调读和读己之写如何选,订单查询怎样避免状态倒退?
口述答案:结论:一致性模型按用户可观察需求选择,不是全系统统一追求最强。库存扣减和所有权切换常需线性化裁决,订单浏览至少要单调读,用户提交后的确认页通常需要读己之写;轨迹明细可容忍迟到但聚合状态不能倒退。约束:越强语义通常需要领导者、Quorum(法定人数)或等待复制,增加延迟与分区拒绝;要先定义会话范围、允许陈旧时间、是否跨设备以及关键动作是否回源。机制链:写成功返回提交版本,客户端或会话保存已见水位;后续查询携带水位,路由到已追平副本,未追平则等待、转权威节点或返回处理中;Read Model(读模型)按事件版本单调更新,浏览显示投影时间,取消与发货再读取权威状态并做条件更新。失败边界:轮询随机从库会看到“已支付”退回“待支付”,负载均衡切实例会丢会话水位;把物理时间当版本会受回拨影响;只保证用户自己的写可见,不代表其他用户立即看到。项目证据:订单确认返回订单版本,工作台投影落后时仍不得覆盖更高版本;跨境轨迹版本 43 先到后,迟到 42 只入明细。验证闭环:制造副本延迟、切换会话实例和乱序事件,断言同一会话状态不倒退、关键动作读取权威版本;监控等待追平耗时、陈旧读率和投影水位差。会话水位需要跨实例可靠传递并限制大小,移动端重新登录或跨设备时则明确降级为哪种语义;关键动作回源失败时宁可提示处理中,也不能基于旧投影继续。
- 追问 1:读己之写等于线性一致吗?直接回答:不等于,它只约束会话看到自己的写,不约束所有客户端全局实时顺序。
- 追问 2:把请求固定到一个从库够吗?直接回答:不够,该从库可能落后或故障,仍需版本水位校验。
- 追问 3:状态快照乱序怎么办?直接回答:按来源版本条件更新,低版本保留审计但不覆盖聚合。
- 关联专题:一致性模型与客户端观察
- 问题(综合题):物理时钟、单调时钟与 Hybrid Logical Clock(混合逻辑时钟)分别解决什么,项目里怎样避免误用?
口述答案:结论:物理时钟用于人类时间和审计区间,单调时钟用于本进程经过时长,Hybrid Logical Clock(混合逻辑时钟)在接近物理时间的同时表达因果推进;三者都不能凭一个时间戳自动解决跨系统业务顺序。约束:主机时钟会漂移和回拨,单调时钟不可跨进程或重启直接比较,逻辑时钟依赖传播且只能描述所见事件;设备时间尤其不可信。机制链:超时、退避和租约本地时长使用单调时钟;订单创建、审计和用户展示保存物理时间并记录时区与来源;分布式事件需要因果关系时携带逻辑分量,接收方取本地与远端最大值后推进。业务版本仍由权威状态机、数据库版本或来源序号决定,支付以渠道流水,库存以事务版本,Runner(执行器)以 Fencing Token(栅栏令牌)裁决。失败边界:物理时钟回拨会让租约延长、最后写入胜出覆盖新值;Lamport Clock(兰伯特时钟)数值大小不能判断并发;Hybrid Logical Clock(混合逻辑时钟)也不能证明外部扣款先后或替代唯一约束。项目证据:物流同时保留设备发生时间、平台接收时间和规则处理时间,聚合按来源序号与业务阶段,不按最大设备时间;租约时长用单调钟。验证闭环:演练时钟前跳、回拨、跨时区与消息迟到,检查超时不异常延长、状态不倒退、审计可解释;监控时钟偏差并将超阈值节点隔离出关键选主。所有时间字段还应登记来源、精度、时区和用途,告警只用于发现时钟异常,不把校时成功当作业务顺序证明;偏差超阈值节点应退出关键租约与选主。
- 追问 1:NTP(网络时间协议)同步后能用时间戳做版本吗?直接回答:仍不能保证严格单调和因果,关键版本应由权威序列生成。
- 追问 2:单调时钟能持久化吗?直接回答:通常不能跨重启解释,只用于当前进程时长。
- 追问 3:逻辑时钟会无限增长吗?直接回答:数值可扩展但元数据与成员管理有成本,需按协议治理。
- 关联专题:物理、单调与逻辑时钟
- 问题(综合题):确认发生脑裂后,如何止血、选择权威历史并安全恢复服务?
口述答案:结论:脑裂恢复的第一目标是停止多个写入权威继续产生分叉,随后依据合法任期、提交证明和业务流水选择或重建权威历史;不能简单按时间戳较大或数据量较多的一侧覆盖。约束:要区分复制延迟与真正双主,保留网络、成员视图、任期、提交索引和外部副作用证据;资金、库存和设备控制的分叉不能用通用键值合并规则处理。机制链:先从入口和下游同时冻结疑似旧主写,保留只读查询和人工通道;确认最后共同提交点、各侧任期与写集合,隔离不合法成员;可重放的轨迹事实按事件标识合并,不可交换的库存与支付逐笔对照订单、预占、渠道和账务流水,生成补偿或人工裁决;旧节点丢弃分叉、从权威快照重建并以新任期加入。失败边界:旧主虽然被摘流,已发出的延迟请求仍可能到达,所以权威存储必须拒绝低 Fencing Token(栅栏令牌);物理时间可能偏差,外部扣款无法靠覆盖数据库撤销;贸然清日志会丢证据。项目证据:库存分叉以预占流水和仓内作业确认哪些业务已真实发生,支付以渠道账单为外部事实;轨迹允许合并全部原始事件后重算。验证闭环:恢复前全量计算分叉键和金额数量影响,恢复后重放、守恒和抽样用户确认;再次注入同类分区,证明少数侧写被拒、旧代次迟到写不可见,观察窗口内无新差异。恢复决策清单要记录每个分叉键的自动合并、补偿或人工裁决理由,修复脚本先只读预演再分批执行;任何无法解释的差异都不能用覆盖操作悄悄抹平。
- 追问 1:为什么不保留记录更多的一侧?直接回答:数量不代表合法提交,可能包含少数侧未确认和重复写。
- 追问 2:只读能马上开放吗?直接回答:可在标明水位且不触发关键动作时开放,否则旧读也会误导业务。
- 追问 3:脑裂结束的标准是什么?直接回答:单一写权威恢复、历史差异闭环、旧主被围栏且演练验证不再分叉。
- 关联专题:脑裂与事故证据
- 问题(综合题):共享数据库中两个服务都声称拥有客户地址,如何裁决所有权并迁移?
口述答案:结论:所有权不由谁先建表或谁调用更多决定,而由谁定义语义、维护不变量、承担变更与审计决定;“客户联系地址”和“订单履约地址”即使字段相同,也可能是不同生命周期的事实。约束:先澄清地址是否允许订单创建后随客户资料变化、谁有法律与审计责任、历史订单是否必须保留快照;迁移期间只能有一个当前写权威,不能让两个服务互相覆盖。机制链:通过 Event(事件) Storming(事件风暴)梳理“客户修改地址”“订单确认地址”“仓库发货”等事实,确定客户域拥有可变联系信息,订单或履约域拥有下单时地址快照;为旧共享列建立读取适配,新增明确字段与版本,所有新写经过所属服务命令;历史数据按来源和时间回填,双读比对,达到水位后撤销旁路账号权限。失败边界:直接按最新客户地址更新历史订单会让已发货证据改变;长期双写会因顺序、重试和部分失败分叉;报表和批处理可能仍绕过接口。项目证据:跨境物流订单保存报关和收件快照,客户资料后改不反向污染历史;WMS(仓储管理系统)发货只读订单确认地址。验证闭环:审计所有写来源、比较历史订单与出库单快照、构造客户修改与订单发货并发;迁移后旁路写为零,权限测试和数据守恒通过,并保留回滚水位。迁移验收还要覆盖历史订单不可被客户资料后改污染,并检查报表、导出和运维脚本的读写方向;只有写权限与语义责任同时收口,所有权才真正成立。
- 追问 1:同一字段能有两个副本吗?直接回答:可以,但要区分权威事实与业务快照,并定义同步方向。
- 追问 2:谁负责修历史脏数据?直接回答:由权威域定义规则,数据治理协作执行并留审计,不由消费方自行猜测。
- 追问 3:所有权会变化吗?直接回答:会,但需正式迁移写权、契约和责任,不能隐式漂移。
- 关联专题:聚合与数据所有权
- 问题(综合题):领域事件由谁拥有,事件模式升级如何避免生产者和消费者相互绑死?
口述答案:结论:事件由产生该事实的领域拥有语义和发布契约,消费者拥有自己的投影与处理逻辑;生产者不能为每个消费者定制内部状态,消费者也不能反向要求修改生产者数据库。约束:事件必须描述已发生事实而非远程过程调用命令,包含稳定事件标识、聚合标识、业务版本和必要语义;隐私字段最小化,模式变更要兼容在途消息、重放和旧消费者。机制链:生产者在本地事务写业务与 Outbox(发件箱),发布版本化事件;新增字段先设为可选,消费者忽略未知字段并对缺失字段使用有语义的默认或停入隔离队列;重大语义变化发布新事件类型或版本,通过双发、消费水位和差异比对迁移,确认旧消费者退出和历史重放策略后再收缩。失败边界:把数据库行镜像成事件会泄露内部结构并诱发强耦合;字段改名直接覆盖会让旧消息无法重放;消费者把事件当命令重复产生外部副作用;双发无关联标识会执行两次。项目证据:支付域发布“支付已确认”并带支付单与金额,不暴露账务表结构;履约域据此创建任务,账务域独立唯一入账。验证闭环:用新生产者对旧消费者、旧消息对新消费者做契约测试,保留模式样本和兼容矩阵;灰度期间核对双版本消费结果、重复命中和水位,完成后演练历史重放。模式治理还应保存代表性旧消息和最新契约样本,作为每次发布的兼容测试输入;消费者若需要无法兼容的新语义,应创建新事件而不是偷偷改变旧字段含义。
- 追问 1:消费者需要更多字段怎么办?直接回答:先判断是否属于事实语义,必要时扩展契约或由消费者回权威接口查询。
- 追问 2:事件版本放哪里?直接回答:放在稳定信封或模式标识中,并与业务版本分开。
- 追问 3:可以删除旧事件类型吗?直接回答:需确认保留期、重放、所有消费者和灾备恢复都不再依赖。
- 关联专题:领域事件发布边界、事件兼容
- 问题(综合题):客户端篡改 tenantId(租户标识)时,微服务链路如何防止越权与串租户?
口述答案:结论:tenantId(租户标识)不能由客户端普通参数决定,必须由服务端从已验证身份和授权关系推导,并在网关、领域服务、数据访问与审计层纵深强制;网关校验一次并不足够。约束:内部调用、异步消息、批任务和运维入口都可能绕过公网网关,租户上下文要可验证、短时有效且最小权限;超级管理员和跨租户操作必须显式审批,不能复用普通业务路径。机制链:Gateway(网关)验证令牌签名、受众、有效期和主体,查出允许租户并生成签名上下文;领域服务再次校验动作、资源归属与上下文一致,忽略请求体自报租户;数据层强制租户谓词、行级策略或独立账号,缓存键、对象路径和消息信封都含可信租户维度;审计记录身份、代理关系、租户、资源和决定。失败边界:内部服务盲信可伪造请求头、消息重试丢租户上下文、批处理使用全局账号漏条件、管理员权限长期开放,都会造成串扰;仅修接口无法撤回已经泄露的数据。项目证据:跨境物流按客户租户隔离运单查询、轨迹导出和对象存储路径,WMS(仓储管理系统)按货主与仓库双重授权。验证闭环:用两个租户相同业务键覆盖同步、消息、缓存、导出和批任务,尝试篡改头与载荷;检查服务拒绝、数据库无越权行、审计告警可关联,并定期扫描无租户谓词查询。安全验证不能只看接口拒绝,还要检查缓存、搜索索引、对象存储和审计日志是否留下越权副本;一旦发生泄露,需按租户和时间窗通知、清理并复盘。
- 追问 1:内部网络可信就能信请求头吗?直接回答:不能,内部也有误配置、横向移动和绕行,应验证签名或重新校验令牌。
- 追问 2:管理员如何跨租户?直接回答:走独立受审计命令,短期授权、明确原因和双人审批。
- 追问 3:租户字段由前端隐藏够吗?直接回答:完全不够,安全边界必须在服务端和数据层强制。
- 关联专题:多租户身份与数据隔离
- 问题(综合题):数据库已按租户隔离,为什么缓存、队列和限流仍可能造成串扰?
口述答案:结论:多租户隔离是全链路属性,数据库正确不代表缓存键、消息上下文、对象存储、限流预算和日志正确;这些派生或共享资源同样可能泄露数据或让大租户拖垮其他租户。约束:每一层都要定义租户标识来源、资源命名、配额、加密密钥和审计方式;租户维度进入缓存与队列时必须来自可信上下文,不能再次采信载荷普通字段。机制链:缓存键使用“环境 + 租户 + 业务类型 + 业务键 + 版本”,失效只作用于所属租户;消息信封携带签名租户和事件标识,消费者在写库前核对资源归属;队列、线程池和第三方配额按租户或优先级分层,限流至少给小租户保底;对象存储路径与密钥策略隔离,日志脱敏且访问审计。失败边界:遗漏租户前缀会让相同订单号命中他人数据,全局热点缓存失效会跨租户放大,消息重试复制时丢上下文会写错库,大租户共享全局令牌桶会饿死小租户;日志即使不影响业务也会泄密。项目证据:跨境物流不同客户可能拥有相同外部运单号,因此缓存和通知幂等键必须包含承运商与租户;IoT(物联网)异常租户单独限速,不占严重告警总预算。验证闭环:构造相同业务键和倾斜流量,检查缓存命中来源、消息落库、配额公平与日志访问;故障后清理受污染缓存、追踪错误通知并做全量泄露影响评估。共享资源的容量报表要同时展示总量与租户分布,避免大租户降速后总指标恢复却小租户仍饥饿;恢复时按保底、权重和业务风险逐级归还配额。
- 追问 1:所有队列都要物理分租户吗?直接回答:不必,可逻辑分区与配额隔离,高风险或超大租户再独立通道。
- 追问 2:租户进入指标标签会怎样?直接回答:租户过多会形成高基数,应分层聚合或为重点租户单独观测。
- 追问 3:缓存串扰修复后就能结案吗?直接回答:不能,还要追踪已返回数据、导出和通知,按安全事故闭环。
- 关联专题:缓存、队列与租户隔离
- 问题(综合题):微服务内部怎样做身份、授权与最小信任,服务发现是否等于可信?
口述答案:结论:能被服务发现只说明实例目录可见,不代表调用者或目标可信;内部调用必须建立服务身份、传输保护、最小权限和领域终局授权,并对机器与用户身份分别审计。约束:安全方案要覆盖证书或令牌生命周期、轮换、时钟偏差、紧急吊销和控制面故障,避免把长期共享密钥散落配置;服务身份只能证明“谁在调用”,不能替代“是否能操作该资源”。机制链:实例通过受控工作负载身份获得短期凭证,通信使用 TLS(传输层安全协议)或 mTLS(双向传输层安全协议)验证双方;令牌限制受众、作用域和有效期,Gateway(网关)传递用户上下文,领域服务同时校验服务调用权限、用户权限、租户和资源状态;密钥由专门系统轮换,策略变更审计。失败边界:注册中心被污染可能注入恶意地址,内部明文连接可被窃听,通用超级令牌扩大横向移动,证书过期会造成大面积拒绝;只在网关授权无法覆盖消息和定时任务。项目证据:支付回调入口先验渠道签名,内部账务调用还验证服务身份和支付单状态;Runner(执行器)只能写所属任务分片,不拥有全库权限。验证闭环:演练过期证书、错误受众、撤销权限、伪造实例和时钟偏差,确认失败封闭且核心应急路径受控;定期审计未使用权限、长期凭证和跨服务调用矩阵。凭证轮换演练要覆盖新旧短期重叠、紧急吊销和控制面暂时不可用,确认服务不会回退到长期共享密钥;权限矩阵还要定期删除已经没有调用证据的授权。
- 追问 1:mTLS(双向传输层安全协议)能替代业务授权吗?直接回答:不能,它证明连接双方身份,不判断用户、租户和资源状态。
- 追问 2:服务发现如何防污染?直接回答:控制注册权限、验证实例身份、保护控制面并在客户端校验证书与目标。
- 追问 3:短期凭证过期怎么办?直接回答:提前轮换并允许小重叠窗口,失败时按业务风险降级,不能回退长期明文密钥。
- 关联专题:分层信任边界
- 问题(综合题):外部回调如何防重放,为什么时间戳、Nonce(随机数)和幂等键缺一不可?
口述答案:结论:防重放需要验证消息确来自可信对方、仍在允许时间窗、未被同一语义重复使用,并让重复到达不产生第二次业务效果;签名、时间戳、Nonce(随机数)和业务幂等键分别解决不同问题。约束:签名覆盖方法、路径、关键头和原始正文摘要,密钥可轮换;时间窗要容忍合理偏差但不能无限,Nonce(随机数)保留期覆盖窗口;业务幂等键应代表渠道交易或回调事件,不能用每次请求新生成的随机值替代。机制链:入口先检查密钥版本与签名,再校验时间戳和受众,原子登记“调用方 + Nonce(随机数)”;随后验证商户、订单、币种、金额和渠道流水,以渠道流水唯一推进支付状态并保存响应;重复 Nonce(随机数)直接拒绝,新的 Nonce(随机数)但同一渠道流水则重放已有业务结果。失败边界:只看时间戳允许攻击者在窗口内多次重放,只存 Nonce(随机数)在缓存重启后会失效,只做幂等不验签会接受伪造数据;时钟漂移过大会误拒绝,密钥轮换中旧新版本需受控共存。项目证据:支付回调以渠道流水唯一入账,金额冲突进入安全差错队列;物流伙伴回调同样保存原文摘要与签名结果。验证闭环:重放完全相同请求、改正文、换 Nonce(随机数)重放同一流水、模拟时钟偏差和密钥轮换,确认伪造拒绝、合法重复无副作用、冲突告警并可审计;定期核对重放拦截与业务重复率。对重放拦截的监控要区分攻击、调用方正常重试和本地幂等命中,防止一条规则同时误伤合法回调;争议事件保留原始报文摘要与密钥版本供审计。
- 追问 1:Nonce(随机数)放数据库还是缓存?直接回答:按风险选择,支付等高风险需持久或具备可靠恢复,普通接口可用带持久保障的缓存。
- 追问 2:签名成功就能更新订单吗?直接回答:不能,还要校验业务归属、金额、状态和幂等流水。
- 追问 3:时间窗多大合适?直接回答:依据网络延迟、对方重试和时钟偏差设定,并监控拒绝分布持续校准。
- 关联专题:防重放与敏感审计
- 问题(综合题):库存预占、支付扣款和订单确认同时存在时,事务方案如何取舍?
口述答案:结论:我不会把三个动作塞进一个跨系统强事务,而是让每个领域用本地事务守住自身不变量,再用状态机、可靠事件、查询与补偿协调;是否先库存还是先支付由缺货损失、资金占用和渠道能力决定。约束:库存不能负数,支付不能重复扣款,订单不得把未知结果标成失败或成功;外部渠道不可加入本地事务,补偿退款与库存释放都可能失败,必须有明确处理中状态和人工出口。机制链:下单先创建订单意图,库存以订单行和动作号条件预占并写流水;成功后创建支付单,渠道调用使用稳定商户请求号,超时保持未知并查单;渠道确认成功后本地事务推进支付单并写 Outbox(发件箱),订单消费后确认。若库存预占过期而支付已成功,先尝试重新预占,失败则创建独立退款单;订单取消发释放命令,各服务按状态和版本裁决。失败边界:支付响应丢失后换号重试会重复扣款,释放消息先于预占到达不能直接加库存,补偿失败会长期占用资源;编排器自身重启也会重复发命令。项目证据:WMS(仓储管理系统)以预占流水守恒,支付以渠道流水和账务分录守恒,订单只汇总状态。验证闭环:组合注入库存冲突、支付超时、消息重复乱序、退款失败和进程重启,检查数量金额守恒、状态不倒退、未知单按时查证与升级,并做四方对账。流程级服务目标还要分别规定库存占用、支付未知和退款处理的最大年龄,避免总订单成功率掩盖少量长期资金问题;超限记录必须自动升级到人工责任人。
- 追问 1:能先扣款再扣库存吗?直接回答:可以,但要接受退款率和资金占用,且退款链路必须成熟。
- 追问 2:预占多久过期?直接回答:按支付时延分布和业务容量设定,过期必须经状态机释放。
- 追问 3:编排器是不是单点?直接回答:状态持久化后可多实例接管,命令仍需幂等和围栏。
- 关联专题:库存与支付项目链路、外部未知结果
- 问题(综合题):数据库提交返回超时,服务不知道事务是否成功时应怎样处理?
口述答案:结论:提交超时是结果未知,不等于回滚;调用方和服务都必须复用原业务键查证,不能用新键重做,也不能凭内存状态告诉用户失败。约束:需要区分连接在提交前断开、提交请求已到达但响应丢失、数据库故障恢复等窗口;业务表必须有唯一意图键和可查询状态,外部副作用不能与未知本地事务无审计地串联。机制链:请求进入时先以业务键创建或定位意图,同一事务写业务状态、版本和 Outbox(发件箱);提交异常后服务返回处理中和查询标识,后台按原键读主库或经过一致性保证的权威节点。若查到已提交,继续发布事件;明确不存在且故障恢复点已确定后才允许同键重试;长期无法判定进入人工队列。调用方重复请求读取既有意图,不创建第二条。失败边界:立即读从库可能因复制延迟误判未提交,数据库恢复可能重放日志后才出现记录;更换幂等键会产生双订单或双扣减;把所有未知都标成功则可能发货无库存。项目证据:库存预占以订单行动作号查询流水,支付单创建以商户请求号查本地与渠道,异步任务以任务号查产物。验证闭环:在事务提交、响应返回和事件发布各窗口强杀连接或进程,确认未知可查、已提交事件可补发、未提交可同键重试;对账无重复业务效果,并监控未知状态年龄与人工积压。数据库恢复后还要核对事务日志恢复点与查询水位,防止刚恢复的只读副本给出不存在结论;未知状态数量突增本身应触发告警,而不是等用户重复提交。
- 追问 1:为什么不能马上查从库?直接回答:复制延迟会把已提交误判为不存在,应查权威读路径或等待水位。
- 追问 2:两次同键参数不同怎么办?直接回答:比较请求摘要并拒绝冲突,不能静默复用旧结果。
- 追问 3:未知状态能一直保留吗?直接回答:不能,要有查证、对账和人工升级时限。
- 关联专题:本地事务与提交边界
- 问题(综合题):配置中心网络分区导致实例使用不同版本,怎样判断和处理“配置脑裂”?
口述答案:结论:配置版本不一致会让同一请求因路由到不同实例得到不同规则,属于控制面分裂造成的数据面风险;处理重点是识别实际生效版本、停止高风险混合写,并恢复单一批准版本,而不是只看配置中心页面。约束:每个实例必须暴露配置版本与加载结果,高风险配置要定义是否允许使用最后良好版本;库存、价格、租户权限等规则混用可能产生不可逆副作用,普通展示配置风险较低。机制链:告警发现版本分布异常后,先按版本给实例打标签并从高风险写流量摘除未知版本,冻结继续发布;核对批准记录、配置校验和实例实际值,选择最后良好版本,原子推送并等待回执;无法同步的实例保持隔离或重启加载。随后按版本和时间窗筛选订单、库存和通知,重算规则影响,补偿可判定差异。失败边界:控制面显示发布成功不代表客户端已应用,监听断开后实例可能长期旧;简单回滚不能撤销旧规则已写的数据和消息;若路由随机,单用户重试可能跨版本反复。项目证据:库存安全阈值不一致时先停止相关仓出库,按实例配置版本与订单 Trace(链路追踪)定位;IoT(物联网)告警规则保留版本以支持重算。验证闭环:演练配置中心分区、客户端断联和回滚,确认版本差异及时告警、危险实例自动摘流、最后良好版本可恢复;全量核对事故窗口业务差异并验证门禁阻止再次混合发布。配置恢复后需按实际内容摘要重新分组实例,并回放事故窗口内受规则影响的业务键;若某项副作用无法自动逆转,就生成带证据和审批的人工处置单。
- 追问 1:配置版本一致就一定值一致吗?直接回答:不一定,还要校验内容摘要和实际生效状态,防止加载失败或本地覆盖。
- 追问 2:可以一直用最后良好版本吗?直接回答:短时可用,但涉及安全吊销等配置时必须有更严格失效策略。
- 追问 3:如何减少用户跨版本?直接回答:事故止血可按版本稳定路由,但根本仍是恢复单一批准配置。
- 关联专题:配置控制面边界
- 问题(综合题):按租户灰度发布为什么仍可能污染非灰度租户,如何建立发布门禁?
口述答案:结论:租户灰度只隔离入口流量,若数据库模式、缓存键、消息消费者、批任务和全局配置共享,新版本产生的格式或副作用仍可能触达非灰度租户;发布门禁必须覆盖完整数据路径。约束:灰度标记由可信身份推导并签名透传,不能接受客户端自报;新旧版本必须在 API(应用程序接口)、数据库、事件和配置四个维度兼容,观察指标按租户和版本分组但控制高基数。机制链:发布前制作兼容矩阵,数据库先 Expand(扩展),事件新增可选字段,消费者容忍新旧格式;选择内部或低风险租户,路由、消息和后台任务均识别灰度范围,独立缓存命名避免污染;每档比较对照租户的错误、P99(99 分位响应时间)、状态分布、金额和库存守恒,达到阈值自动停止。失败边界:共享消费者可能把灰度事件写入全局投影,缓存遗漏租户导致新值外溢,批任务不带灰度上下文会全量执行;回滚流量后新格式数据仍留在库中,旧代码可能无法读取。项目证据:支付灰度按测试商户,账务事件带模式版本且旧消费者可忽略新字段;跨境物流缓存键包含租户和版本。验证闭环:用灰度与非灰度租户相同业务键并发执行,检查缓存、消息、数据库和导出隔离;失败时停灰度、处理已产生副作用、对照组无差异后才关闭事故。发布报告必须证明非灰度租户的业务分布没有漂移,并抽查共享消费者和批任务;若对照组也变化,应停止发布并先排查共享数据面,而不是扩大样本稀释差异。
- 追问 1:按用户灰度和按租户灰度一样吗?直接回答:不一样,租户内共享数据与协作更强,通常应保持同租户版本一致。
- 追问 2:灰度标记可以放普通请求头吗?直接回答:可传输但必须由可信入口签名,服务不能盲信客户端值。
- 追问 3:回滚后何时能再发布?直接回答:历史副作用闭环、兼容缺陷修复、回滚演练通过并重新从小流量开始。
- 关联专题:链路灰度与兼容
- 问题(综合题):下游数据库变慢引发全链路雪崩时,你如何在前十分钟做决策?
口述答案:结论:前十分钟优先阻断放大器、保护核心写和保留证据,不能盲目扩容调用方或重启全部实例;定位与止血并行。约束:先确认库存、支付、租户安全等高风险影响,区分数据库真实容量下降与应用排队放大;每个动作记录时间和指标,确保可逆,避免清空队列或丢弃未知请求。机制链:第一分钟确认告警、变更与用户影响,暂停高风险发布;立即关闭网关或中间层重复重试,按业务优先级限流,非关键查询降级,隔离耗时导出;传播更短但合理的截止预算,让过期工作取消。另一组查看数据库连接、锁等待、慢 SQL(结构化查询语言)、主机资源和流量热点,用 Trace(链路追踪)关联线程池排队。若数据库仍有余量,谨慎扩消费;若已饱和则降低并发。修复后小流量探测并按净处理能力消积压。失败边界:调用方扩容会增加连接,统一重启丢现场且触发连接风暴,超时缩得过短会制造更多重试;熔断恢复全开形成二次冲击。项目证据:库存慢查询事故中先保护条件扣减,暂停报表和批量查询,支付已提交未知单保留查证。验证闭环:技术上看 P99(99 分位响应时间)、连接等待、在途和重试倍数,业务上核对库存、订单和支付未知;积压回基线且观察窗口无复发才结束。前十分钟的每个止血动作都要登记负责人、开始时间、预期信号和回退条件,便于并行团队判断因果;故障稳定后再逐一撤销,避免保护措施本身长期限制容量。撤销保护动作也必须逐项验证。
- 追问 1:什么时候可以扩容?直接回答:确认瓶颈不在共享下游且其有余量,新增实例能获得真实并行时。
- 追问 2:是否立刻熔断数据库?直接回答:通常不能粗暴熔断所有数据库操作,应按核心写、查询和资源池分级保护。
- 追问 3:十分钟内要找根因吗?直接回答:要形成强假设和证据,但先控制损失,完整根因可在稳定后验证。
- 关联专题:治理事故止血、服务隔离
- 问题(综合题):支付渠道显示成功、本地订单仍待支付时,如何止血、查证和修复?
口述答案:结论:渠道成功是外部资金事实,本地不能回滚成失败或重新扣款;事故处理要先阻止重复支付与错误发货,以渠道流水、支付单、账务和订单四方查证,再幂等补齐缺失状态。约束:必须验证渠道回调签名、商户、币种和金额,区分回调丢失、消费积压、状态条件拒绝和账务失败;自动修复只处理证据唯一的记录,金额冲突转人工。机制链:先让待支付订单查询渠道时复用原商户请求号,并暂停用户使用新支付号重复付款;按事故时间窗导出渠道成功流水,关联本地支付单。若支付单未成功但渠道明确成功,使用渠道流水唯一条件推进并写 Outbox(发件箱);账务消费者唯一入账,订单消费者按版本改已支付。已有支付单成功但事件缺失则补发原事件,不伪造新流水;已重复扣款创建退款或冲正工单。失败边界:渠道查询也可能暂时未知,响应成功但金额不符不能自动入账;补事件重复投递会再次触发消费者,故各方必须幂等;订单已取消或库存已释放时不能直接发货。项目证据:支付模块监控未知状态年龄、渠道成功未入账、账务差异金额与人工积压,订单履约根据库存事实决定重新预占或退款。验证闭环:全量四方对账事故窗口,核对金额守恒、无重复账务、用户状态正确;灰度恢复回调与消费,观察差异新增为零并演练丢回调场景。对账完成还要通知受影响用户并核对重复付款、退款在途和库存状态,技术流水一致不代表用户体验已经恢复;观察期内任何新增差异都要重新打开事故。
- 追问 1:可以让用户再付一次后退第一笔吗?直接回答:不应作为默认,增加资金占用与退款风险,应先查原交易。
- 追问 2:渠道账单一定正确吗?直接回答:它是重要外部权威,但仍要验签、金额和结算记录,冲突需人工核对。
- 追问 3:补发消息用新事件号吗?直接回答:不用,应复用原业务事件标识,使消费者识别同一事实。
- 关联专题:支付资金事故闭环
- 问题(综合题):库存双主分叉并已产生出库作业时,怎样决定保留、补偿还是人工介入?
口述答案:结论:库存脑裂不能只合并两个库存数,因为预占、拣货和出库是已发生的业务事实;先恢复单一写权威,再按流水和仓内作业逐笔裁决,无法自动满足不变量的冲突必须人工处理。约束:冻结受影响商品与仓的新增写,保留查询和安全库存提示;确认分区窗口、两侧任期、Fencing Token(栅栏令牌)、订单与库存流水,不能删除少数侧记录掩盖问题。机制链:选择合法任期和最后共同提交点,隔离旧主,统计两侧新增预占;对未进入仓内作业且库存不足的非法预占发取消与退款,对已经拣货或出库的订单保留物理事实,调整可售量并触发补货、跨仓或人工客服;所有调整写新的修正流水,不直接改余额。重建旧节点后只从权威快照加入。失败边界:物理库存也可能与系统账不同,按订单时间先后不一定符合业务优先级,补偿释放可能与迟到确认竞态;自动取消高价值或已发货订单会扩大损失。项目证据:WMS(仓储管理系统)以初始量、入库、预占、扣减、释放和修正流水守恒,并关联拣货单与出库单。验证闭环:全量核对事故商品的逻辑量、物理盘点和订单状态,修正后库存不负、每条差异有处置;再次分区演练确认少数侧无法写、旧代次提交被拒。库存修正必须生成新的业务流水并关联原分叉记录,禁止直接更新余额;高价值或已发货订单的处置还需仓内、客服和财务共同确认,不能只按技术时间排序。修正后的可售量需再次压测校验。
- 追问 1:为什么不能直接把数量取最小?直接回答:会掩盖具体订单归属和已发生作业,无法审计与补偿。
- 追问 2:物理库存优先还是系统流水优先?直接回答:二者都要核对,物理事实决定可发量,流水解释责任与修正。
- 追问 3:恢复后何时开放销售?直接回答:单一权威、关键商品守恒和高风险差异闭环后分级开放。
- 关联专题:库存与脑裂事故
- 问题(综合题):Runner(执行器)租约过期后新旧执行者同时上传结果,怎样保证只有一个结果生效?
口述答案:结论:租约只能决定一段时间内谁被认为是所有者,不能停止暂停后恢复的旧执行者;必须用单调 Fencing Token(栅栏令牌)、幂等步骤和条件提交让存储拒绝旧所有者,任务消息允许重复。约束:任务表是权威状态,消息只唤醒;每次领取生成更高代次,续租只能作用于当前所有者与版本;对象存储等不支持原生围栏的外部系统要通过带版本元数据的提交服务间接保护。机制链:执行者甲领取代次 101,按任务号和步骤号写临时产物;甲长暂停失租,乙以 102 接管并从持久检查点继续。最终发布通过事务比较任务当前代次与状态,只有 102 可把产物指针改为完成;甲恢复上传的临时对象因代次低不能成为正式指针,随后由清理任务删除。外部副作用使用相同业务键查证。失败边界:续租线程与业务线程分离会产生“租约活着、任务卡死”,对象上传成功但提交响应丢失会重复,任务表更新和对象发布非原子会留下孤儿;只依赖分布式锁自动过期无法拒绝甲。项目证据:异步导出按分片保存检查点与摘要,最终文件指针由单一代次发布;物流推送复用任务步骤键。验证闭环:在上传前后暂停甲、让乙接管,再恢复甲,确认正式结果摘要唯一、旧代次拒绝可观测、孤儿可清理;监控失租率、接管次数、运行年龄和围栏拒绝。对象存储中的临时产物要有生命周期清理和摘要校验,防止旧执行者虽未发布却持续占用空间;任务关闭前核对正式指针、代次和结果摘要三者一致。
- 追问 1:消息只投递一次就不需要围栏吗?直接回答:仍需要,进程停顿、人工重放和调度接管都可能产生并发执行者。
- 追问 2:临时对象怎样命名?直接回答:包含任务、步骤、尝试和代次,正式指针单独条件提交。
- 追问 3:乙能否从头重跑?直接回答:可以但成本更高,副作用步骤必须幂等,最好从持久检查点续跑。
- 关联专题:Runner(执行器)租约与围栏
- 问题(综合题):IoT(物联网)报警风暴中通知链路已满,怎样决定丢弃、聚合、降级和恢复?
口述答案:结论:先保护原始安全事实和严重告警,再对普通抖动做窗口聚合、租户与设备限速,通知链路过载时牺牲时效与重复明细,不牺牲审计和高危事件;恢复不能把全部历史通知重新轰给用户。约束:定义严重等级、聚合键、时间窗、迟到事件和通知服务目标,原始事件存储也有容量上限;不同租户要有保底预算,异常设备不能占满全局通道,降级动作必须可追踪。机制链:接入层按稳定事件标识持久化最小原始事实,严重事件进入独立高优先级通道;普通事件按“租户 + 设备 + 规则 + 窗口”聚合次数、峰值和持续时间,通知使用告警实例与渠道幂等。背压上升时先暂停分析和普通即时通知,再按设备限速,生成摘要;恢复后先发当前仍有效的严重告警和状态摘要,历史明细留查询,不逐条重放骚扰用户。失败边界:在内存聚合后落盘会因重启丢事实,所有事件都聚合会掩盖短促高危告警,固定窗口边界可能双发,严重通道与普通通道共享线程池仍会互相拖累。项目证据:平时 3,000 EPS(每秒事件数)、峰值 45,000 EPS(每秒事件数) 时,通过压缩比、严重告警 P99(99 分位响应时间)和原始事件完整率验收。验证闭环:注入异常设备、通知限流、消费者重启和存储水位,检查严重告警达标、普通降级可重建、租户公平;恢复后对账告警实例、通知和状态。报警恢复报告还要区分未通知、已聚合、已过期和仍有效事件,避免用队列清零表示成功;严重告警需抽样回访通知到达,并核对原始事件可完整重建。
- 追问 1:原始事件也存不下怎么办?直接回答:预留高危容量,对普通遥测采样或压缩,并明确丢弃审计与上游限速。
- 追问 2:恢复后为何不全量补通知?直接回答:大量过期通知无价值且会二次冲击,应按当前状态和风险汇总。
- 追问 3:聚合会破坏顺序吗?直接回答:原始事实保留顺序信息,聚合是派生视图,规则需处理迟到和窗口水位。
- 关联专题:IoT(物联网)报警风暴治理
- 问题(综合题):请用一个完整决策链设计跨境物流履约平台,并说明何时不拆、如何保一致与处理事故。
口述答案:结论:我会先以模块化单体确认订单、库存、履约、支付、轨迹和通知边界,仅把具有独立峰值、发布或故障隔离收益的能力迁成服务;平台目标是订单与资金正确、轨迹可追溯、峰值可恢复,而不是服务数量。约束:库存不超卖、支付不重复入账、租户不串扰是硬边界;轨迹摘要允许延迟,通知可降级;团队必须具备发布、观测、对账和值班能力。机制链:各域拥有数据与本地事务,订单通过 Outbox(发件箱)发布事实,库存条件预占,支付用稳定请求号查渠道,履约以状态机和补偿推进,轨迹保原始事件并构建 Read Model(读模型);调用传播截止时间,异步链有幂等、背压和状态年龄;发布按 Expand/Contract(扩展/收缩)和租户灰度,多层校验租户身份。失败边界:分区时库存少数侧拒绝写,轨迹可继续接收后收敛;支付超时保持未知,消息重复由唯一键吸收;治理重试可能放大,配置和灰度会污染共享数据,Runner(执行器)失租写由 Fencing Token(栅栏令牌)拒绝。项目证据:用跨服务变更率决定拆分,用预占与账务流水证明守恒,用轨迹水位、任务年龄和报警压缩比证明恢复能力。验证闭环:上线前做分区、慢依赖、重复乱序、配置误推、租户越权和回滚演练;线上以用户旅程、业务差异、积压与恢复时间验收,收益不足的服务可回迁。最终评审要把每个服务的拆分收益与新增事务、观测、发布和安全成本放在同一张表,并设回迁条件;架构成熟的标志是决策可逆、证据可查,而不是组件齐全。
- 追问 1:第一批最值得拆什么?直接回答:通常是资源曲线独立且边界稳定的轨迹解析或异步任务,不先拆强事务核心。
- 追问 2:平台最关键的人工出口是什么?直接回答:支付资金差错、库存分叉和无法自动裁决的履约冲突队列。
- 追问 3:怎样证明设计不是纸上谈兵?直接回答:用基线、故障注入、对账守恒、灰度数据和事故恢复记录持续验证。
- 关联专题:演进决策、边界所有权、一致性、治理、事务、发布安全、项目事故
4. 七条追问树复习清单
- 是否拆服务:能否同时给出不拆、迁出、回迁三种条件,并用变更率、容量和故障半径作证。
- 边界所有权:能否指出每个数据的语义拥有者、唯一写入者、查询副本和旁路写审计。
- 一致性脑裂:能否区分分区、超时、复制延迟,说明合法任期、Quorum(法定人数)、栅栏和恢复对账。
- 事务选型:能否按资源前提选择本地事务、XA(扩展架构事务)、TCC(Try Confirm Cancel,尝试确认取消)、Saga(长事务补偿)或消息方案,并说出人工出口。
- 治理雪崩:能否计算预算与重试放大,说明隔离、限流、熔断、降级和阶梯恢复的组合顺序。
- 发布安全:能否说明 API(应用程序接口)、数据库、事件、配置的新旧共存,以及租户、安全与副作用回滚。
- 项目事故:能否在时间线内完成定界、止血、跨信号定位、历史差异修复和验证闭环。
5. 跨册索引
| 决策主题 | 权威分册 | 本册训练重点 |
|---|---|---|
| 演进、成本、拆分与回迁 | 01-单体到微服务演进拆分原则与成本模型 | 是否拆服务追问树 |
| DDD(领域驱动设计)、聚合与数据所有权 | 02-DDD限界上下文聚合事件风暴与数据所有权 | 边界所有权追问树 |
| CAP(一致性、可用性、分区容错)、Quorum(法定人数)、时钟与脑裂 | 03-CAP-BASE一致性复制Quorum时钟与脑裂 | 一致性脑裂追问树 |
| 服务发现、超时、重试、韧性与观测 | 04-服务治理注册发现负载均衡与韧性 | 治理雪崩追问树 |
| 分布式事务、补偿与消息一致性 | 05-分布式事务补偿与消息一致性 | 事务选型追问树 |
| 配置、灰度、兼容、多租户与安全 | 06-配置网关灰度兼容多租户与安全边界 | 发布安全追问树 |
| WMS(仓储管理系统)、支付、轨迹、Runner(执行器)与 IoT(物联网)事故 | 07-项目案例与事故排障 | 项目事故追问树 |
