消息队列不是“可选项”,而是支付系统的标准部件。它解决三个核心问题:
- 解耦
- 异步
- 削峰
为什么用 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 时必须同时设计:
- 幂等
- 失败重试
- 告警与补偿