消息队列不是“可选项”,而是支付系统的标准部件。它解决三个核心问题:

  • 解耦
  • 异步
  • 削峰

为什么用 MQ

典型场景:

  • 支付成功后通知、发券、入账
  • 异常重试与补偿
  • 限流与削峰

常见 MQ 选择

  • RabbitMQ:吞吐中等,功能丰富
  • Redis:适合轻量队列,易出现热点
  • Kafka:高吞吐,但调度能力弱

MQ 的代价

  • 可用性下降,外部依赖多
  • 复杂度上升,幂等与重复消费必须处理
  • 一致性问题,需要额外补偿

高可用设计

RabbitMQ

  • 镜像集群保证队列高可用
  • 代价是同步成本与写放大

Kafka

  • 多 broker + partition
  • 通过副本与 leader 机制保证可靠

重复消费如何处理

幂等是唯一答案:

  • Redis set 记录业务 key
  • MySQL 唯一键防重

消息丢失如何避免

生产者丢:

  • RabbitMQ 使用 confirm 或事务
  • Kafka 设置 acks=all

MQ 丢:

  • RabbitMQ 开启持久化

消费者丢:

  • RabbitMQ 关闭自动 ack,处理后手动 ack
  • Kafka 关闭自动提交 offset,处理后手动提交

顺序性

  • RabbitMQ 单队列内有序
  • Kafka 单分区内有序

如果必须保证业务级顺序,可按业务 key 路由到固定队列或分区。

小结

MQ 的价值很大,但代价同样大。引入 MQ 时必须同时设计:

  • 幂等
  • 失败重试
  • 告警与补偿