RabbitMQ的核心作用是在分布式系统中实现 消息的异步传递、解耦服务、削峰填谷和保证消息可靠性,广泛应用于微服务架构、大数据处理、异步任务调度等场景。
RabbitMQ消息可靠性
RabbitMQ消息可靠性可以通过三个方面来保证:
-
创建交换机,队列,消息进行持久化
-
生产者方方面:
-
开启消息发送失败的重试策略
设置重试次数和重试间隔比例,如果耗尽重试次数后,依旧失败,记录失败的消息到数据库消息列表,用于后期补偿错误,或后期人工处理
-
开启confirm机制
保证消息正确到达交换机,返回ack;若返回nack,则是没有到达交换机,写入数据库,后期再补偿
-
开启return机制
保证消息正确到达队列,没有到达队列,会调用ReturnCallback,写入数据库,后期再补偿
- 消费者方面
-
开启手动ack,让消费者消费成功后,手动提交
使用Redis来记录消费失败的次数,如果达到阈值,则记录到数据库,后期再补偿
-
自动ack + 重试耗尽失败策略,定义错误交换机队列,在耗尽重试次数后,依旧失败,记录失败的消息到数据库消息列表,用于后期补偿错误,或后期人工处理
消息重复消费问题
根本原因:网络不稳定导致「ACK 丢失 / 延迟」,Broker 误认为消息未被消费,从而重发。
解决核心思路:保证消费者业务逻辑的幂等性(即 “重复执行多次,结果与执行一次一致”)。常见方案:
- 「数据库唯一约束」:如订单场景,用 “订单号” 作为数据库唯一键,重复消息插入时因唯一约束冲突,直接忽略。
- 「全局唯一 ID + 状态标记」:为每个消息生成唯一 ID,消费者处理前,先查 Redis / 数据库是否已处理该 ID;若已处理,直接跳过。
- 「版本号 / 乐观锁」:更新数据时,带版本号字段(如
version),重复处理时版本不匹配,操作自动失败。
消息消费如何保证顺序消息
乱序原因:多消费者并行消费同一队列,或消息被分发到不同分区(如 Kafka)。保证顺序的关键是「让需要顺序的消息,按顺序被同一消费者处理」。
-
「单队列单消费者」:若业务吞吐量允许,一个队列只由一个消费者处理,天然保证顺序(但性能低,适合低并发场景)。
-
「拆分队列 + 单线程消费」:
- 按 “业务标识”(如订单 ID)拆分队列:将同一份逻辑需要顺序的消息,路由到同一个队列(或 Kafka 的同一个分区)。
- 每个队列 / 分区由一个消费者线程处理,避免多线程并行导致乱序。
消息积压问题
原因:生产者发送速度远大于消费者处理速度,导致 Broker 中消息堆积。解决分 “应急处理” 和 “预防”:
-
应急扩容:
- 「增加消费者实例」:临时扩容消费者数量(前提是队列支持多消费者并行消费),提升消费能力。
- 「优化消费逻辑」:简化消费者业务(如同步操作改异步、缓存热点数据减少 DB 查询),降低单条消息处理耗时。
-
消息分流转储:
将积压的消息临时转储到 Redis / 数据库 / 新队列,再用多个消费者集群并行消费转储的消息,处理完成后回归正常流程。 -
预防措施:
监控队列长度并预警;合理设置队列大小和过期策略;根据业务峰值提前规划消费者容量。
死信交换机(Dead-Letter Exchange,DLX)
「死信」是指满足以下条件的消息:
-
消息被消费者拒绝(reject/nack)且 requeue=false;
-
消息TTL(生存时间)过期;
-
队列达到最大长度,头部消息被丢弃。
死信处理流程:
为队列配置x-dead-letter-exchange(死信交换机)和x-dead-letter-routing-key(死信路由键)。死信消息会被路由到指定的死信交换机,再由该交换机转发到绑定的 “死信队列”,供专门的消费者处理(如人工补偿、日志分析)。
典型场景:电商订单 “超时未支付”(订单消息 TTL 过期后成为死信,触发 “释放库存” 操作)。