知识卡片
最终一致性的关键是不丢不重
内容
用消息中间件实现最终一致性最易踩的坑是把”发消息”和”扣本地库”当成原子操作——[[网络2将军问题的不可解性]]决定这必出问题。正确做法:发送方把扣款和写消息表放进同一本地事务,后台任务重试推送直到成功(不丢);接收方用判重表处理前先判重(不重)。发散:与其让单次操作绝对可靠,不如设计成允许失败后安全重试加接收端天然幂等。
参考来源
- 位置:第10章《事务一致性》10.2.2节「最终一致性(消息中间件)」(源文件:_epub-src/text/part0047.html)
- 结论依据:原文明确说明系统A增加消息表,把扣钱和写消息表放进同一数据库事务,后台程序不断重试推送消息表内容直到成功(消息不丢但可能重复);系统B用判重表记录已处理消息ID/offset实现幂等(消息不重复消费),直接支持卡片对不丢不重两条独立保证的论述。
- 原始内容:"系统A增加一张消息表……把DB1的扣钱操作(表1)和写入消息表(表2)这两个操作放在一个数据库事务里……系统A允许消息重复,但消息不会丢失……为了解决重复消息的问题,系统B增加一个判重表……每次接收到新消息,先通过判重表进行判重,实现业务的幂等。"