RabbitMQ-基础
1. 简介
MQ(Message Queue)消息队列,是基础数据结构中“FIFO(先进先出)”的一种数据结构。
一般用来解决应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性架构。
应用解耦
MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
异步消息
将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。提高了应用程序的响应时间。
流量削峰
如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候数据库肯定卡死了。
这时候我们可以使用MQ将消息保存起来,然后系统就可以按照自己的消费能力来消费,比如每秒1000个数据,这样慢慢写入数据库,这样就不会卡死数据库了。
但是使用了MQ之后,限制消费消息的速度为1000,但是这样一来,高峰期产生的数据势必会被积压在MQ中,高峰就被“削”掉了。但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000QPS,直到消费完积压的消息,这就叫做“填谷”。
2. RabbitMQ
RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的消息队列。
RabbitMQ 其实是一个消息代理:它接受和转发消息。可以将其视为邮局:当你把 要投递的邮件放入邮箱时,你可以确定邮递员最终会将邮件递送给你的收件人。在这个比喻中,RabbitMQ 是一个邮箱、一个邮局和一个信件载体。 RabbitMQ 和邮局之间的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据块 - 消息。
3. 模式
这里仅介绍了常用的模式,最近看官网又多个模式Publisher Confirms,完了有时间再补充上。
关于官网中提到的第六种模式RPC,由于RPC通信一般不使用RabbitMQ,所以这里也没有讲。
3.1 简单模式
如图所示:只有一个生产者(P)一个队列(红色块)和 一个消费者(C)。
应用场景:可以实现对应用程序的解耦,并且可以实现对业务的异步处理。事实上这是mq最基本的功能。
3.2 工作模式
如图所示:一个生产者对应多个消费者。多个消费者功能消费一个队列(负载均衡)。
每个消息只能被其中的一个消费者消费。
应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。
3.3 发布订阅模式
如图所示:在生产者和队列之间多了个交换机(X),此时的交换机类型为:扇形交换机(Fanout Exchange)
。
事实上,简单模式和工作模式也都有自己的Exchange,只不过不用显性的声明,因为默认使用default Exchange
。
即:一个发送到Exchange的消息都会被转发到与该交换机绑定的所有队列上。
每一个消息能被多个消费者都消费。
Fanout Exchange
消息路由规则如图所示:
应用场景:顾名思义,一个消息想被多个订阅者消费。
3.4 路由模式
如图所示:相比发布订阅模式,Exchange和Queue之间多了个路由关系,此时的交换机类型为:直连交换机(Direct Exchange)
。
-
队列和交换机不是任意绑定了,而是要指定一个
Routingkey
。 -
生产者在向Exchange发送消息时,也必须指定消息的
RoutingKey
。 -
Exchange不再把消息交给每一个绑定的队列,而是根据消息的
Routing Key
进行判断,只有队列的Routingkey
与消息的Routing key
完全一致,才会接收到消息。
3.5 通配符模式/主题模式
如图所示:相比路由模式,Exchange和Queue之间不只是通过固定的RoutingKey
进行绑定,还支持通配符的方式,此时的交换机类型为:主题交换机/通配符交换机(Topic Exchange)
。
Topic Exchange
消息路由规则如图所示:
3. 安装RabbitMQ
4. 各种模式的简单实现
4.1 项目搭建
4.1.1 引入依赖
我们这里使用spring-boot-starter-amqp
操作RabbitMQ。
4.1.2 application.yaml
4.2 简单模式
4.2.1 声明一个简单队列
4.2.2 创建生产者
4.2.3 创建消费者
4.2.4 创建测试类
4.2.5 启动测试
启动测试类,输出内容如下:
每秒消费一条消息。
4.2.6 小节
简单模式,顾名思义,很简单,相当于Hello World程序。我们在编写的时候
- 指定了一个
Queue
并且名称为helloMQ
。 - 消息生产者通过SpringBoot 提供的
RabbitTemplate
发送消息,我们在发送时指定了Queue
为helloMQ
且发送了指定内容。 - 消息消费者通过
@RabbitListener
注解监听了指定Queue
为helloMQ
,且使用@RabbitHandler
注解指定消费方法SimpleConsumer::process()
。 - 最后编写测试类循环调用生产者消息发送逻辑,实现了消息的生产与消费。
4.3 工作模式
首先分析:其实工作模式和简单模式相比,仅仅是由一个消费者变成了多个消费者。ok,很好办,我们通过代码再多加一个消费者即可。
4.3.1 添加消费者
4.3.2 启动测试
我们再次执行test方法,查看消息消费情况。
输出日志如下:
SimpleConsumer
和 SimpleConsumer2
交替消费队列中的消息(消费者之间消费消息是通过轮询的关系)。
4.3.3 小节
在一个队列中如果有多个消费者,那么消费者之间是轮询的关系。
4.4 发布订阅模式
首先分析:发布订阅模式其实是将消息先发送给扇形交换机
,交换机再将消息转发给其绑定到此交换机的队列上。
这里,我们声明一个交换机,给交换机绑定两个队列,并且使用两个消费者分别绑定到两个队列上(其实就是为了和3.3
保持一致)。
4.4.1 声明交换机和队列
4.4.2 创建生产者
4.4.3 创建消费者
4.4.4 创建测试代码
4.4.5 启动测试
执行测试方法,输出内容如下:
生产者发送的两条消息,被两个消费者共同消费了。实现了消息的广播。
4.4.6 小节
本节代码中我们创建了一个fanout Exchange
,并且创建了两个队列与其绑定,其中一个队列进行绑定的时候还指定了routing key
,但程序执行时消息正常被消费,说明fanout Exchange
不用指定routing key
。
发布订阅模式与工作队列模式的区别
1、工作队列模式不用定义交换机,而发布/订阅模式需要定义交换机。
2、发布/订阅模式的生产方是面向交换机发送消息,工作队列模式的生产方是面向队列发送消息(底层使用默认交换机)。
3、发布/订阅模式需要设置队列和交换机的绑定,工作队列模式不需要设置,实际上工作队列模式会将队列绑定到默认的交换机 。
4.5 路由模式
首先分析:路由模式其实就是将 发布订阅模式中的 fanout Exchange
换成了 direct Exchange
从而指定相应的路由规则即可。
4.5.1 声明交换机和队列
4.5.2 创建生产者
4.5.3 创建消息者
4.5.4 创建测试代码
4.5.5 启动测试
执行测试代码,输出内容如下:
insert 和 update 对应的消息都被正常消费,其中值得注意的是指定routing key=delete
的消息丢失了,因为队列与交换机绑定时根本没有此routing key
,而交换机之所以叫交换机,因为其不存储消息,只是转发消息,其没有持久化消息的能力,所以消息还没有到queue
,然后嗝屁。
4.5.6 小节
路由模式特点:
- 队列与交换机的绑定,不能是任意绑定了,而是要指定一个
rutingKey
(路由key)。 - 消息的发送方在 向 Exchange发送消息时,也必须指定消息的
routingKey
。 - Exchange不再把消息交给每一个绑定的队列,而是根据消息的
routing Key
进行判断,只有队列的routingkey
与消息的routing key
完全一致,才会接收到消息。
4.6 主题模式
首先分析:通配符模式其实就是将 路由模式中的 direct Exchange
换成了 topic Exchange
, 使其不仅可以将exchange
和queue
以routing key
全匹配的方式进行绑定,而且还支持通配符
。
routingkey
一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:
#
:匹配一个或多个单词
*
:匹配一个单词
举例:
item.#
:能够匹配item.insert.abc
或者 item.insert
item.*
:只能匹配item.insert
图解:
- 红色Queue:绑定的是
usa.#
,因此凡是以usa.
开头的routing key
都会被匹配到 - 黄色Queue:绑定的是
#.news
,因此凡是以.news
结尾的routing key
都会被匹配
4.6.1 声明交换机和队列
4.6.2 创建生产者
4.6.3 创建消费者
4.6.4 创建测试代码
4.6.5 启动测试
执行测试代码,输入内容如下:
其中符合通配符条件的消息均已消费。
4.6.6 小节
Topic主题模式可以实现 Publish/Subscribe发布与订阅模式
和 Routing路由模式
的功能;只是Topic在配置routing key 的时候可以使用通配符,显得更加灵活。
5. 模式总结
RabbitMQ工作模式:
1、简单模式 HelloWorld
一个生产者、一个消费者,不需要设置交换机(使用default Exchange
)。
2、工作队列模式 Work Queue
一个生产者、多个消费者(平均分配消息),不需要设置交换机(使用default Exchange
)。
3、发布订阅模式 Publish/subscribe
需要设置交换机类型为fanout Exchange
,并且交换机和队列进行绑定,当发送消息到交换机后,交换机会将消息发送到绑定的队列。
4、路由模式 Routing
需要设置交换机类型为direct Exchange
,交换机和队列进行绑定,并且指定routing key
,发送消息时也要指定对应的routing key
到交换机,交换机会根据routing key
将消息发送到对应的队列。
5、主题模式 Topic
需要设置交换机类型为topic Exchange
,,交换机和队列进行绑定,并且指定通配符方式的routing key
,发送消息时指定routing key
到交换机后,交换机会根据routing key
规则将消息发送到对应的队列。主题模式比上面四类更灵活。
__EOF__

本文链接:https://www.cnblogs.com/ludangxin/p/15249473.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