RabbitMQ详解

RabbitMQ是什么

RabbitMQ 是基于 高级消息队列协议(AMQP)、Erlang 开发的开源消息中间件,优势在于消息路由灵活、投递可靠性高,适合业务告警、事件通知这类对消息可靠度要求高的场景。

核心组件

  1. Producer(生产者):发送消息,消息先发给交换机 Exchange,不直接发给队列

  2. Exchange(交换机):路由核心,本身不存消息;根据 routingKey 和绑定关系,把消息路由到队列

  3. Binding(绑定):交换机和队列之间的绑定规则,包含 bindingKey

  4. Queue(队列):存储消息,FIFO 先进先出,等待消费者消费

  5. Consumer(消费者):监听队列,处理消息

  6. Vhost(虚拟主机):资源逻辑隔离,多项目共用一套 RabbitMQ 时做权限隔离,类似命名空间

  7. Channel(信道):TCP 连接上的轻量逻辑通道,一条 TCP 连接可复用多个 Channel,减少 TCP 连接开销

4 种交换机类型

  1. Direct 直连交换机: 精确匹配 Routing Key 。routingKey 和 bindingKey 完全匹配;点对点通知,如指定设备告警推送

  2. Fanout 扇出交换机:忽略 routingKey,消息广播到所有绑定队列;适合平台全局通知

  3. Topic 主题交换机: 根据 routing key 模式匹配 进行路由,*匹配 1 个单词,#匹配 0 或多个单词,项目最常用,例如 iot.alarm.* 匹配 IoT 告警消息

  4. Headers 头交换机:依靠消息 header 匹配,业务很少使用

四大经典问题

1. 消息丢失(三层保障)

  • 生产者:开启 Publisher Confirm 确认机制 + Return 回退机制。Broker 收到消息返回 ACK;路由失败则退回生产者。

  • Broker:交换机持久化、队列持久化、消息持久化;集群采用仲裁队列(新版推荐)/ 镜像队列保证高可用。

  • 消费者:手动 ACK,业务处理完成后再发送 ACK;自动 ACK 容易出现业务失败,消息却被删除,造成丢失。

2. 重复消费

场景:业务处理完毕、ACK 还没发送,服务宕机,重启后消息重新投递。 解决方案:业务幂等,用唯一业务标识(设备 ID + 消息时间戳),重复消息直接跳过,不重复执行业务。

3. 死信队列 DLQ

消息成为死信的 3 个条件: ① 消息被 reject/nack,并且不重新入队 ② 消息 TTL 超时 ③ 队列达到最大长度

用途:存放处理失败的异常消息;TTL + 死信交换机实现延迟队列(设备离线超时告警、订单超时关闭)

什么是死信队列

假设一条消息一直失败:

Message

↓

失败

↓

Retry

↓

失败

↓

Retry

↓

失败

如果无限重试:会造成消息积压。所以可以:

正常 Queue

↓

消费失败

↓

重试 N 次

↓

Dead Letter Queue

即:死信队列。之后由人工或者专门程序处理。

4. 消息堆积

生产速率大于消费速率。 优化手段:

  1. 优化消费业务逻辑,提升消费速度

  2. 增加消费者;设置 prefetch 预取值,控制单次推送给消费者的消息数量,避免一次性大量消息压垮消费者

  3. 海量堆积场景开启惰性队列 Lazy Queue,消息直接落盘,降低内存占用

消息确认机制(可靠性)

1 生产者确认(Publisher Confirm)

  • 默认情况下,生产者发送消息到交换机后,Broker 不会通知是否成功。

  • 开启发布确认模式后,Broker 会异步发送确认(Confirm)或未确认(Nack)信号。

  • 生产者可据此重试发送未确认消息,避免消息丢失。

2 消费者确认(Consumer Ack)

  • 默认自动确认(autoAck),消息从队列投递给消费者后立即删除。

  • 改为手动确认(manual ack)后,消费者处理成功后发送 basicAck,处理失败可发送 basicNack 或 basicReject 将消息重新入队或丢弃。

  • 结合 预取数量(Prefetch) 可控制每个消费者未确认消息的数量,实现公平分发。

3 持久化

  • 队列持久化:声明队列时设置 durable=true,队列元数据存盘,Broker 重启队列不丢失。

  • 消息持久化:发送消息时设置 delivery_mode=2,消息写入磁盘。

  • 交换机持久化:声明交换机时设置 durable=true。

  • 三者同时设置才能保证消息在 Broker 重启后不丢失,但仍有极小概率因刷盘时机问题丢失。

RabbitMQ 如何控制消费者速度?

RabbitMQ 可以通过:Prefetch Count

控制消费者一次预取多少消息。

prefetch = 10

prefetch 预取是什么?

prefetch 用来限制 MQ 一次性推送给消费者的消息条数,防止单个消费者一次性接收大量消息,引发堆积、内存溢出

RabbitMQ vs Kafka

  • RabbitMQ:AMQP 协议,路由能力强、可靠性高;吞吐量中等;适合业务告警、事件通知、延迟消息;消息堆积能力偏弱

  • Kafka:日志流模型,超高吞吐;适合海量设备上报、日志采集;路由能力弱,原生不擅长延迟消息

|--------|-----------------|----------------|
| 对比 | Kafka | RabbitMQ |
| 核心定位 | 高吞吐事件流 | 消息队列 |
| 吞吐量 | 很高 | 较高 |
| 消息模型 | Topic/Partition | Exchange/Queue |
| 消费模型 | Consumer Group | Consumer |
| 消息存储 | 日志 | Queue |
| 消费后消息 | 不立即删除 | 通常 ACK 后移除 |
| 顺序 | Partition 内有序 | Queue 内可保证一定顺序 |
| 扩展 | Partition 水平扩展 | Queue/集群扩展 |
| 历史消息 | 很强 | 相对弱 |
| 流式处理 | 非常适合 | 一般 |
| IoT数据流 | 很适合 | 可以 |

相关推荐
爱吃火鸡面呀44 分钟前
Spark RDD 创建与转换算子详解
大数据·分布式·spark
叶总没有会17 小时前
RabbitMQ高级
分布式·rabbitmq
ABB自动化20 小时前
ABB 500CIM06 (1MRB150077R0111) | REB500 通信接口
大数据·分布式·系统架构·系统安全·模块测试·plc 控制器
ZENERGY-众壹20 小时前
告别本地工控机:分布式光伏 SCADA 架构如何实现云边协同
分布式·架构·光伏运维·能源数字化·电站监控
code_slave(码畜)20 小时前
微服务架构落地:读写分离架构 —— 主从延迟引发的“刚开单查不到”灾难与破局
spring boot·分布式·spring cloud·微服务·云原生·架构·读写分离
JAVA_AI人工智能项目实战1 天前
分布式大模型训练_学习笔记
人工智能·分布式·语言模型·自然语言处理
星夜孤帆1 天前
Redis缓存击穿与分布式锁实战:专栏目录、源码与实验说明
redis·分布式·缓存
yyk333241 天前
Spark介绍
大数据·分布式·spark
成为你的宁宁1 天前
【基于 SSH 与 JNLP 协议的 Jenkins 分布式构建方案】
分布式·jenkins