《RabbitMQ系列》之RabbitMQ的4种Exchange

news/2024/10/22 7:26:32

大家好,我是 tc,今天为大家介绍一下RabbitMQ中的4种exchange,水平一般,能力有限,若有错误之处,欢迎指正。

 

对RabbitMQ稍有了解的朋友应该都知道,在RabbitMQ中,一个有4中Exchange,分别是direct、topic、fanout、headers。

其实,还有一个默认的交换机,称为default exchange,其本质也是一个direct exchange。在这4种exchange中,最常用的是direct、topic、fanout。

下面,我们就通过代码示例分别介绍这4种exchange的用法,以及应用场景。

本文中代码涉及到的RabbitMQ的配置如下。

本文中代码涉及到的MAVEN依赖如下。

direct exchange

此种类型的交换机是通过routing key 和队列绑定在一起的。

通过一个routing key,交换机可以绑定一个队列,也可以同时绑定多个队列。

如果一个交换机绑定了多个队列,则交换机会将消息分别路由给每一个队列,也就是说每个队列都会得到一份全量的消息。

例如,交换机绑定了2个队列,接到生产者的10条消息后,不是分别向两个队列发送5条消息,而是向2个队列都发送10条消息。

下面,我们通过代码简单演示一下direct exchange的使用方式。

交换机绑定一个队列

启动类RabbitmqDemoApplication代码如下

@EnableRabbit注解的作用是开启基于注解的RabbitMQ。

生产者Producer代码如下

convertAndSend方法的作用就是向RabbitMQ发送消息,第一个参数"directExchange"指交换机的名称,

第二个参数"rk.001"指routing key,第三个参数是消息。

消费者代码如下

@RabbitListener注解的作用是指定目标方法来作为消费消息的方法,通过参数queues指定监听的队列,通过参数bindings指定监听的绑定。

其中,@Queue("queue.test.001") 在项目启动时,会创建一个名为queue.test.001的队列。

@Exchange("directExchange") 在项目启动时,会创建一个名为directExchange的交换机,如果不指定类型,默认就是direct exchange。

key指定交换机和队列的绑定的routing key。

通过如此配置,交换机directExchange就通过routing key“rk.001”和队列queue.test.001绑定在一起了。

一旦生产者向交换机directExchange发送消息,并指定routing key为“rk.001”,消费者consumer就可以消费消息了。

单元测试代码如下
测试结果如下

从测试结果来看,消费者正常消费了10条消息,与我们上面的预测是一致的。

RabbitMQ控制台如下

队列信息如下图。

交换机信息如下图。

交换机绑定多个队列

除了消费者代码之外,其他代码和上面相同,就不在赘述。

消费者代码如下

如上图代码所示。

我们创建了两个队列queue.test.001和queue.test.002,并都将其通过相同的routing key “rk.001”绑定到同一个交换机directExchange上。

按照我们上面的推测,这两个消费者process1和process2,都会消费10条消息。

测试结果如下

如上图所示,测试结果证明了我们的推测是正确的。

RabbitMQ控制台如下

队列信息如下。

交换机信息如下。

适用场景

1、适用于业务数据需要直接传输并消费的场景,比如不同业务模块之间的消息交互,就可以借助基于DirectExchange的消息模型进行通信。

2、点对点聊天

topic exchange

和direct exchange类似,topic exchange也是根据routing key,将exchange和queue绑定在一起。

区别在于,direct exchange的routing key 是精确匹配,而topic exchange的的routing key 是模式匹配,类似于正则表达式匹配。

routing key 可以是类似 *.orange.* 或者 lazy.# 的表达式。其中,* (星) 代表一个单词,# (hash) 代表0个或多个单词。

从上面的运行示意图中,我们可以看出queues中绑定的routing key是模糊的,usa.#这个routing key可以接收到usa.news和usa.weather的消息;而#.news这个routing key可以接收到usa.news和europe.news的消息。

下面,我们通过一个代码示例简单介绍一下topic exchange的用法,以及应用场景。

示例代码

生产者代码

如上图所示,我们创建了四个生产者,向topicExchange交换分别发送一条消息,同时指定routing key。

消费者代码

如上图所示,我们创建了四个消费者,并创建一个topic exchange,创建4个队列,并分别指定routing key,其中,*表示一个单词。

