投递语义与消费幂等

按类型定义投递语义

普通弹幕通常接受至少一次投递或少量丢失;礼物消息、付费消息和管理消息需要更可靠。系统可以按消息类型定义语义:

消息投递语义
普通弹幕低延迟优先,允许降采样和丢弃
礼物消息至少一次投递,消费端幂等
管理消息必须送达或重试,记录审计

这能避免为了普通弹幕追求强可靠,把整个系统做得又慢又复杂。

为什么是「至少一次」

消息队列通常是「至少一次」投递(可能重复)。要保证可靠性:

  • 失败重试:消费失败进入重试。
  • 重复投递:网络抖动、超时重试导致同一条消息投多次。

系统层面接受「至少一次」,用消费端幂等来兜底。

消费幂等

队列可能重复投递,消费端必须幂等。可以使用 message_id 做去重:

processed:message:{message_id}
  • 处理前检查是否已处理。
  • 处理完标记已处理。
  • 重复投递直接跳过。

礼物消息的幂等

礼物消息尤其要注意:

  • 展示动画可以重复容忍(多播一次无伤大雅)。
  • 余额扣减不能重复(重复扣款不可接受)。

关键设计:账务动作应由支付或账户系统完成,弹幕系统只消费结果事件。

幂等的边界

  • 幂等键:message_id / gift_event_id / order_id。
  • 幂等范围:展示、统计、账务各自处理。
  • 幂等存储:Redis / 数据库唯一键。

一句话

投递语义按类型定:普通弹幕可丢、礼物管理要可靠。可靠性靠「至少一次 + 消费幂等」实现,账务幂等交给支付 / 账户系统。

下一节看队列积压时怎么办。

发现内容有问题?

告诉我们哪里需要改进。