当前位置: 首页 > news >正文

RabbitMQ02-RebbitMQ简介及交换器

一. AMQP协议

什么是AMQP协议

AMQP(Advanced Message Queuing Protocol,高级消息队列协议):它是进程之间传递异步消息的网络协议

AMQP工作过程

发布者通过发布消息,通过交换机,交换机根据路由规则将收到的消息分发交换机绑定的下消息队列,最后AMQP代理将消息推送给订阅了此队列的消费者
或消费者按照需求自行获取。

二. RabbitMQ简介

RabbitMQ是通过Erlang语言基于AMQP协议编写的消息中间件,它在分布式系统中可以解应用耦合、流量削峰、异步消息等问题。它有两个特性
队列排队和异步

  1. 应用解耦:多个个应用程序之间可通过RabbitMQ作为媒介,两个应用不再粘连,实现解耦;
  2. 异步消息:多个应用可通过RabbitMQ进行消息传递;
  3. 流量削峰:在高并发情况下,可以通过RabbitMQ的队列特性实现流量削峰;
  4. 应用场景:
    1. 应用到队列特性的应用场景: 排序算法、秒杀活动。
    2. 应用到异步特性的应用场景: 消息分发、异步处理、数据同步、处理耗时任务。

三.springBoot整合RabbitMQ

生产者端发送消息

pom文件

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

yml文件

spring:application:name: producerrabbitmq:host: xxxusername: adminpassword: admin

配置类,需要返回一个Queue,org.springframework.amqp.core.Queue下的Queue对象

@Configuration
public class RabbitMqConfig {@Beanprotected Queue queue(){return new Queue("myQueue");}
}

使用RabbitMQ发送消息,注入AmqpTemplate,调用convertAndSend()方法

class ProducerApplicationTests {@Autowiredprivate AmqpTemplate amqpTemplate;@Testvoid send() {for (int i = 0; i < 10; i++) {amqpTemplate.convertAndSend("myQueue","这是发送的消息");System.out.println("发送成功!");}}}

消费端接收消息

配置同生产端,不需要配置RabbitMqConfig,接收消息时只需要使用注解RabbitMqConfig,queues属性绑定相应的队列即可。

@Component
public class ReceiveService {@RabbitListener(queues = "myQueue")public void test01(String msg){System.out.println("接收到消息1" + msg);}@RabbitListener(queues = "myQueue")public void test02(String msg){System.out.println("接收到消息2" + msg);}@RabbitListener(queues = "myQueue")public void test03(String msg){System.out.println("接收到消息3" + msg);}
}

四.交换器(四种)

Direct Exchange:直连交换器

它是RabbitMQ的默认交换器,给指定队列发消息,绑定该消息队列的消费者一次获取消息

实战:

/** 生产者发送消息,发送10个消息*/
@SpringBootTest
class ProducerApplicationTests {@Autowiredprivate AmqpTemplate amqpTemplate;@Testvoid send() {for (int i = 0; i < 10; i++) {amqpTemplate.convertAndSend("myQueue","这是发送的消息");System.out.println("发送成功!");}}}
/** 接收消息*/
@Component
public class ReceiveService {@RabbitListener(queues = "myQueue")public void test01(String msg){System.out.println("接收到消息1" + msg);}@RabbitListener(queues = "myQueue")public void test02(String msg){System.out.println("接收到消息2" + msg);}@RabbitListener(queues = "myQueue")public void test03(String msg){System.out.println("接收到消息3" + msg);}
}

结果:可以看到1、2、3依次接收消息

接收到消息1这是发送的消息
接收到消息2这是发送的消息
接收到消息3这是发送的消息
接收到消息2这是发送的消息
接收到消息3这是发送的消息
接收到消息1这是发送的消息
接收到消息3这是发送的消息
接收到消息1这是发送的消息
接收到消息2这是发送的消息
接收到消息1这是发送的消息

Fanout Exchange:扇形交换器

绑定该交换器的所有队列都可以接收到消息,扇形交换机将消息广播到所有与之绑定的队列。无论消息的路由键是什么,扇形交换机都会将消息发送到所有绑定的队列中。这种类型的交换机常用于实现发布-订阅模式,将消息广播给多个消费者。

实战