单元测试代码
测试结果

从上图可以看出:

消费者一通过routing key(usa.*)消费了两条和usa相关的消息,分别是生产者一和生产者二发送的消息;

消费者二通过routing key(*.news)消费了两条和news相关的消息,分别是生产者一和生产者三发送的消息;

消费者三通过routing key(europe.*)消费了两条和europe相关的消息,分别是生产者三和生产者四发送的消息;

消费者四通过routing key(*.weather)消费了两条和weather相关的消息,分别是生产者二和生产者四发送的消息;

和我们上面的推测是一致的。

RabbitMQ控制台信息

队列信息如下,可以看出我们创建了4个队列。

交换机信息如下,可以看出我们创建了一个topic类型的交换机。

适用场景

1、涉及分类或标记的新闻更新,例如体育新闻、娱乐新闻、社会新闻、金融新闻等分类推送。

2、后台任务处理,每个工作线程处理特定的任务。

fanout exchange

和direct exchange、topic exchange不同,fanout exchange不使用routing key,它会将消息路由到所有与其绑定的队列。

fanout exchange是消息广播路由的理想选择。

和direct exchange的一个交换机绑定多个队列的情况一样,绑定了fanout exchange的队列,都会接收到一份全量的消息。

示例代码

生产者代码

我们创建了4个生产者,指定交换机为fanoutExchange,但是没有指定routing key。

消费者代码

如上图,我们创建了4个消费者,同样指定交换机是fanoutExchange,且类型是fanout,同时还指定了routing key。

单元测试代码
测试结果

从上图的测试结果中可以看出,绑定了fanout exchange的每一个队列,都全量消费了消息。

我们在发送消息时,只指定了交换机,没有指定routing key,在消费者这边也指定了交换机,同时还指定了routing key,结果每个绑定了交换机的队列都可以消费到全量消息,这说明了fanout exchange不使用routing key,它会将消息路由到所有与其绑定的队列。

RabbitMQ控制台信息

队列信息如下。

交换机信息如下。

适用场景

1、适用于广播消息的场景

2、群聊功能,广播消息给当前群聊中的所有人

3、大型多人在线游戏的游戏积分排行榜更新

4、体育新闻客户端实时更新分数

5、分布式系统可以广播各种状态和配置更新

headers exchange

和上面三种交换机类型不同,headers exchange是根据Message的一些头部信息来分发过滤Message的,它会忽略routing key的属性,如果Header信息和message消息的头信息相匹配,那么这条消息就匹配上了。

有一个重要参数x-match:当“x-match”参数设置为“any”时,只要一个匹配的header 属性值就足够了;当“x-match”设置为“all”时,意味着所有值都必须匹配,才能将交换机和队列绑定上。

示例代码

配置代码

如上图所示,我们配置了三个队列:queue.headers.001、queue.headers.002和queue.headers.003,并创建了一个Headers类型的交换机headerExchange。

将队列queue.headers.001绑定到headerExchange上,并指定x-match=any,绑定的属性分别是type = 1,name = send11,也就是说,只能有一个属性可以匹配上,消费者就可以消费消息。

将队列queue.headers.002绑定到headerExchange上,并指定x-match=all,绑定的属性分别是type = 2,name = send2,也就是说,必须两个属性都匹配上,消费者才可以消费消息。

将队列queue.headers.003绑定到headerExchange上,并指定x-match=all,绑定的属性分别是type = 3,name = send33,也就是说,必须两个属性都匹配上,消费者才可以消费消息。

生产者代码

如上图所示,我们配置了三个生产者。

生产者一向交换机headerExchange发送消息,同时指定了两个headers属性:type = 1,name = send1;

生产者二向交换机headerExchange发送消息,同时指定了两个headers属性:type = 2,name = send2;

生产者三向交换机headerExchange发送消息,同时指定了两个headers属性:type = 3,name = send3;

消费者代码

如上图所示,我们配置了三个消费者,分别消费队列queue.headers.001、queue.headers.002和queue.headers.003的消息。

我们在上面的配置文件中,将queue.headers.001和headerExchange绑定在一起了,且只要有一个headers属性匹配上就可以消费消息;

