【RabbitMQ】RabbitMQ的交换机

交换机类型

在上文中,都没有交换机,生产者直接发送消息到队列。而一旦引入交换机,消息发送的模式会有很大变化:可以看到,在订阅模型中,多了一个exchange角色,而且过程略有变化:

  • Publisher:生产者,不再发送消息到队列中,而是发给交换机
  • Exchange:交换机,一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。
  • Queue:消息队列也与以前一样,接收消息、缓存消息。不过队列一定要与交换机绑定。
  • Consumer:消费者,与以前一样,订阅队列,没有变化

Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!

交换机的类型有四种:

  • Fanout:广播,将消息交给所有绑定到交换机的队列。我们最早在控制台使用的正是Fanout交换机
  • Direct:订阅,基于RoutingKey(路由key)发送给订阅了消息的队列
  • Topic:通配符订阅,与Direct类似,只不过RoutingKey可以使用通配符
  • Headers:头匹配,基于MQ的消息头匹配,用的较少。

Fanout,英文翻译是扇出,我觉得在MQ中叫广播更合适。在广播模式下,消息发送流程是这样的:

  • 1)  可以有多个队列
  • 2)  每个队列都要绑定到Exchange(交换机)
  • 3)  生产者发送的消息,只能发送到交换机
  • 4)  交换机把消息发送给绑定过的所有队列
  • 5)  订阅队列的消费者都能拿到消息

Fanout

Fanout,英文翻译是扇出,我觉得在MQ中叫广播更合适。在广播模式下,消息发送流程是这样的:

  • 1)  可以有多个队列
  • 2)  每个队列都要绑定到Exchange(交换机)
  • 3)  生产者发送的消息,只能发送到交换机
  • 4)  交换机把消息发送给绑定过的所有队列
  • 5)  订阅队列的消费者都能拿到消息

我们的计划是这样的:

  • 创建一个名为Rys.fanout的交换机,类型是Fanout
  • 创建两个队列fanout.queue1和fanout.queue2,绑定到交换机Rys.fanout
  • 声明队列和交换机,在控制台创建队列fanout.queue1:在创建一个队列fanout.queue2:然后再创建一个交换机:然后绑定两个队列到交换机:
消息发送

在publisher服务的SpringAmqpTest类中添加测试方法:

@Test
public void testFanoutExchange() {// 交换机名称String exchangeName = "Rys.fanout";// 消息String message = "hello, everyone!";rabbitTemplate.convertAndSend(exchangeName, "", message);
}
消息接收

在consumer服务的SpringRabbitListener中添加两个方法,作为消费者:

@RabbitListener(queues = "fanout.queue1")
public void listenFanoutQueue1(String msg) {System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
}
​
@RabbitListener(queues = "fanout.queue2")
public void listenFanoutQueue2(String msg) {System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
}
总结

交换机的作用是什么?

  • 接收publisher发送的消息
  • 将消息按照规则路由到与之绑定的队列
  • 不能缓存消息,路由失败,消息丢失
  • FanoutExchange的会将消息路由到每个绑定的队列

Direct交换机

在Fanout模式中,一条消息,会被所有订阅的队列都消费。但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。

在Direct模型下:

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
  • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的RoutingKey。
  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

案例需求如图:

  1. 声明一个名为Rys.direct的交换机
  2. 声明队列direct.queue1,绑定Rys.direct,bindingKey为blud和red
  3. 声明队列direct.queue2,绑定Rys.direct,bindingKey为yellow和red
  4. 在consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2
  5. 在publisher中编写测试方法,向Rys.direct发送消息

消息接收

在consumer服务的SpringRabbitListener中添加方法:

@RabbitListener(queues = "direct.queue1")
public void listenDirectQueue1(String msg) {System.out.println("消费者1接收到direct.queue1的消息:【" + msg + "】");
}
​
@RabbitListener(queues = "direct.queue2")
public void listenDirectQueue2(String msg) {System.out.println("消费者2接收到direct.queue2的消息:【" + msg + "】");
}

消息发送

在publisher服务的SpringAmqpTest类中添加测试方法:

@Test
public void testSendDirectExchange() {// 交换机名称String exchangeName = "Rys.direct";// 消息String message = "红色警报!!";// 发送消息rabbitTemplate.convertAndSend(exchangeName, "red", message);
}

由于使用的red这个key,所以两个消费者都收到了消息:我们再切换为blue这个key:

@Test
public void testSendDirectExchange() {// 交换机名称String exchangeName = "Rys.direct";// 消息String message = "蓝色预警";// 发送消息rabbitTemplate.convertAndSend(exchangeName, "blue", message);
}