/** 绑定*/
/** Fanout Exchange*/
@Bean
public Queue FanoutExchangeQueue1(){return new Queue("fanoutExchangeQueue1");}
@Bean
public Queue FanoutExchangeQueue2(){return new Queue("fanoutExchangeQueue2");}
@Bean
public FanoutExchange fanoutExchange(){return new FanoutExchange("amq.fanout");}
@Bean
public Binding  FanoutExchangeBinding1(Queue FanoutExchangeQueue1,FanoutExchange fanoutExchange){return BindingBuilder.bind(FanoutExchangeQueue1).to(fanoutExchange);}
@Bean
public Binding  FanoutExchangeBinding2(Queue FanoutExchangeQueue2,FanoutExchange fanoutExchange){return BindingBuilder.bind(FanoutExchangeQueue2).to(fanoutExchange);}
/** 生产者发送消息*/@Testvoid sendByFanoutExchange() {amqpTemplate.convertAndSend("amq.fanout","key","这是发送到的消息");System.out.println("发送成功!");}
    /** 消费者 Direct Exchange*/@RabbitListener(queues = "fanoutExchangeQueue1")public void test04(String msg){System.out.println("接收到消息4" + msg);}@RabbitListener(queues = "fanoutExchangeQueue2")public void test05(String msg){System.out.println("接收到消息5" + msg);}

结果:每一个绑定到Fanout Exchange上的队列都可以接收到消息

接收到消息4这是发送到的消息
接收到消息5这是发送到的消息

Topic Exchange:主题交换器

允许在路由键中设置匹配规则:'*‘代表一个字母两个’.'之间的内容;‘#’代表0或多个字符;

实战

    /** 绑定*/@Beanpublic Queue topicExchangeQueue1(){return new Queue("topicExchangeQueue1");}@Beanpublic Queue topicExchangeQueue2(){return new Queue("topicExchangeQueue2");}@Beanpublic TopicExchange topicExchange(){return new TopicExchange("amq.topic");}@Beanpublic Binding TopicExchangeToQueue1(Queue topicExchangeQueue1,TopicExchange topicExchange){return BindingBuilder.bind(topicExchangeQueue1).to(topicExchange).with("com.shaoby.*");}@Beanpublic Binding TopicExchangeToQueue2(Queue topicExchangeQueue2,TopicExchange topicExchange){return BindingBuilder.bind(topicExchangeQueue2).to(topicExchange).with("com.shaoby.test.#");}
    /**生产者发送消息*//** key为com.shaoby.test*/@Testvoid sendByTopicExchange() {amqpTemplate.convertAndSend("amq.topic","com.shaoby.test","这是发送到的消息");System.out.println("发送成功!");}/** key为com.shaoby.test.a*/@Testvoid sendByTopicExchange() {amqpTemplate.convertAndSend("amq.topic","com.shaoby.test.a.b","这是发送到的消息");System.out.println("发送成功!");}
    /**消费者接收消息*//**Topic Exchange*/@RabbitListener(queues = "topicExchangeQueue1")public void test06(String msg){System.out.println("接收到消息6" + msg);}@RabbitListener(queues = "topicExchangeQueue2")public void test07(String msg){System.out.println("接收到消息7" + msg);}

结果:

路由key为com.shaoby.test都能接收到消息,com.shaoby.test.a.b只有topicExchangeQueue2能接收到消息

Header Exchange:首部交换器

绑定:

/** Header Exchange*/
@Bean
public Queue headerExchangeQueue1(){return new Queue("headerExchangeQueue1");}@Bean
public Queue headerExchangeQueue2(){return new Queue("headerExchangeQueue2");}
@Bean
public HeadersExchange headersExchange(){return new HeadersExchange("amp.header");}
@Bean
public Binding headExchangeToQueue1(Queue headerExchangeQueue1,HeadersExchange headersExchange){HashMap<String, Object> map = new HashMap<>();map.put("type","OK");map.put("status","200");return BindingBuilder.bind(headerExchangeQueue1).to(headersExchange).whereAll(map).match();}
@Bean
public Binding headExchangeToQueue2(Queue headerExchangeQueue2,HeadersExchange headersExchange){HashMap<String, Object> map = new HashMap<>();map.put("type","error");map.put("status","500");return BindingBuilder.bind(headerExchangeQueue2).to(headersExchange).whereAll(map).match();}
/** 生产者发送消息*/
@Testvoid sendByHeadExchange() {Map<String, Object> headers = new HashMap<>();headers.put("type","OK");headers.put("status","200");String message = "这是发送到的消息";MessageProperties messageProperties = new MessageProperties();headers.forEach(messageProperties::setHeader);Message msg = new Message(message.getBytes(), messageProperties);amqpTemplate.convertAndSend("amp.header",null, msg);System.out.println("发送成功!");}
    @RabbitListener(queues = "headerExchangeQueue1")public void test08(Message msg){System.out.println("接收到消息8:" + msg.toString());}@RabbitListener(queues = "headerExchangeQueue2")public void test09(Message msg){System.out.println("接收到消息9:" + msg.toString());}

