RabbitMQ(任务模型,交换机(广播,订阅,通配符订阅))

一.WorkQueues模型

WorkQueues(任务模式):让多个消费者绑定到一个队列,共同消费队列中的消息

架构:

所需场景:

当消息处理比较耗时的时候,可能生产消息的速度会远远大于消息的消费速度。长此以往,消息就会堆积越来越多,无法及时处理。 此时就可以使用work 模型,多个消费者共同处理消息处理,消息处理的速度就能大大提高了。

1.新建队work.queue

2.生产者模块循环发送消息
    @Test
    void testWorkQueue() throws InterruptedException {
        String queueName = "work.queue";
        for (int i = 1; i <= 50; i++) {
            String msg = "hello, worker, message_" + i;
            rabbitTemplate.convertAndSend(queueName, msg);
            Thread.sleep(20);
        }
    }
3.消费者模块模拟多个消费者绑定该队列
    @RabbitListener(queues = "work.queue")
    public void listenWorkQueueMsg1(String msg) throws InterruptedException {
        System.out.println("消费者一接收到work.queue的信息" + msg+ LocalDateTime.now());
        Thread.sleep(20);
    }

    @RabbitListener(queues = "work.queue")
    public void listenWorkQueueMsg2(String msg) throws InterruptedException {
        System.out.println("消费者2接收到work.queue的信息" + msg+LocalDateTime.now());
        Thread.sleep(200);
    }

消费者1 sleep了20毫秒,相当于每秒钟处理50个消息

消费者1 sleep了20毫秒,相当于每秒钟处理50个消息

4.测试

测试结果中:尽管给消费者二设置了比消费者一十倍长的休眠时间。但是两个消费者的处理信息个数是相同的。且消费者一很快就处理完消息,而剩下的消息只有消费者二去消费。并没有充分利用每一个消费者的能力。

可以通过配置消费者模块的yml文件解决该问题

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息
5.二次测试

6.总结:

Work模型的使用:

  • 多个消费者绑定到一个队列,同一条消息只会被一个消费者处理

  • 通过设置prefetch来控制消费者预取的消息数量

二.Exchange(交换机)

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

交换机的类型有四种:

  • Fanout:广播,将消息交给所有绑定到交换机的队列。我们最早在控制台使用的正是Fanout交换机

  • Direct:订阅,基于RoutingKey(路由key)发送给订阅了消息的队列

  • Topic:通配符订阅,与Direct类似,只不过RoutingKey可以使用通配符

  • Headers:头匹配,基于MQ的消息头匹配,用的较少。

三.Fanout交换机(广播)

架构:

广播模式发送流程:

  • 1)  可以有多个队列

  • 2)  每个队列都要绑定到Exchange(交换机)

  • 3)  生产者发送的消息,只能发送到交换机

  • 4)  交换机把消息发送给绑定过的所有队列

  • 5)  订阅队列的消费者都能拿到消息

一.创建两个队列:fanout.queue1,fanout.queue2

二.创建一个交互机:fanout

三.将队列绑定至交互机

四.编写测试代码

生产者端:

    @Test
    void testSendFanout() {
        String exchangeName = "hmall.fanout";//交换机
        String msg = "hello, everyone!";
        rabbitTemplate.convertAndSend(exchangeName, null, msg);
    }

消费端:

    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue1(String msg) throws InterruptedException {
        System.out.println("消费者1 收到了 fanout.queue1的消息:【" + msg +"】");
    }

    @RabbitListener(queues = "fanout.queue2")
    public void listenFanoutQueue2(String msg) throws InterruptedException {
        System.out.println("消费者2 收到了 fanout.queue2的消息:【" + msg +"】");
    }

测试结果:

五.总结

交换机的作用

  • 接收publisher发送的消息

  • 将消息按照规则路由到与之绑定的队列

  • 不能缓存消息,路由失败,消息丢失

  • FanoutExchange的会将消息路由到每个绑定的队列

四.Direct交换机(订阅)

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

结构:

在Direct模型下

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)

  • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey

  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

一.测试逻辑:
  1. 声明一个名为hmall.direct的交换机

  2. 声明队列direct.queue1,绑定hmall.directbindingKeybludred

  3. 声明队列direct.queue2,绑定hmall.directbindingKeyyellowred

  4. consumer服务中,编写两个消费者方法,分别监听direct.queue1和direct.queue2

  5. 在publisher中编写测试方法,向hmall.direct发送消息

二.创建两个队列direct.queue1和direct.queue2

三.创建一个direct类型交换机 hmall.direct并绑定队列

四.编写测试类

消费模块:

    @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 +"】");
    }

生产模块:

    @Test
    void testSendDirect() {
        String exchangeName = "hmall.direct";
        String msg = "蓝色通知,警报解除,哥斯拉是放的气球";
        rabbitTemplate.convertAndSend(exchangeName, "blue", msg);
    }

