中间件_RabbitMQ五种消息模型

news2024/11/24 7:40:32

文章目录

  • 1.简单消息队列模型
  • 2.Work工作队列模型
  • 3.发布订阅模型
    • 3.1.Fanout广播
    • 3.2.Direct路由
    • 3.3.Topics通配符

RabbitMQ官方文档
RabbitMQ 提供了5种常用消息模型。但是其实3、4、5这三种都属于订阅模型,只不过进行路由的方式不同。
在这里插入图片描述
在这里插入图片描述

1.简单消息队列模型

简单消息队列官方文档

1、创建简单消息队列

在这里插入图片描述

2、导入依赖

    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

3、编写生产者测试类SpringAmqpTest,并利用 RabbitTemplate 实现消息发送

@SpringBootTest
public class SpringAMQPTest {
	//SpringAMQP提供的三个功能之一:封装了 RabbitTemplate 工具,用于发送消息 (生产者)
    @Autowired
    private RabbitTemplate template;

    @Test
    void test(){
    	//利用RabbitTemplate提供的方法向指定队列发送消息
        template.convertAndSend("simple.queue","Hello SpringAQMP!");
    }
}

4、编写消费者,监听队列消息

@Component
public class MessageListener {
	  /**
     * SpringAMQP提供的三个功能之二:基于注解的监听器模式,异步接收消息 (消费者)
     * @RabbitListener是SpringAMQP提供的监听消息队列的注解
     * @param message
     */
    @RabbitListener(queues = "simple.queue")
    public void basicQueueListener(String message) {
        System.out.println("消费者接收到消息:" + message);
    }
}

在这里插入图片描述

5、编写生产者和消费者的application.yml文件

spring:
  rabbitmq:
    host: 192.168.6.131
    port: 5672
    # 虚拟主机
    virtual-host: /
    username: rabbitmq
    password: 123456

在这里插入图片描述

6、测试

运行生产者代码后,simple.queue 队列中产生了一条待消费的消息。
在这里插入图片描述
运行消费者代码后,队列中的消息被消费
在这里插入图片描述
在这里插入图片描述

2.Work工作队列模型

work工作队列官方文档

1、 创建 work.queue 队列

在这里插入图片描述

2、创建生产者测试类

    @Test
    void testWorkQueue(){
        String queueName = "work.queue";
        String message = "Hello SpringAQMP-";
        for (int i = 0; i < 20; i++) {
            template.convertAndSend(queueName,message+i);
        }
    }

3、创建消费者测试类

    @RabbitListener(queues = "work.queue")
    public void workQueueListener01(String message) throws InterruptedException {
        System.out.println("消费者01接收到消息:" + message + " - " + LocalTime.now());
        Thread.sleep(20);
    }
    @SneakyThrows
    @RabbitListener(queues = "work.queue")
    public void workQueueListener02(String message){
        System.out.println("消费者02接收到消息:" + message + " - " + LocalTime.now());

4、修改消费者的application.yml

正常情况下每个消费者要消费的消息数量是一样的。消息是平均分配给每个消费者,并没有考虑到消费者的处理能力。这样显然不合理,因此修改消费者的配置文件使得每个消费者按照能力顺序处理信息

spring:
  rabbitmq:
    listener:
      simple: # 简单队列和work队列的配置
        prefetch: 1 # 每次只能获取一条消息,处理完成才获取下一条消息

5、测试

运行生产者和消费者类,两个消费者收到的同一个队列中的消息肯定是不一样的。
在这里插入图片描述

3.发布订阅模型

在发布订阅模型中,多了一个exchange角色,而且过程略有变化:

  • producer:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)

  • exchange:交换机,一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于exchange的类型。exchange 有以下3种类型:

    • fanout:广播,将消息交给所有绑定到交换机的队列
    • direct:定向,把消息交给符合指定 routing key 的队列
    • topic:通配符,把消息交给符合 routing pattern 的队列
  • consumer:消费者,订阅队列

  • queue:消息队列,接收消息、缓存消息。

exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与 exchange 绑定,或者没有符合路由规则的队列,那么消息会被丢弃!
在这里插入图片描述

3.1.Fanout广播

Fanout广播官方文档
在这里插入图片描述

在广播模式下,消息发送流程是这样的:

  • 可以有多个消费者

  • 每个消费者有自己的queue(队列)

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

  • 生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。

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

  • 队列的消费者都能拿到消息。实现一条消息被多个消费者消费

  • 使用内置的 amq.fanout 交换机
    在这里插入图片描述

  • 两个队列不用手动创建,是在下面

1、创建生产者测试类

@Test
void testFanoutExchange() {
    rabbitTemplate.convertAndSend("amq.fanout", "", "Hello amq.fanout");
}

2、创建消费者测试类


@Component
public class SpringRabbitListener {
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "fanout.queue01"),
            exchange = @Exchange(name = "amq.fanout", type = ExchangeTypes.FANOUT)
    ))
    public void fanoutQueueListener01(String message) {
        System.out.println("消费者01接收到fanout.queue01的消息:" + message);
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "fanout.queue02"),//使用@Queue(name = "fanout.queue01")RabbitMQ自动生成队列
            exchange = @Exchange(name = "amq.fanout", type = ExchangeTypes.FANOUT)
    ))
    public void fanoutQueueListener02(String message) {
        System.out.println("消费者02接收到fanout.queue02的消息:" + message);
    }
}

3、测试

运行生产者和消费者
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.2.Direct路由

Direct路由官方文档
在这里插入图片描述
在 Fanout 模式中,一条消息,会被所有订阅的队列都消费。但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到 direct 类型的 exchange。

Direct模型下:

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

1、创建生产者测试类

@Test
void testDirectExchange() {
    rabbitTemplate.convertAndSend("amq.direct", "save", "新增通知");
    rabbitTemplate.convertAndSend("amq.direct", "delete", "删除通知");
}

2、创建消费者测试类

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue01"),
    exchange = @Exchange(name = "amq.direct", type = ExchangeTypes.DIRECT),
    key = {"save"}
))
// 处理新增的业务
public void directQueueListener01(String message){
    System.out.println("消费者01接收到direct.queue01的消息:" + message);
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue02"),
    exchange = @Exchange(name = "amq.direct", type = ExchangeTypes.DIRECT),
    key = {"delete"}
))
// 处理删除的业务
public void directQueueListener02(String message){
    System.out.println("消费者02接收到direct.queue02的消息:" + message);
}

3、测试

运行生产者和消费者测试类
在这里插入图片描述
在这里插入图片描述

3.3.Topics通配符

Topics通配符官方文档
在这里插入图片描述
Topics 类型的 Exchange 与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。

不同的是 Topic类型的 Exchange 可以让队列在绑定 Routingkey 的时候使用通配符

通配符规则:

  • #:匹配一个或多个单词

  • *:匹配一个单词

举例:

  • user.#:能够匹配 user.add 或者 user.detail.add

  • user.*:只能匹配 user.add

1、创建生产者测试类

@Test
public void testTopicExchange() {
    rabbitTemplate.convertAndSend("amq.topic", "user.add", "新增用户通知");
    rabbitTemplate.convertAndSend("amq.topic", "user.update", "更新户通知");
    rabbitTemplate.convertAndSend("amq.topic", "dept.add", "新增部门通知");
    rabbitTemplate.convertAndSend("amq.topic", "dept.update", "更新部门通知");
}

2、创建消费者测试类

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue01"),
    exchange = @Exchange(name = "amq.topic", type = ExchangeTypes.TOPIC),
    key = "user.*"
))
public void topicQueueListener01(String message){
    System.out.println("消费者01接收到topic.queue01的消息:" + message);
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue02"),
    exchange = @Exchange(name = "amq.topic", type = ExchangeTypes.TOPIC),
    key = "dept.*"
))
public void topicQueueListener02(String message){
    System.out.println("消费者02接收到topic.queue02的消息:" + message);
}

3、测试

运行生产者和消费者测试类
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