结果:只有匹配上header才能收到消息

接收到消息8:(Body:'[B@a7b38a8(byte[24])' MessageProperties [headers={type=OK, status=200}, contentType=application/octet-stream, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=amp.header, receivedRoutingKey=, deliveryTag=2, consumerTag=amq.ctag-1WTdKW4n_rAEdJUosQD7bg, consumerQueue=headerExchangeQueue1])

相关文章:

RabbitMQ02-RebbitMQ简介及交换器

一. AMQP协议 什么是AMQP协议 AMQP(Advanced Message Queuing Protocol,高级消息队列协议):它是进程之间传递异步消息的网络协议 AMQP工作过程 发布者通过发布消息&#xff0c;通过交换机&#xff0c;交换机根据路由规则将收到的消息分发交换机绑定的下消息队列&#xff0c;最…...

Matlab自学笔记三十:元胞数组的修改、添加、删除和连接

1.说明 元胞数组的子数组或元素也是元胞型的&#xff0c;其元素内容&#xff08;值&#xff09;是本身类型&#xff0c;因此&#xff0c;在添、删、改和连接处理时&#xff0c;必须明确每个元素的值的类型和大小&#xff0c;否则&#xff0c;编程报错是不可避免的了。看本文前…...

【LeetCode】数组——双指针法

1 双指针法 1.1 介绍 双指针法是一种常用的算法技巧&#xff0c;通常用于处理数组或链表中的问题。它使用两个指针&#xff0c;通常一个从数组的开始位置遍历&#xff0c;另一个从数组的末尾位置开始遍历&#xff0c;根据问题的不同&#xff0c;这两个指针可以同时移动&#…...

react 低代码平台方案汇总

React作为当前最流行的前端框架之一&#xff0c;其生态系统中孕育了多种低代码平台方案&#xff0c;旨在加速应用开发过程。以下是几款基于React的低代码平台或工具&#xff0c;它们通过可视化构建、预制组件、数据绑定等功能&#xff0c;帮助开发者快速构建应用程序&#xff1…...

oss对象上传文件设置格式