测试结果:

rabbitTemplate.convertAndSend(exchangeName, "blue", msg)改为rabbitTemplate.convertAndSend(exchangeName, "red", msg)

测试结果:

五.总结:

Direct交换机与Fanout交换机的差异

  • Fanout交换机将消息路由给每一个与之绑定的队列

  • Direct交换机根据RoutingKey判断路由给哪个队列

  • 如果多个队列具有相同的RoutingKey,则与Fanout功能类似

五.Topic交换机

架构:

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

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

通配符规则:

  • #:匹配一个或多个词

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

举例:

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

  • item.*:只能匹配item.spu

一.测试逻辑

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

  • china.news代表有中国的新闻消息;

  • china.weather 代表中国的天气消息;

  • USA.news 则代表美国新闻

  • USA.weather 代表美国的天气消息;

解释:

  • topic.queue1:绑定的是china.# ,凡是以 china.开头的routing key 都会被匹配到,包括:

    • china.news

    • china.weather

  • topic.queue2:绑定的是#.news ,凡是以 .news结尾的 routing key 都会被匹配。包括:

    • china.news

    • USA.news

二.绑定交互机与队列

三.编写测试代码

消费者:

@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.out.println("消费者2接收到topic.queue2的消息:【" + msg + "】");
}

生产者:

@Test
void testSendTopic() {
    String exchangeName = "hmall.topic";
    String msg = "今天天气挺不错,我的心情的挺好的";
    rabbitTemplate.convertAndSend(exchangeName, "china.weather", msg);
    rabbitTemplate.convertAndSend(exchangeName,"USA.news","美国新闻");
    rabbitTemplate.convertAndSend(exchangeName,"china.news","中国新闻");
}

测试结果

四.总结

Direct交换机与Topic交换机的差异

  • Topic交换机接收的消息RoutingKey必须是多个单词,以 **.** 分割

  • Topic交换机与队列绑定时的bindingKey可以指定通配符

  • #:代表0个或多个词

  • *:代表1个词

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

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

相关文章

工业镜头的重要参数之视场、放大倍率、芯片尺寸--51camera

今天来简单介绍下工业镜头中常用的参数中的三个&#xff1a; 1、视场 视场&#xff08;FOV&#xff09;也称视野,是指能被视觉系统观察到的物方可视范围。 对于镜头而言&#xff0c;可观察到的视场跟镜头放大倍率及相机芯片选择有关。因此需要根据被观察物体的尺寸&#xff…

docker安装和配置minio

1. 安装镜像 docker pull minio/minio:latest上方的命令是拉取最新版本, 目前我的版本为1.29.0 2. 运行minio 客户端端口号: 29000 ,服务端端口号: 29090 docker run -p 29000:29000 -p 29090:29090 \--name minio \-d --restartalways \-e "MINIO_ACCESS_KEYminioadm…

《花书》学习:LeNet

# LeNet网络架构 正常的应该是&#xff1a;输入→操作→输出 但都简化 要么省略 操作 要么省略 输出 # LeNet第一个卷积层详解

华为OD七日集训第1期 - 按算法分类,由易到难,循序渐进,玩转OD

目录 一、适合人群二、本期训练时间三、如何参加四、七日集训第 1 期&#xff0c;极简题&#xff0c;培养刷题兴趣五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、逻辑分析第2天、字符串处理第3天、数组第4天、数据结构第5天、栈第6天、双指针第7天、二分查找…

Java面试题【必知必会】Spring常见面试题(2024)

近期一直在准备面试&#xff0c;所以为了巩固知识&#xff0c;也为了梳理&#xff0c;整理了一些java的基础面试题&#xff01;同时也希望各位英雄和女侠能够补充&#xff01;不胜荣幸&#xff01;&#xff01;&#xff01; 1.spring是什么&#xff1f;它的优点是什么&#xff…

灯塔:CSS笔记(1)

CSS&#xff1a;层叠样式表 所谓层叠 即叠加的意思&#xff0c;表示样式可以一层一层的层叠覆盖 css写在style标签中&#xff0c;style标签一般写在head标签里面&#xff0c;title标签下面 <!DOCTYPE html> <html lang"en"> <head><meta cha…

js设计模式:解释器模式

作用: 对文本进行解释和编译的时候,就会用到解释器模式 比如你写了一段js代码,js引擎就会去解释并执行这段代码 webpack中的各种loader就是用来解释各种文件类型的,并将其解释为js可识别的代码 示例: //翻译词库const wordList [{text:韩信前期有蓝有红,必须拿二杀。你要是…

衣服晒三天湿臭,AI果蝇图片一般,玩物让生活更急幸福——早读(逆天打工人爬取热门微信文章解读)

