RabbitMQ基础

目录

一、RabbitMQ 基础认知

1、RabbitMQ 是什么?

RabbitMQ 是一款基于 Erlang 语言开发、开源、轻量级、高可靠的业务型消息中间件。主打消息可靠性高、延迟极低、支持事务、支持死信、可视化管理、集群高可用

2、使用场景 🔴

  1. 服务解耦:微服务之间异步通信,减少接口强依赖。

  2. 流量削峰:瞬时高并发流量存入队列,消费者匀速消费。

  3. 异步处理:非核心业务异步化,提高接口响应速度。

  4. 延时任务:订单超时、自动取消、超时提醒。

  5. 事件分发:广播消息、多服务同步数据。

3、核心五大基础组件

  1. 生产者 Producer:发送消息的应用程序,负责生成消息、推送至交换机。

  2. 交换机 Exchange:路由组件,不存储消息、只做转发

  3. 绑定 Binding:交换机与队列之间的关联关系,绑定路由规则。

  4. 队列 Queue:唯一持久化存储消息的容器,等待消费者消费。

  5. 消费者 Consumer:监听队列,获取并执行业务逻辑。

4、消息完整流转流程 🔴

  1. 生产者与MQ建立TCP连接,创建信道Channel;

  2. 生产者携带 routingKey 发送消息到指定交换机;

  3. 交换机根据自身类型 + routingKey 匹配绑定关系;

  4. 消息路由分发至对应队列;

  5. 消息持久化落盘,等待消费者拉取;

  6. 消费者监听队列,获取消息执行业务;

  7. 消费成功手动ACK,MQ删除消息。

二、交换机详解 🟠

1、四大交换机类型

(1)Direct 直连交换机(精准匹配)

  • 规则:routingKey 与 bindingKey 完全一致才转发。

  • 特点:一对一、单播、精准投递。

  • 场景:单服务点对点通知、订单状态通知。

(2)Topic 主题交换机(模糊匹配)

  • 规则:支持通配符模糊匹配。

  • *****:匹配单个单词。

  • #:匹配零个或多个单词。

  • 场景:多服务订阅、日志分类、业务事件分发。

(3)Fanout 广播交换机(无视key)

  • 规则:忽略 routingKey,全部绑定队列全部接收

  • 特点:发布订阅、广播群发。

  • 场景:系统公告、缓存刷新、多服务同步。

(4)Headers 请求头交换机(极少用)

  • 根据消息header属性匹配。

  • 性能差、配置繁琐,生产几乎不用。

2、特殊交换机 🟠

(1)死信交换机 DLX

专门接收过期、拒绝、溢出消息的交换机,搭配死信队列使用。

(2)延迟交换机(插件安装)

原生RabbitMQ不支持精准延时,需安装 delay-exchange 插件,基于时间戳精准延时投递。

三、RabbitMQ 可靠机制 🔴

1、消息丢失三大阶段

  1. 生产者发送阶段:网络抖动、MQ未接收成功。

  2. 交换机路由阶段:没有匹配队列,消息丢弃。

  3. 消费者消费阶段:业务异常,消息被误删。

2、生产端可靠性(防止发送丢失)

2.1 Confirm 发送确认模式(主流)

  • 原理:生产者发送消息后,MQ返回ACK确认;

  • ack=true:消息持久化成功;

  • ack=false:发送失败,本地重试补偿。

  • 优点:异步确认、性能高、生产必开。

2.2 Return 退回机制(路由失败)

  • 作用:消息无法匹配队列时,不丢弃、退回生产者

  • 场景:路由key错误、无绑定队列。

2.3 事务机制(不推荐)

  • txCommit、txRollback,同步阻塞。

  • 吞吐量极低,互联网行业禁止使用。

3、服务端可靠性(防止宕机丢失)

3.1 队列持久化

durable=true:队列元数据持久化,重启队列不消失。

3.2 消息持久化

deliveryMode=2:消息写入磁盘,断电不丢失。

注意:只持久化消息、不持久化交换机。

4、消费端可靠性(防止消费丢失)

4.1 自动ACK(不推荐)

MQ推送消息成功直接删除,业务报错也丢失消息。

4.2 手动ACK(生产强制)

  • basicAck:消费成功,MQ删除消息。

  • basicNack:消费失败,重回队列或丢弃。

  • basicReject:拒绝单条消息,不可批量。

四、死信队列 DLX 🟠

1、消息进入死信三种条件

  1. 消息过期:设置TTL,超时未消费。

  2. 消费拒绝:nack并且requeue=false。

  3. 队列溢出:队列达到最大长度,尾部消息丢弃进入死信。

2、死信架构搭建流程

  1. 创建普通业务队列,绑定死信交换机;

  2. 普通队列设置TTL、最大长度;

  3. 异常消息自动转入死信交换机;

  4. 死信交换机路由至死信队列;

  5. 消费者监听死信队列,人工补偿排查。