C语言入门篇——编译篇

目录 1、程序环境 1.1 ANSI C 标准 1.2程序的翻译环境和执行环境 1.3运行环境 2、预处理详解 2.1、预定义符号 2.2、#define 2.2.1#define定义表示符 2.2.2#define定义宏 2.2.3#define替换规则 2.4#和## 2.2.5带副作用的宏参数 2.2.6宏和函数对比 3、#undef 4、…

项目1:登录功能设计

需求 后端接口设计MySQL表常用功能模块 后端总和前端实现方案 home页面 需求 实现一个登录功能 实现的功能 注册(邮箱注册) 登录(邮箱密码) 重置密码 查看操作记录(登录, 注册, 重置密码, 登出. 都算操作) 登出 后端接口设计 1. 人机验证 只要下面出现 人机验证 的功能都需要使…

容器化:MySQL

1 缘起 开启容器化之路。 2 容器化MySQL 2.1 查看MySQL镜像 docker search mysql2.2 指定版本&#xff1a;5.7.30 通过官网查看&#xff1a;https://hub.docker.com/ docker pull mysql:5.7.302.3 路径挂载 容器路径挂载到宿主机。 新建宿主机路径 mkdir -p /home/xind…

ElasticSearch-索引和文档的创建修改删除

目录 一、创建索引 二、查看索引 三、索引是否存在 四、删除索引 五、创建文档 六、查看文档 七、更新文档 八、文档是否存在 九、删除文档 一、创建索引 # 创建一个默认的索引&#xff0c;默认是标准分词器的索引 PUT /es_db2# 创建一个默认为ik分词器的索引 PUT /e…

十万条数据,后端不分页咋办!(如何优化长列表渲染)

十万条数据&#xff0c;后端不分页咋办&#xff01;&#xff08;如何优化长列表渲染&#xff09; 长列表是什么&#xff1f; 我们通常把一组数量级很大的数据叫做长列表&#xff0c;比如渲染一组上千条的数据&#xff0c;我们以数组的形式拿到这些信息&#xff0c;然后遍历渲…

Rust快速安装

Rust依赖C编译&#xff0c;Rust官方推荐的安装方式是利用VisualSudio安装C环境&#xff0c;VisualStuidio用过的都懂&#xff0c;庞大无比、卡顿、下载还贼慢(我当时装了一上午好像)&#xff0c;因此我们通过其它方式配置C 安装C环境 下载MinGW 64 win32 seh Mingw官网&…

Java的并发集合框架

文章目录 一、并发集合框架1. 简介2. 接口Iterable2. 接口Collection3. 接口List4. 接口Set5. 接口Queue6. Deque 二、非阻塞队列1. 概念2. ConcurrentHashMap使用&#xff08;1&#xff09;简介&#xff08;2&#xff09;验证HashMap不是线程安全的&#xff08;3&#xff09;验…

ld文件中指定变量在flash中的地址定义

本文说的是在gcc环境中&#xff0c;Keil或IAR可能有自己的使用方法。 我们在定义变量时&#xff0c;有时候需要把变量定义放到flash中的固定位置或区域&#xff0c;此时需要修改工程中的链接文件&#xff08;link file&#xff0c;ld文件&#xff09;。 方法一 修改ld文件中的…

软件IIC通信以及源码解析(如何使用)

以对读取MPU6050为例&#xff0c;解析如何采用IIC通信源码。 IIC的的通信&#xff0c;通常三种用途读写。分为&#xff1a; 1&#xff1a; 2&#xff1a; 3&#xff1a; 注&#xff1a;其中最常用的就是1和3了。 对1进行讲解&#xff1a; 指定地址写&#xff0c;通常用作对状…

【网络】- TCP/IP四层(五层)协议 - 网际层(网络层) - IP地址

目录 一、概述 二、IP地址的定义 三、IP地址由网络和主机两部分标识组成 一、概述 上篇文章简单介绍了网际协议IP。网际协议 IP 大致分为三大作用模块&#xff0c; ①IP寻址、 ②路由&#xff08;最终节点为止的转发&#xff09; 、③IP分包与组包。 这篇文章主要详细介绍IP地址…