你会发现,只有消费者1收到了消息:

总结

描述下Direct交换机与Fanout交换机的差异?

  • Fanout交换机将消息路由给每一个与之绑定的队列
  • Direct交换机根据RoutingKey判断路由给哪个队列
  • 如果多个队列具有相同的RoutingKey,则与Fanout功能类似

Topic交换机

1.说明

Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符!

BindingKey 一般都是有一个或多个单词组成,多个单词之间以.分割,例如: item.insert

通配符规则:

  • #:匹配一个或多个词
  • *:匹配不多不少恰好1个词

举例:

  • item.#:能够匹配item.spu.insert 或者 item.spu
  • item.*:只能匹配item.spu

假如此时publisher发送的消息使用的RoutingKey共有四种:

  • china.news代表有中国的新闻消息;
  • china.weather 代表中国的天气消息;
  • japan.news 则代表日本新闻
  • japan.weather 代表日本的天气消息;

消息发送

在publisher服务的SpringAmqpTest类中添加测试方法:

@Test public void testTopicExchange() { // 交换机名称 String exchangeName = "RysTopic"; // 消息 String message = "明天下大暴雨!!!"; rabbitTemplate.convertAndSend(exchangeName, "china.news", message); }

消息接收

@RabbitListener(queues = "topic.queue1") public void listenTopicQueue1(String msg) { System.out.println("消费者1收到了topic.queue1的消息......:【" + msg +"】"); } @RabbitListener(queues = "topic.queue2") public void listenTopicQueue2(String msg) { System.err.println("消费者2收到了topic.queue2的消息......:【" + msg +"】"); }

关系绑定

运行

总结

描述下Direct交换机与Topic交换机的差异?

  • Topic交换机接收的消息RoutingKey必须是多个单词,以 . 分割
  • Topic交换机与队列绑定时的bindingKey可以指定通配符
  • #:代表0个或多个词
  • *:代表1个词

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android bp构建引入其他模块头文件

最近做项目过程中经常遇到Android.bp文件引入其他模块的头文件库,总是记不住bp的写法,这里做个记录 1.产生头文件库 2.其他的模块应用引入头文件库 不由想起来老师的名句:好记忆不如烂笔头。

Linux虚拟机上离线安装ansible awx_亲测成功

Linux虚拟机上离线安装ansible awx_亲测成功 可自行去下载相关包,也可以给我评论留言,我发给大家 ansible awx离线安装----虚拟机上安装 成功----------------------------- python -V 2.7.5tar -zxvf setuptools-20.0.tar.gz cd setuptools-20.0 python setup.py installtar…

基于遗传算法改进的RBF神经网络流量控制,基于GA-RBF的流量预测

目录 完整代码和数据下载链接:基于遗传算法改进的RBF神经网络流量控制,基于GA-RBF的流量预测(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/abc991835105/88937452 RBF的详细原理 RBF的定义 RBF理论 易错及常见问题 RBF应用实例,基于遗传算法改…

【Python使用】python高级进阶知识md总结第3篇:静态Web服务器-返回指定页面数据,静态Web服务器-多任务版【附代码文档】

python高级进阶全知识知识笔记总结完整教程(附代码资料)主要内容讲述:操作系统,虚拟机软件,Ubuntu操作系统,Linux内核及发行版,查看目录命令,切换目录命令,绝对路径和相对…

nacos服务注册和发现

打开nacos console&#xff1a;http://192.168.1.30:8848/nacos&#xff0c;创建名称空间 添加依赖&#xff0c;在 api 模块中添加对应依赖&#xff08;service和service-order从api传递&#xff09; <dependency> <groupId>com.alibaba.cloud</groupId> …

拥抱灵活性与可扩展性:为什么NoSQL数据库是现代应用的理想选择

引言&#xff1a; 随着数据在当今社会中的重要性不断增加&#xff0c;数据存储技术也在不断演变。传统的SQL数据库虽然在处理结构化数据方面表现出色&#xff0c;但随着数据的多样性和规模的迅速增长&#xff0c;它们开始显现出一些局限性。在这样的背景下&#xff0c;NoSQL数…

Linux操作系统Linux—C编程

一、编写C程序 1.设置vim编辑器 &#xff08;1&#xff09;vim编辑器tab键默认为8个空格键不适合编程使用&#xff0c;因此我们需要修改为4个空格。 第一步&#xff1a;打开vimrc文件 sudo vi /etc/vim/vimrc 第二步&#xff1a;文件末行添加一句set ts4 &#xff08;2&#x…

react recharts饼图 及配置项

<Pie>&#xff1a;指定饼图的数据和样式。 data&#xff1a;设置图表使用的数据数组。dataKey&#xff1a;指定用于饼图切片面积计算的数据字段。nameKey&#xff1a;指定用于显示在图例和提示框中的数据字段。cx 和 cy&#xff1a;设置饼图中心的位置。outerRadius&…

笔记79:ROS入门之前的准备

一、ROS是什么 ROS其实是一个伪操作系统&#xff0c;是基于Liunx操作系统的一个用于机器人各个节点之间通信的系统&#xff1b;ROS制定了一系列规则使得每个节点之间遵循相同的通信规则&#xff0c;使得每个人都可以有一个守则区遵守开发自己的节点&#xff0c;也能和别人开发…

Linux -- 线程概念和控制

一 什么是线程 1.1 线程的引出 我们开始理解一下Linux中的线程。我们以前说过&#xff0c;一个进程被创建出来&#xff0c;要有自己对应的进程PCB的&#xff0c;也就是 task_struct&#xff0c;也要有自己的地址空间、页表&#xff0c;经过页表映射到物理内存中。所以在进程角…

python基础练习 Fibonacci数列

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 Fibonacci数列的递推公式为&#xff1a;FnFn-1Fn-2&#xff0c;其中F1F21。 当n比较大时&#xff0c;Fn也非常大&#xf…

基于java ssm springboot女士电商平台系统

基于java ssm springboot女士电商平台系统源码文档设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末…

WebPack自动吐出脚本

window.c c; window.res ""; window.flag false;c function (r) {if (flag) {window.res window.res "${r.toString()}" ":" (e[r] "") ",";}return window.c(r); }代码改进了一下&#xff0c;可以过滤掉重复的方…

web基础05-jQuery

目录 一、jQuery 1.概述 2.原生js与jQuery对比 3.特点 4.使用 &#xff08;1&#xff09;入口函数 &#xff08;2&#xff09;语法 &#xff08;3&#xff09;jQuery选择器 5.方法 &#xff08;1&#xff09;获取属性值&#xff1a; &#xff08;2&#xff09;删除属…

WinForm 修改TableControl背景和标签

在界面设计中&#xff0c;TableControl控件经常使用。默认设置中&#xff0c;TabControl的背景和标签样式。接下来我们将学习如何修改TableControl的标签选项、修改TabControld的背景色或背景图片。页面效果如下&#xff1a; 简述原理 TableControl项目属性DrawMode&#xff0c…

【开源工程】数字孪生工厂~工业上楼解决方案

飞渡科技数字孪生轻工厂管理平台&#xff0c;基于数字孪生技术驱动的智能&#xff0c;结合物联网IOT实现的联接&#xff0c;以及大数据分析生成的融合共享数据&#xff0c;实现生产过程的智能化监控和管理&#xff0c;实现设备之间的互联互通和协同工作。 通过智能算法&#xf…

前端报错404,nginx正常、gateway没有转发请求

问题描述&#xff1a;前端报错 404 Not Found 原因&#xff1a;nacos中对应服务没有上线&#xff0c;下线后&#xff0c;可以启动本地服务&#xff0c;然后在测试上调试代码。&#xff01;&#xff01; 记住重启对应服务&#xff0c;也不会自动上线。

Linux-TCP并发模型-013

1【TCP】多线程模型 2【IO】模型 2.1阻塞IO 没有数据到来时&#xff0c;可以让任务挂起&#xff0c;节省CPU资源开销&#xff0c;提高系统效率2.2非阻塞IO 程序未收到数据时一直执行&#xff0c;效率很低2.3异步IO 只能绑定一个文件描述符用来读取数据2.4多路复用IO 2.4.…

电商数据分析19——数据分析在电商平台价格弹性研究中的应用

目录 写在开头1. 价格弹性的基本理论1.1 价格弹性的定义1.2 价格弹性对销售和利润的影响1.2.1 如何通过价格弹性预测销量变化1.2.2 价格弹性高和低对企业策略的影响2 数据分析方法在价格弹性研究中的应用2.1 收集与处理销售和价格数据2.1.1 收集数据2.1.2 数据处理2.2 使用统计…

linux设置开机启动慎用nohup

我机器ubuntu9,设置开机启动我的应用程序&#xff0c;这个大家都知道只要在/etc/rc.local中加上一条shell启动命令就可以了。 但我确碰到了一个奇怪的问题&#xff1a;无法启动我的应用程序。 由于我的程序是java写的&#xff0c;一直怀疑是classpath问题&#xff0c;检查多次没…