回南天&#xff0c;衣服晒三天湿臭 引言python代码第一篇 人民日报 极简工作报告第二篇 人民日报 【夜读】5个好习惯&#xff0c;让生活更幸福第三篇 人民日报 来了&#xff01;新闻早班车要闻社会政策 结尾 路漫漫其修远兮&#xff0c;犹如披荆斩棘翻越高山之巅 在疾风骤雨中砥…

#QT(TCP网络编程-服务端)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;编写一个tcp服务端 QTcpsever QTcpsocket 3.记录&#xff1a; (1)先搭建界面 &#xff08;2&#xff09;服务端代码 a. pro QT core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c1…

2024关于idea激活码报This license xxxx has been suspended

HOSTS文件中增加 0.0.0.0 www.jetbrains.com 0.0.0.0 account.jetbrains.com 然后

7、Linux-防火墙和配置静态ip

一、防火墙&#xff08;防火墙服务名firewalld&#xff09; 防火墙配置命令&#xff1a;firewall-cmd firewall-cmd --help&#xff1a;防火墙帮助firewall-cmd --state&#xff1a;查看防火墙状态firewall-cmd --zonepublic --list-ports&#xff1a;查看所有打开的端口firew…

三大数学软件之Maple

相信钻研数学的小伙伴们对MATLAB、SPSS这样的重量级软件并不陌生&#xff0c;这些大型软件能求解复杂的运算&#xff0c;解决各领域的数学问题。今天博主为大家带来了一款名不见经传的软件——Maple&#xff0c;作为三大数学软件之一&#xff0c;Maple同样拥有不菲的计算能力&a…

医院电动床脚踏开关的机械强度测试检测

医院电动床是现代医疗设备中不可或缺的一部分。它们提供了病人安全舒适的床位&#xff0c;并具备调节床位高度和角度的功能。然而&#xff0c;在日常使用过程中&#xff0c;医院电动床的各个部件可能会受到一定程度的磨损和摩擦。因此&#xff0c;确保电动床的每个关键部件的机…

TRIZ理论破解重量与强度难题:材料科学的革命性突破!

在机械结构设计的领域里&#xff0c;工程师们常常面临着一个难以抉择的问题&#xff1a;如何在保证结构强度的同时&#xff0c;尽可能地减轻重量&#xff1f;传统的惯性思维可能会让我们倾向于增加材料的厚度来增强结构的稳固性&#xff0c;但这样一来&#xff0c;结构的重量也…

SpringBoot集成flink

Flink是一个批处理和流处理结合的统一计算框架&#xff0c;其核心是一个提供了数据分发以及并行化计算的流数据处理引擎。 最大亮点是流处理&#xff0c;最适合的应用场景是低时延的数据处理。 场景&#xff1a;高并发pipeline处理数据&#xff0c;时延毫秒级&#xff0c;且兼具…

2024软考大改革!一年只能考一次!

软考办2024年软考考试安排刚刚发布了&#xff01;变化很大&#xff01; 信息系统项目管理师上半年考、系统集成项目管理工程师下半年考。 很多科目一年只考一次&#xff01;&#xff01;&#xff01; 报名时间&#xff1a; 上半年&#xff1a;2024年3月18日开始&#xff0c;…

蓝桥杯备赛 day2 | 4. 付账问题 5. 数字三角形

付账问题&#xff0c;关键是要了解整型的范围&#xff0c;确定获取输入数据的变量类型 需要注意的是int的十进制范围-32768 ~ 32767&#xff0c;那么我们可以知道&#xff0c;人数n是可以用int来装的&#xff0c;需付款数S应该是long long&#xff0c;获取的每个人初始钱数也应…

uniapp+vue3+vites使用lime-echart问题记录

问题记录 1.vue3使用echarts,H5和微信小程序兼容问题 1.vue3使用echarts,H5和微信小程序兼容问题 问题描述&#xff0c;正常使用echarts&#xff0c;H5正常&#xff0c;小程序报错 报错信息如下 解决方案&#xff1a; 注意要点一&#xff1a;vue3需要使用esm文件 地址&#x…

JVM类加载机制以及双亲委派模型的介绍

目录 1.类加载介绍 2.具体步骤 2.1加载 2.2验证 2.3准备 2.4解析 2.5初始化 3.加载过程中的策略-双亲委派模型 1.类加载介绍 类加载,指的是Java进程在运行的时候,把.class文件从硬盘读取到内存,并进行一系列校验解析的过程. .class文件>类对象.硬盘>内村 类加载…

IDEA切换JDK版本超详细步骤

&#x1f600; IDEA切换JDK版本详细教程&#xff0c;全网步骤最详细&#xff0c;实测可用。 文章目录 第一步、选择SDKs切换SDK版本&#xff1a;第二步、选择Modules切换Sources和Dependencies版本&#xff1a;第三步、选择Project切换SDK和Language Level版本&#xff1a;第四…