【RabbitMQ】RabbitMQ的交换机

news2024/11/17 14:45:27

交换机类型

在上文中,都没有交换机,生产者直接发送消息到队列。而一旦引入交换机,消息发送的模式会有很大变化:可以看到,在订阅模型中,多了一个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.coloradmin.cn/o/1508276.html

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

相关文章

ThreadLocal出现内存泄露原因分析

ThreadLocal 导致内存泄漏的主要原因是它的工作方式。在 Java 中,ThreadLocal 通过维护一个以 Thread 为键,以用户设置的值为值的映射来工作。每个线程都拥有其自身的线程局部变量副本,不同线程间的这些变量互不干扰。这个映射是存储在每个 T…

EpiCypher—SMARCAL1介导的肿瘤免疫逃避

资深作者Alberto Ciccia博士(左)和第一作者Giuseppe Leuzzi博士。 在新的博客系列中,我们将对话最近发表染色质研究工作的首席科学家们,了解他们的幕后工作。在EpiCypher,我们很感兴趣染色质技术是如何整合到不同领域的,如免疫学、…

【Ubuntu】gonme桌面的 gdm 和 lightdm 区别

总结:都可以 gdm: 【Gnome Display Manager】 完整,体积大 lightdm: 【Light Display Manager】 轻量

HBase非关系型数据库

HBase非关系型数据库 1 什么是HBase2 HBase的特点3 什么时候需要HBase4 HBase的数据模型5 HBase架构5.1 架构5.2 HBase如何列式储存 6 如何正确设计RowKey 1 什么是HBase HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩、 实时读写的分布式数据…

趣味看图-Linux 文件系统的组成

/(根目录):根目录是Linux文件系统中的顶级目录。所有其他目录都是根目录的子目录,使其成为整个文件系统的父目录。 /bin:包含启动系统和执行基本操作所需的基本二进制可执行文件。这些对所有用户都可用。 /boot&…

手撕栈和队列

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧 引言 栈和队列作为数据结构的重要组成部分,可以用栈实现非递归等,为后面学习打基础。栈由数组来实现,队列由链表来实现,接下来将详细介绍 …

C++实现引用计数(二)

实现引用计数 引言实现集成开发环境项目结构实现代码运行结果 注意 引言 C中经常使用智能指针来管理内存。对于共享指针shared_ptr的原理:每当有一个指针指向这块内存,引用计数的值加一,每当一个指针不再指向这块内存,引用计数的…

【OpenGL手册14】投光物

目录 一、说明二、平行光三、点光源四、衰减五、选择正确的值六、实现衰减七、聚光八、手电筒九、平滑/软化边缘练习 一、说明 我们目前使用的光照都来自于空间中的一个点。它能给我们不错的效果,但现实世界中,我们有很多种类的光照,每种的表…

员工私单亡羊补牢!这个监管神器让你从此放心!

对于企业而言,如何有效监管员工的微信使用成为了一项重要的任务。幸运的是,现在有一个监管神器——微信管理系统,可以帮助企业从根本上解决这个问题。 接下来,让我们一起来看看这个监管神器究竟有哪些神奇的功能吧! …

5款好用的AI办公软件,一键轻松制作PPT、视频,提升工作效率!

众所周知,AI 人工智能技术已渗透到生活的方方面面,无论是很多人早已用上的智能音箱、语音助手,还是新近诞生的各种 AI 软件工具,背后都离不开 AI 人工智能技术的加持。 对于各类新生的 AI 软件工具,人们很容易「选边站…

亚马逊多账号怎么防关联?超级浏览器来帮你!

很多做亚马逊跨境电商的小伙伴都会遇到的问题就是多登店铺账号被关联,我们要知道,如果在亚马逊上运营多个店铺,保持账户之间的独立性是很重要的。一旦账户之间被平台识别为关联,不仅可能导致收入损失,还可能面临账号被…

短视频,文案素材哪里找?找短视频文案素材指南

有很多创业者,耗费了很长时间创作出了很多短视频,文案素材没写好,导致浏览量下降,或者写文案的同时就已经花费了很长时间,导致没有时间发布视频,从而影响了流量,导致流量下滑,其实我…

React-嵌套路由

1.概念 说明&#xff1a;在一级路由中又内嵌了其他路由&#xff0c;这种关系就叫做嵌套路由&#xff0c;嵌套至一级路由内的路由又称作二级路由。 2.实现步骤 说明&#xff1a;使用childen属性配置路由嵌套关系&#xff0c;使用<Outlet/>组件配置二级路由渲染的位置。…

RK3588-hdmiin

1. HDMI-IN简介 HDMI IN功能可以通过桥接芯⽚的⽅式实现&#xff0c;将HDMI信号转换成MIPI信号接收RK3588芯⽚平台⾃带HDMI RX模块&#xff0c;可以直接接收HDMI信号&#xff0c;无需通过桥接芯⽚实现。在ArmSoM系列产品中&#xff0c;ArmSoM-W3支持HDMI-IN功能HDMI-IN功能框图…

容灾演练双月报|美创DRCC助力银行高效验证数据库高可用架构

了解更多灾备行业动态 守护数字化时代业务连续 目录 CONTENTS 01 灾备法规政策 02 热点安全事件 03 容灾演练典型案例 01 灾备法规政策 2月&#xff0c;工信部印发《工业领域数据安全能力提升实施方案&#xff08;2024—2026年&#xff09;》&#xff0c;要求到2026年…

Java语言的演变之路:从过去到现在,以及未来的展望与探索

引言 Java&#xff0c;这个在全球范围内广受欢迎的编程语言&#xff0c;自其诞生之日起&#xff0c;就注定要在计算机科学的历史上留下浓墨重彩的一笔。起源于20世纪90年代&#xff0c;Java的初衷是打造一种能够在多种平台上运行的、安全且易于使用的编程语言。它不仅成功地实…

MySQL-QA-异常问题及解决方案(持续更新)

MySQL-Q&A(持续更新) 1.1 PID文件找不到 问题描述 错误详情&#xff1a; ERROR&#xff01;The server quit without updating PID file (/usr/local/mysql/data/localhost.localdomain.pid) 解决方案 首先排查配置文件&#xff0c;一般路径为&#xff1a;/etc/my.cnf 检查…

【C++】stack/queue

链表完了之后就是我们的栈和队列了&#xff0c;当然我们的STL中也有实现&#xff0c;下面我们先来看一下简单用法&#xff0c;跟我们之前C语言实现的一样&#xff0c;stack和queue有这么几个重要的成员函数 最主要的就是这么几个&#xff1a;empty&#xff0c;push&#xff0c;…

嘿!AI 编码新玩法上线!

随着 AI 智能浪潮到来&#xff0c;AI 编码助手成为越来越多开发者的必备工具&#xff0c;将开发者从繁重的编码工作中解放出来&#xff0c;极大地提高了编程效率&#xff0c;帮助开发者实现更快、更好的代码编写。 通义灵码正是这样一款基于阿里云通义代码大模型打造的智能编码…

ReorderData - 优化阅读笔记

主要实现文件: bolt/lib/Passes/ReorderData.cpp 支持 X86/Arm 测试用例&#xff1a; bolt/test/reorder-data-writable-ptload.c int a1,a2,a3,a4; // 待补充默认关闭&#xff0c;开启选项&#xff1a; # 指定要重排的数据段 --reorder-data<section1,section2,section3…