将queue.headers.002、queue.headers.003也和headerExchange绑定在一起了,且必须所有的headers属性都匹配上才可以消费消息;

从上面的代码中,我们可以作出如下推测:

1、消费者一可以正常消费消息。因为生产者一发送消息时指定了type = 1,name = send1属性,而在配置文件中,同样配置了type = 1,name = send11属性,且x-match = any,正好有一个type = 1 属性是可以匹配上的,故而可以可以正常消费消息。

2、消费者二可以正常消费消息。因为生产者二发送消息时指定了type = 2,name = send2属性,而在配置文件中,同样配置了type = 2,name = send2属性,且x-match = all,两个headers属性都可以匹配上,故而可以正常消费消息。

3、消费者三不可以正常消费消息。因为生产者三发送消息时指定了type = 3,name = send3属性,而在配置文件中,同样配置了type = 3,name = send33属性,且x-match = all,两个headers属性只有type可以匹配上,故而不可以正常消费消息。

单元测试代码
测试结果

从上图可以看出,消费者一和消费者二可以正常消费消息,但是消费者三没有消费,因为没有匹配上。

RabbitMQ控制台信息

队列信息如下。

交换机信息如下。

适用场景

1、适用于routing key非常复杂或者灵活多变的场景


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/72345.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

10.16测试分类

软件测试之测试分类 一、按开发阶段划分 1、单元测试 2、集成测试 3、系统测试 4、验收测试 二、按查看代码划分 1、黑盒测试 定义:黑盒测试也是功能测试,测试中把被测试的软件当成一个黑盒子,不关心盒子的内部结构是什么,只关心软件的输入数据和输出数据 比如: 计算器当作…

C#线程---await

简介:前面异步编程的不足:它允 许我们以模块化的方式设计程序,来组合不同的异步操作。遗憾的是: 一: 当阅读此类程序时仍然非常难理解程序的实际执行顺序。在大型程序中将会有许多相互依赖的任务和后续操作,用于运行其他后续操作的后续操作,处理异常的后续操 作,并且它…

倒排索引及ES相关概念对比MySQL

一、倒排索引 1、先把文档内容进行分词,形成词条与文档ID的对应关系,叫做词条库,词条具备唯一性,建立索引 2、对搜索内容进行分词,分词后得到一个关键词列表,根据关键词去词条库中匹配,在找对应的文档ID列表 3、然后根据文档ID列表,找到对应的文档信息 对比:二、ES相关…

SD外向交货单

1、写在前面 1.1、文档说明 本文档将介绍外向交货单的创建、修改、删除、过账以及冲销,并且包含如何使用代码来实现上述过程。另外,还将介绍衍生出的交货单屏幕增强和BAPI维护扩展字段等内容。 1.2、关于外向交货单 在 SAP系统中,外向交货单(Outbound Delivery Note)是一个…

Idea序列图插件-SequenceDiagram Core

简介 SequenceDiagram Core 是一个 IntelliJ IDEA 插件,它允许开发者直接在 IDE中创建和编辑序列图(Sequence Diagrams)。序列图是 UML(统一建模语言)中的一种图表类型,用于描述对象之间如何交互以及这些交互的顺序。这种类型的图表对于理解复杂的系统流程、设计模式或者…

【Unity微信】Unity发布微信小游戏+对接第三方SDK过程

官方文档:https://wechat-miniprogram.github.io/minigame-unity-webgl-transform/ 上面的文档,能完成库的导入和发布操作下面开始调用接口获取玩家信息1 2 /// <summary>3 /// 初始化SDK4 /// </summary>5 private void InitSDK()6 {7 …

pikachu靶场搭建

使用Dockers 搭建靶场安装docker 因为我使用的是kali 这里就直接安装了apt-get install docker.io搜索 pikachu 的镜像容器┌──(root㉿kali)-[/home/kali] └─# docker search pikachu NAME DESCRIPTION STARS …

NSString 与 Unicode

这篇文章里,我会先向你简单地讲一下 Unicode 这个标准,然后解释 NSString 是怎么处理它的,再讨论一下你可能会遇到的一些常见问题。英文: https://www.objc.io/issues/9-strings/unicode/ https://learn.microsoft.com/en-us/dotnet/api/system.string.normalize?view=net-…