【HTTP协议详解】

目录 1.什么是http2.抓包工具2.1 抓包工具2.2 抓包原理 3.Http协议格式3.1Http请求报文3.2Http响应报文的格式 4.请求报文格式4.1 报文首行4.2 请求报文header 5. 响应报文格式6.构造Http请求7.Https协议7.1 对称密钥7.2 非对称密钥7.3 证书 1.什么是http HTTP全称为“超文本协…

《MySQL是怎么运行的》阅读分享

mysql运行的整体架构简介 Mysql是由两部分构成&#xff0c;一部分是服务器程序&#xff0c;一部分是客户端程序。 服务器程序又包括两部分&#xff1a; 第一部分server层包括连接器、查询缓存、分析器、优化器、执行器等。涵盖 MySQL 的大多数核心服务功能&#xff0c;以及所有…

LeetCode:738.单调递增的数字 714.买卖股票的最佳时机含手续费 968.监控二叉树

738.单调递增的数字 题目 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 贪心 class Solution {public int monotoneIncrea…

数据结构——单链表(C语言)

在这⼀条⼗分漫长的路上&#xff0c;我⾛过阳关⼤道&#xff0c;也⾛过独⽊⼩桥。路旁有深⼭⼤泽&#xff0c;也有平坡宜⼈&#xff1b;有杏花春⾬&#xff0c;也有塞北秋风&#xff1b;有⼭重⽔复&#xff0c;也有柳暗花明&#xff1b;有迷途知返&#xff0c;也有绝处逢⽣。—…

[论文分享] Function Representations for Binary Similarity

Function Representations for Binary Similarity [TDSC 2022] Luca Massarelli , Giuseppe Antonio Di Luna, Fabio Petroni, Leonardo Querzoni, and Roberto Baldoni 二进制相似度问题在于仅考虑两个函数的编译形式来判断它们是否相似。近年来&#xff0c;计算二进制相似度…

【2023 · CANN训练营第一季】进阶班 Atlas 200I DK 智能小车

1 智能小车三维结构设计 1.1 基本模块 坚固酷炫结构模块运动控制模块超声波传感器模块摄像头视觉模块其他传感器模块 1.2 结构设计基本原则 从零开始设计并搭建智能小车&#xff0c;在满足外观要求的基础上&#xff0c;要满足小车运转过程中的运动干涉率为O&#xff0c;并且…

玩转ChatGPT:Show Me插件尝鲜

一、写在前面 之前&#xff0c;不少人问我GPT能否画技术路线图&#xff0c;然后看到了这个插件&#xff1a;Show Me&#xff1a; 简单问GPT这个插件的使用方法&#xff1a; 二、尝鲜过程 &#xff08;1&#xff09;用TA提供的例子试一试&#xff1a; 咒语&#xff1a;请用图…

009、实例连接访问控制

实例连接访问控制 1、实例连接访问控制概述2、pg_hba.conf文件3、名单格式4、pg_hba.conf 示例:5、当有重复或者冲突的时候1、实例连接访问控制概述 • 实例访问控制就像是一道防火墙,用它来控制来自于不同主机、不同用户是否 允许访问指定的数据库、以及验证方式。 2、pg…

【Tcp通信服务器流程】

TCP通信流程 1、服务器端&#xff08;被动接收连接的角色&#xff09; &#xff08;1&#xff09;创建一个用于监听的套接字 - 监听&#xff1a;监听有客户端的连接 - 套接字&#xff1a;这个套接字其实就是一个文件描述符 &#xff08;2&#xff09;将这个监听文件描述符和…

TextCNN文本分类

本文主要介绍TextCNN文本分类&#xff0c;主要从TextCNN的原理的Pytorch实现来逐步讲解。主要思想来自论文《Convolutional Neural Networks for Sentence Classification&#xff08;EMNLP2014&#xff09; 论文连接&#xff1a;[1408.5882] Convolutional Neural Networks f…