PostMapping("upload")ApiOperation(value "上传文件")public Result<UploadDTO> upload(RequestParam("file") MultipartFile file) throws Exception {if (file.isEmpty()) {return new Result<UploadDTO>().error(ModuleErrorCo…...

【Linux学习】进程

下面是有关进程的相关介绍&#xff0c;希望对你有所帮助&#xff01; 小海编程心语录-CSDN博客 目录 1. 进程的概念 1.1 进程与程序 1.2 进程号 2. 进程的状态 2.1 fork创建子进程 2.2 父子进程间的文件共享 3. 进程的诞生与终止 3.1 进程的诞生 3.2 进程的终止 1. 进…...

Python数据分析实验四:数据分析综合应用开发

目录 一、实验目的与要求二、主要实验过程1、加载数据集2、数据预处理3、划分数据集4、创建模型估计器5、模型拟合6、模型性能评估 三、主要程序清单和运行结果四、实验体会 一、实验目的与要求 1、目的&#xff1a; 综合运用所学知识&#xff0c;选取有实际背景的应用问题进行…...

基于51单片机的盆栽自动浇花系统

一.硬件方案 工作原理是湿度传感器将采集到的数据直接传送到ADC0832的IN端作为输入的模拟信号。选用湿度传感器和AD转换&#xff0c;电路内部包含有湿度采集、AD转换、单片机译码显示等功能。单片机需要采集数据时&#xff0c;发出指令启动A/D转换器工作&#xff0c;ADC0832根…...

SpirngMVC框架学习笔记(一):SpringMVC基本介绍

1 SpringMVC 特点&概述 SpringMVC 从易用性&#xff0c;效率上 比曾经流行的 Struts2 更好 SpringMVC 是 WEB 层框架&#xff0c;接管了 Web 层组件, 比如控制器, 视图, 视图解析, 返回给用户的数据格式, 同时支持 MVC 的开发模式/开发架构SpringMVC 通过注解&#xff0c;…...

实现信号发生控制

1. 信号发生器的基本原理 信号发生器是一种能够产生特定波形和频率的电子设备&#xff0c;常用于模拟信号的产生和测试。 信号发生器的基本原理 信号发生器的工作原理基于不同的技术&#xff0c;但最常见的类型包括模拟信号发生器和数字信号发生器&#xff08;DDS&#xff0…...

二叉树基于队列实现的操作详解

一、队列知识补充 有关队列的知识请详见博主的另一篇博客&#xff1a;http://t.csdnimg.cn/3PwO4 本文仅仅附上需要的队列操作供读者参考 //结构体定义 typedef struct BinaryTreeNode* QDataType;typedef struct QueueNode {struct QueueNode* next;QDataType val; }QNode;…...

LabVIEW常用开发架构有哪些

LabVIEW常用开发架构有多种&#xff0c;每种架构都有其独特的特点和适用场合。以下是几种常用的开发架构及其特点和适用场合&#xff1a; 1. 单循环架构 特点&#xff1a; 简单易用适用于小型应用将所有代码放在一个循环中 适用场合&#xff1a; 简单的数据采集和处理任务…...

告别 Dart 中的 Future.wait([])

作为 Dart 开发人员&#xff0c;我们对异步编程和 Futures 的强大功能并不陌生。过去&#xff0c;当我们需要同时等待多个 future 时&#xff0c;我们依赖 Future.wait([]) 方法&#xff0c;该方法返回一个 List<T>。然而&#xff0c;这种方法有一个显着的缺点&#xff1…...

Cisco ASA防火墙抓包命令Capture

在日常运维中&#xff0c;遇到故障时经常需要在ASA上抓包进行诊断。 从抓包中可以看到流量是否经过ASA流量是否被ASA放行&#xff0c;或block&#xff0c;匹配的哪一条ACL capture在Firepower平台上同样适用&#xff0c;无论跑的是ASA还是FTD 1 抓包命令 capture 2 配置方…...

Linux网络编程:HTTP协议

前言&#xff1a; 我们知道OSI模型上层分为应用层、会话层和表示层&#xff0c;我们接下来要讲的是主流的应用层协议HTTP&#xff0c;为什么需要这个协议呢&#xff0c;因为在应用层由于操作系统的不同、开发人员使用的语言类型不同&#xff0c;当我们在传输结构化数据时&…...

HTTP 协议中 GET 和 POST 有什么区别?分别适用于什么场景?

HTTP 协议中 GET 和 POST 是两种常用的请求方法&#xff0c;它们的区别如下: 1. 参数传递方式不同 GET 请求参数是在 URL 中以键值对的形式传递的&#xff0c;例如:http://www.example.com/&#xff1f;key1value1&k ey2value2。 而 POST 请求参数是在请求体中以键值对的…...

talib 安装

这里写自定义目录标题 talib 安装出错 talib 安装出错 https://github.com/cgohlke/talib-build/releases 这里找到轮子 直接装。...

echarts-树图、关系图、桑基图、日历图

树图 树图主要用来表达关系结构。 树图的端点也收symbol的调节 树图的特有属性&#xff1a; 树图的方向&#xff1a; layout、orient子节点收起展开&#xff1a;initialTreeDepth、expandAndCollapse叶子节点设置&#xff1a; leaves操作设置&#xff1a;roam线条&#xff1a…...

04Django项目基本运行逻辑及模板资源套用

对应视频链接点击直达 Django项目用户管理及模板资源 对应视频链接点击直达1.基本运行逻辑Django的基本运行路线&#xff1a;视图views.py中的 纯操作、数据返回、页面渲染 2.模版套用1.寻找一个好的模版2.模板部署--修改适配联动 OVER&#xff0c;不会有人不会吧不会的加Q1394…...

安徽大学数学科学学院教授陈昌昊

男&#xff0c;本&#xff08;2005-2009&#xff09;、硕&#xff08;2009-2012&#xff09;学位都在湖北大学获得&#xff0c;博士学位在芬兰获得&#xff08;2012-2016&#xff09;&#xff0c;博士后分别在澳大利亚&#xff08;2016-2019&#xff09;、香港&#xff08;2020…...

com.alibaba.fastjson.JSONObject循环给同一对象赋值会出现“$ref“:“$[0]“现象问题

1、问题描述 有些场景下&#xff0c;我们会选择用JSONObject代替Map来处理业务逻辑&#xff0c;但是使用JSONObject时有一个需要注意的地方&#xff1a;在处理JSONObject对象时&#xff0c;引用的com.alibaba.fastjson.JSONObject&#xff0c;在一个集合中&#xff0c;循环给这…...

【C++】详解AVL树——平衡二叉搜索树

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 目录 二叉搜索树 AVL树概述 平衡因子 旋转情况分类 左单旋 右单旋 左右双旋 右左双旋 AVL树节点设计 AVL树设计 详解单旋 左单旋 右单旋 详解双旋 左右双旋 平衡因子情况如…...

《计算机网络微课堂》2-2 物理层下面的传输媒体

请大家注意&#xff0c;传输媒体不属于计算机网络体系结构的任何一层&#xff0c;如果非要将它添加到体系结构中&#xff0c;‍‍那只能将其放在物理层之下。 传输媒体可分为两类&#xff1a;一类是导引型传输媒体&#xff0c;‍‍另一类是非导引型传输媒体。 在导引型传输媒体…...

【算法设计与分析】基于Go语言实现动态规划法解决TSP问题

本文针对于最近正在学习的Go语言&#xff0c;以及算法课实验所需内容进行Coding&#xff0c;一举两得&#xff01; 一、前言 由于这个实验不要求向之前的实验一样做到那种连线的可视化&#xff0c;故可以用图形界面不那么好实现的语言进行编写&#xff0c;考虑到Go语言的…...

Golang单元测试

文章目录 传统测试方法基本介绍主要缺点 单元测试基本介绍测试函数基准测试示例函数 传统测试方法 基本介绍 基本介绍 代码测试是软件开发中的一项重要实践&#xff0c;用于验证代码的正确性、可靠性和预期行为。通过代码测试&#xff0c;开发者可以发现和修复潜在的错误、确保…...

mac下安装airflow

背景&#xff1a;因为用的是Mac的M芯片的电脑&#xff0c;安装很多东西都经常报错&#xff0c;最近在研究怎么把大数据集群上的crontab下的任务都配置到一个可视化工具中&#xff0c;发现airflow好像是个不错的选择&#xff0c;然后就研究怎么先安装使用起来&#xff0c;后面再…...

二进制中1的个数c++

题目描述 计算鸭给定一个十进制非负整数 NN&#xff0c;求其对应 22 进制数中 11 的个数。 输入 输入包含一行&#xff0c;包含一个非负整数 NN。(N < 10^9) 输出 输出一行&#xff0c;包含一个整数&#xff0c;表示 NN 的 22 进制表示中 11 的个数。 样例输入 100 …...

【面试干货】数据库乐观锁,悲观锁的区别,怎么实现

【面试干货】数据库乐观锁&#xff0c;悲观锁的区别&#xff0c;怎么实现 1、乐观锁&#xff0c;悲观锁的区别2、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、乐观锁&#xff0c;悲观锁的区别 悲观锁&#xff08;Pessimistic Lo…...

移动端仪表盘,支持更多组件

05/22 主要更新模块概览 定位函数 快捷筛选 轨迹图表 时间组件 01 表单管理 1.1 【表单组件】- 表单关联新增支持自定义按钮样式 说明&#xff1a; 表单关联-关联数据按钮&#xff0c;原仅支持默认按钮样式&#xff0c;现增加关联数据按钮自定义功能&#xff0c;满…...

科技产业园3D探秘:未来科技之城的奇幻之旅

在数字时代的浪潮中&#xff0c;科技产业园区成为了推动城市经济发展、科技创新的重要引擎。 当我们打开科技产业园的3D可视化模型&#xff0c;仿佛穿越时空&#xff0c;来到了一个充满奇幻色彩的科技世界。在这里&#xff0c;高楼大厦鳞次栉比&#xff0c;绿色植被点缀其间&am…...