跳转到正文

工程实战 / ENGINEERING JOURNAL

跨境网络会中断:为事件总线设计重试、去重与补偿

不依赖“网络总是可靠”的假设,让两地业务在中断后仍能恢复一致。

ViSEO 工程编辑组4 分钟阅读
跨境网络会中断:为事件总线设计重试、去重与补偿

01 / 先保证事件不会丢失

业务记录与待发送事件放入同一个本地数据库事务。独立投递器读取 Outbox,成功投递后更新状态,避免业务保存成功而消息发送失败。

事件需要稳定的唯一标识、实体版本和发生时间。时间只用于观察顺序,核心业务顺序应使用实体版本或分区序号。

投递器可以重复发送,所以“标记已发送”不应被视为消费者已经成功处理。将传输确认与业务确认区分开来;对于需要端到端核对的交易,额外维护可关联到原始事件的处理结果。

02 / 接受重复,控制副作用

多数消息系统在异常场景下可能重复投递。消费者用事件 ID 建立去重记录,并在同一事务内更新业务状态,让同一事件重复到达也不会重复扣减库存。

去重记录的保留期至少覆盖实际重放窗口。先写去重标记再单独提交业务更新,会在崩溃后丢失真正的处理;应把去重检查和业务副作用纳入同一事务,或通过明确的状态机协调。

-- 示例:事件消费去重记录
CREATE TABLE consumed_events (
  event_id UUID PRIMARY KEY,
  processed_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

03 / 重试有边界,失败可恢复

使用指数退避并加入随机抖动,避免线路恢复时同时重试造成拥塞。无法自动处理的事件进入隔离队列,保留原始载荷与失败原因。

补偿操作应表达业务语义,例如释放预占库存,而不是机械执行数据库反向更新。重放工具应支持预览影响范围和单批限速。

隔离队列不是永久归档。为每一类失败指定负责人和处理时限,支持修复规则后重放原事件。重放前检查版本兼容,且不能绕过正常的授权、校验和审计链路。

04 / 监控积压而不仅是在线状态

关键指标包括最老消息年龄、投递失败率、隔离队列长度及两地实体版本差异。线路连通并不代表业务已经追平。

上线演练覆盖短暂抖动、持续断线和消费者重启,在恢复后核对业务账本。这些指标是建议验收口径,不是已测得的客户业绩。

演练时记录断线开始、网络恢复与业务追平的不同时间点。使用已知订单样本核对最终状态,检查重复通知和重复扣减;单独观察队列清空可能漏掉被错误丢弃的事件。

  • 业务事务与 Outbox 原子提交。
  • 消费者去重与业务更新保持一致。
  • 隔离事件有负责人、重放窗口和审计记录。
微服务出海架构

分享这篇文章

X

KEEP EXPLORING

继续阅读