跳到正文

Outbox、Inbox与消息一致性

55 分钟

Outbox、Inbox与消息一致性

从一次真实故障进入

先别急着背定义。把场景摆出来:模拟提交后进程崩溃、重复发布和重复消费。在单机里,函数返回和内存状态通常由一个执行上下文观察;到了“分布式事务与跨服务一致性”,节点有各自时钟、内存、磁盘和故障,消息可能延迟、重复、乱序或永远不到。你看到超时、旧值、双写、重复消费或领导切换,只是现象。第一步要画参与者、消息方向、稳定状态与采集点,不能用一句“系统自动同步”跳过真正机制。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

本节核心是:业务变更与outbox事件在同一本地事务提交,转发器至少一次投递,消费者inbox去重。请把它拆成至少四条 旧状态 --消息/超时/本地持久化--> 新状态,为每条边写执行节点、输入字段、稳定介质动作和回应。分布式系统的正确性来自所有允许执行都守住不变量,而不是某次演示恰好成功。(唯一锚点:分布式系统6-5《Outbox、Inbox与消息一致性》。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

先声明模型与不变量

在纸上写五栏:节点与角色、持久状态、易失状态、消息、故障假设。围绕Outbox、Inbox与消息一致性,说明节点会不会崩溃恢复、网络能否分区、磁盘是否可能截断、客户端会不会重试、是否考虑恶意节点。模型不同,能承诺的安全和活性也不同;不能把崩溃故障协议直接拿来处理任意伪造消息。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

然后写一个安全不变量和一个活性目标。安全回答“绝不能同时发生什么”,例如两个不同值不能都在同一日志位置提交;活性回答“在什么恢复条件下最终会完成”。关键边界是:Outbox解决数据库与消息发送间隙,不自动保证所有消费者业务正确。请把它变成具体反例执行,而不是一句注意事项。(模型锚点:Outbox、Inbox与消息一致性,第6章第5节。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

跟我沿消息时间线推一遍

执行实验:模拟提交后进程崩溃、重复发布和重复消费。固定节点数、初始任期/版本、消息队列与磁盘内容。每取出一个事件,只允许一个节点依据当前状态处理;记录发送、接收、超时、写稳定日志、响应和状态变化。遇到丢包就删除指定消息,遇到崩溃就清除易失状态但保留已声明的稳定状态,恢复后重新读取。这样才能准确区分“没有执行”“已执行响应丢失”和“已提交但尚未应用”。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

本节做一个仲裁量纲检查:有7个副本时,普通多数派是 4;任意两个大小为4的集合至少相交。若一次流程串行处理4个事件、每个事件服务2ms并追加稳定日志3ms,则简化预算为 4×(2+3)=20ms。这个数字只用于暴露假设;真实系统若并行、批量、跨区、排队或无需每事件刷盘,必须重画时间线后重算。(计算锚点:Outbox、Inbox与消息一致性。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

可运行实验如何证明机制

代码题全部从标准输入读取、输出稳定文本,不访问外网、不绑定固定端口、不依赖睡眠运气。共识和复制用确定性消息队列,事务把内存与稳定日志分开,分片固定哈希函数,流处理显式事件时间和水位线。每个参考实现至少运行正常、边界、失败和回归四组测试,发布前逐例真实执行。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

你要再补第五组:重复消息、过期任期、响应丢失、日志截断、无多数派、并发版本、分片迁移或迟到事件任选其一。优化后逐输出对比参考模型,并保存首个偏差。伪代码、随机sleep、人工点选和只写死预期结果都不算可运行分布式实验。(实验锚点:Outbox、Inbox与消息一致性。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

故障注入与恢复边界

现在在承诺前、稳定日志后、消息发出后、响应返回前或领导切换中任选一个点崩溃。预测每个节点恢复时能看到什么、谁有权继续、客户端能否安全重试。若出现两个可写领导、已确认数据丢失、重复副作用或状态机分叉,就沿时间线找首个不变量失败,而不是在最终状态补丁。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

尤其要区分安全与可用:失去多数派时停止写可能是正确的安全行为;强行让两个分区都写会在恢复时欠下不可自动解决的冲突。相反,永远停止虽然安全,却没有活性。答案必须写协议在什么网络恢复、节点数量和故障上限下能继续。(故障锚点:Outbox、Inbox与消息一致性。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

与上下游机制建立联系

向前追问本节依赖什么时间、任期、版本、请求ID或稳定存储;向后追问它怎样影响副本读取、分片迁移、事务结果、流状态、故障恢复和SLO。请画三条因果箭头,每条写消息字段或状态条件。例如客户端超时会触发重试,重试若没有稳定去重会重复执行,重复执行又会破坏跨服务业务不变量。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

如果同一现象有多种解释,建立假设表。旧读可能来自复制滞后、路由过期、会话跨副本或冲突合并;领导频繁变化可能来自时钟暂停、网络抖动、负载阻塞或错误超时。下一项观测应让至少两个假设产生不同预测。(连接锚点:Outbox、Inbox与消息一致性。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

在线练习与严格作答

本节下方至少绑定单选、多选和计算题,部分课时另有代码题。单选先圈故障模型和承诺,多选逐项构造反例,计算题写节点数、仲裁、单位和事件,代码题通过全部测试并补失败输入。章节卷、期中、期末、共识和故障专项使用独立题池,不能靠记随课答案过关。

错题按“模型未声明、因果倒置、稳定/易失混淆、超时误判、任期版本遗漏、仲裁错误、重复副作用、恢复假设缺失”分类。更换节点数、消息顺序和崩溃点重做;仍能守住同一不变量,才算迁移成功。(练习锚点:Outbox、Inbox与消息一致性。)

下课前闭卷自检

一,列出Outbox、Inbox与消息一致性的节点、稳定状态和易失状态。二,画至少四条带消息的状态迁移。三,复述核心机制并指出安全不变量。四,为实验新增一个故障测试。五,用具体执行解释“Outbox解决数据库与消息发送间隙,不自动保证所有消费者业务正确”。六,说明失去多数派时系统做什么。七,把本节连接到恢复或SLO。
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

如果答案仍是“最终会一致”“Raft会处理”“超时就是失败”,回到消息时间线补出谁在何时持久化什么、哪个仲裁允许决定、恢复后怎样拒绝旧权力。合格不是认出名词,而是能在消息重排和节点崩溃后继续证明。(自检锚点:Outbox、Inbox与消息一致性。)
(长段唯一锚点:DS-06-05-Outbox、Inbox与消息一致性。)

Practice

本课练习

4

先独立作答再提交;编程题会在隔离沙箱中真实编译、运行并对拍。

1单选:Outbox、Inbox与消息一致性 3

分析Outbox、Inbox与消息一致性的实验“模拟提交后进程崩溃、重复发布和重复消费”时,哪项动作能形成可复核的安全性证据?

登录 后答题可以领小红花
2多选:Outbox、Inbox与消息一致性 3

严格验收Outbox、Inbox与消息一致性时,哪些材料不可缺少?

多选题:必须选全正确项,漏选或多选均不得分。

登录 后答题可以领小红花
3计算:Outbox、Inbox与消息一致性 3

围绕Outbox、Inbox与消息一致性建立简化仲裁工作量:系统有7个副本,普通多数派大小为4;每个参与副本顺序验证6条事件。忽略并行、重试和批处理,共执行多少次事件验证?

登录 后答题可以领小红花
4U06独立题04:Outbox、Inbox与消息一致性 4

完成Outbox、Inbox与消息一致性分布式设计题:提交故障模型、消息/状态机或公式、实验、一个崩溃/分区反例和恢复说明。

【公开评分量表】模型初态2分;机制推演3分;实验故障3分;恢复边界2分。只列术语不得分。

登录 后答题可以领小红花