← [ BACK_TO_NOTES ]

消息投递语义

对比 at-most-once、at-least-once 与 exactly-once 语义,解释消息确认、重试和故障恢复为什么会把“是否丢消息”与“是否重复处理”变成工程取舍。

#synthesis #growing #backend #architecture

[!info] related notes

消息投递语义

[!abstract] 核心问题 投递语义描述在发送、处理、确认和故障恢复之间,消息可能被处理零次、一次或多次。它不是 Broker 的单个开关;最终业务效果还取决于 Consumer、数据库和外部 API 的事务与幂等边界。

At-most-once

ACK / advance progress first
→ process later

失败时消息可能丢,但不会因为 Broker 重投而重复处理。

适合:

  • 可丢 Telemetry;
  • 高频状态采样;
  • 重复比丢失代价更高、且可以接受缺口的场景。

At-least-once

process first
→ ACK / commit progress after success

如果业务处理成功后、ACK 或 Offset Commit 前崩溃,消息会再次交付。

优点:尽量不丢业务处理;代价:Consumer 必须接受重复。

这是生产消息系统中非常常见的组合:

At-least-once Delivery
+ Idempotent Consumer

Exactly-once 为什么容易被误解

必须先定义边界:

Producer → Broker?
Broker internal processing?
Consumer Offset + Kafka output?
Consumer → PostgreSQL?
Consumer → payment API?

一个系统可以保证 Broker 内部事务性,却无法自动让外部数据库和第三方 API 与它原子提交。

更实用的目标通常是:

消息可能重复交付,但业务副作用通过唯一约束、幂等键、状态机或事务绑定,只产生一次有效结果。

ACK / Offset 的两个故障窗口

先确认,再处理

ACK / commit
→ crash before business effect
→ message not redelivered

风险:业务效果丢失。

先处理,再确认

business effect succeeds
→ crash before ACK / commit
→ message redelivered

风险:重复执行。

网络不可靠时无法同时凭空消除两个窗口,必须通过事务、幂等或 Reconciliation 缩小影响。

Producer 也有未知结果

Producer sends
→ Broker persists
→ response lost
→ Producer cannot know whether publish succeeded

安全重试需要稳定 Message ID、Idempotent Producer 或 Broker/业务层去重;否则可能产生重复消息。

顺序与投递语义是不同维度

即使 At-least-once 工作正常,也可能出现:

  • Retry 导致旧消息晚到;
  • 多 Consumer 并发完成顺序不同;
  • 跨 Partition 没有全局顺序;
  • DLQ Replay 把历史事件重新带回。

需要 Entity Version、Sequence、State Machine 或 Conflict Policy 处理顺序,而不是只做去重。

Broker 与业务数据库的边界

consume record
→ write business DB
→ commit progress

想减少“双写”窗口,可采用:

  • 同一数据库中的 Processed Message + Business Update 事务;
  • Kafka 内部 Transaction(只覆盖其支持边界);
  • Transactional Outbox / CDC;
  • Idempotency Key + Reconciliation;
  • Saga / Compensation。

设计检查表

  • 明确允许丢失、重复和乱序中的哪些风险。
  • Producer、Broker、Consumer、DB 的确认点分别在哪里。
  • Message ID 与业务 Idempotency Key 稳定。
  • Consumer 成功的定义是业务提交,而不是函数未抛错。
  • Retry / DLQ 不破坏顺序和版本规则。
  • 指标能观察 Redelivery、Duplicate、Lag、DLQ 和最终业务结果。
  • 文档中的 “exactly-once” 明确写出系统边界。
创建于 2026/9/4 更新于 2026/9/4
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本