3、延时队列实现方案 🟠

方案一:死信实现延时(简单、低精度)

  • 缺点:队列头部消息未过期,后面消息阻塞,时间不准。

  • 适用:低精度、短延时任务。

方案二:Delay插件延时(生产推荐)

  • 基于时间戳排序,精准延时。

  • 不会阻塞、精度高。

  • 适用:订单超时、精准定时任务。

五、重复消费 & 幂等性 🔴

1、为什么会重复消费?

  1. 消费者业务执行成功,ACK网络超时未送达MQ;

  2. 服务宕机、重试机制触发;

  3. 集群切换、消息重分发。

2、四大幂等解决方案 🔴

(1)数据库唯一索引(最简单、最稳)

消息唯一ID作为唯一索引,重复插入直接报错,不会重复业务。

(2)Redis 判断幂等(高性能)

消费前判断key是否存在,存在则直接跳过;消费成功写入Redis。

(3)业务状态机判断

数据库增加状态字段,已处理状态直接跳过。

(4)全局唯一流水号

上游生成唯一编号,下游不可重复消费。

六、消息堆积问题 🔴

1、堆积产生原因

  1. 消费者消费速度慢,生产者发送过快;

  2. 消费者代码报错、无限重试卡死队列;

  3. 消费者服务宕机断开;

  4. prefetch一次性拉取过多消息。

2、堆积解决方案(生产实操)

  1. 扩容消费者:增加消费者实例,水平扩容提高并发。

  2. 异常消息隔离:异常消息转入死信,防止卡死队列。

  3. 批量消费:单次消费多条,减少IO次数。

  4. 限流prefetch:限制单次拉取消息数量,防止OOM。

  5. 临时拆分队列:超大堆积临时拆分队列分流。

七、集群模式详解 🔴

1、普通集群(静态集群)

  • 特点:队列只存在一台节点,其他节点仅同步元数据。

  • 缺点:主节点宕机,队列不可访问,数据丢失。

  • 适用:测试环境。

2、镜像集群(旧生产)

  • 特点:队列数据同步复制到所有节点。

  • 优点:任意节点宕机不丢失数据。

  • 缺点:同步开销大、吞吐量低、性能差。

3、仲裁队列(新版生产推荐)

  • RabbitMQ3.8+全新模式。

  • 原理:过半节点保存数据,类似zk选举机制。

  • 优点:性能优于镜像、高可用、低开销。

  • 生产强制推荐:3主架构仲裁队列

八、进阶 🔴

1、Channel 为什么轻于 Connection?

  • Connection:TCP物理连接,开销极大、数量有限。

  • Channel:虚拟信道,共享一条TCP连接。

  • 生产规范:一个服务少量Connection,大量Channel。

2、消息为什么不建议发大消息?

  • 大消息占用网卡带宽,阻塞其他消息投递;

  • 持久化慢、内存占用高;

  • 序列化慢、消费卡顿。

3、如何避免无限重试死循环?

  1. 设置重试次数上限;

  2. 失败达到阈值转入死信;

  3. 异常捕获,不要抛出原生异常。

4、RabbitMQ 内存溢出怎么解决?

  • 设置内存水位,超过水位禁止生产者写入;

  • 磁盘水位告警,防止磁盘爆满;

  • 限制prefetch数量,防止消费者堆积内存。

九、三大消息中间件硬核对比 🔴

中间件 开发语言 吞吐量 可靠性 时效性 适用场景
RabbitMQ Erlang 中等 极高 毫秒级 订单、支付、金融、业务异步
RocketMQ Java 较高 极高 毫秒级 电商、事务消息、阿里生态
Kafka Scala 极高 微秒级 大数据、日志、流处理、高吞吐

十、生产强制规范 🔴

  1. 必须开启 Confirm + Return 保证发送可靠;

  2. 队列、消息全部开启持久化;

  3. 消费端必须手动ACK,禁止自动ACK;

  4. 异常消息禁止无限重试,兜底转入死信队列;

  5. 业务必须做幂等,防止重复消费造成数据错乱;

  6. 限制prefetch数量,避免一次性拉取过多消息;

  7. 禁止发送超大消息,复杂数据压缩后传输;

  8. 线上采用仲裁队列,保证高可用、低损耗。

十一、 总结 🔴

RabbitMQ是Erlang开发、高可靠业务型消息中间件,核心包含生产者、交换机、队列、消费者;

交换机分为直连、主题、广播三类常用类型;

为保证消息零丢失,生产端开启Confirm确认和Return退回机制,服务端队列与消息双重持久化,消费端采用手动ACK;

通过死信队列处理异常消息、实现延时任务;

为防止网络抖动造成重复消费,业务层实现幂等;

集群推荐仲裁队列保障高可用;

相比Kafka,吞吐量适中、可靠性更强,适合订单、支付等核心业务异步解耦,是中小型微服务项目首选MQ。