springboot与rabbitmq的整合【演示5种基本交换机】

前言
👏作者简介:我是笑霸final,一名热爱技术的在校学生。
📝个人主页:个人主页1 || 笑霸final的主页2
📕系列专栏:后端专栏
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

话不多说 直接开干

目录

  • 一 导入maven坐标与配置
  • 二、直连交换机direct exchange
    • 2.1配置类QueueConfig
    • 2.2消息提供者
    • 2.2消息消费者
    • 2.3测试类
  • 三、默认交换机default exchange
    • 3.1配置类和消息提供者
    • 3.2消息消费者
    • 3.3测试结果
  • 四、扇型交换机fanout exchange
    • 4.1配置类
    • 4.2消息提供者
    • 4.3消息消费者
    • 4.4测试类
  • 五、主题交换机topic exchanges
    • 5.1配置类
    • 5.2消息提供者
    • 5.3消息消费者
    • 5.4测试
  • 六、头交换机 headers exchange
    • 6.1配置类
    • 6.2创建消息提供者
    • 6.3消息消费者
    • 6、4测试结果

一 导入maven坐标与配置

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

基础配置文件

spring:rabbitmq:username: 你的用户名password: 你的密码host: rabbitmq安装的主机的 ip地址port: 5672 #端口号

二、直连交换机direct exchange

直连型交换机(direct exchange)是根据消息携带的路由键(routing key)将消息投递给对应队列的。

  • 将一个队列 绑定到 某个交换机上,同时赋予该绑定一个路由键(routing key)
  • 当一个携带着路由键为routingKey01的消息被发送给直连交换机时,交换机会把它路由给绑定值同样为routingKey01的队列。

直连交换机经常用来循环分发任务给多个工作者(workers)。当这样做的时候,我们需要明白一点,在AMQP 0-9-1中,消息的负载均衡是发生在消费者(consumer)之间的,而不是队列(queue)之间。

在这里插入图片描述

2.1配置类QueueConfig

@Configuration
public class QueueConfig {/*** 创建一个队列  队列名为direct1* */@Beanpublic Queue queue01(){return new Queue("direct1",true);//true表示持久化}/*** 创建一个直连交换机 名为directExchange* */@Beanpublic DirectExchange directExchange(){return new DirectExchange("directExchange");}/*** 在让队列和直连交换机绑定在一起* */@Beanpublic Binding binding(){Binding binding= BindingBuilder.bind(queue01()).to(directExchange()).with("routingKey01");return binding;}}

2.2消息提供者

@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;public void sent_test(Object o){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend("directExchange",//交换机名字"routingKey01",//路由keyo);}
}

2.2消息消费者


@Component
@Slf4j
public class MqConsumer {/*** 接收消息*/@RabbitListener(queues = {"direct1"})public void receivedD(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("当前时间:{},消费者1收到消息:{}",new Date().toString(),msg);}}

我写了两个消费者内容一致

2.3测试类

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send() throws InterruptedException {// 循环发送消息while (true) {mqProducer.sent_test("你好,我是Lottery 001");Thread.sleep(3500);}}
}

测试结果
在这里插入图片描述

三、默认交换机default exchange

默认交换机(default exchange)实际上一个由消息代理预先声明好的没有名字(名字为空字符串)的直连交换机(direct exchange)。它有一个特殊的属性使得它对于简单应用特别有用处:那就是每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称队列名称 相同

3.1配置类和消息提供者

/**
*配置类
*/
@Configuration
public class QueueConfig {
//只需要创建一个队列
//每个`新建队列`(queue)都会`自动`绑定到`默认交换机`上,
//绑定的`路由键(routing //key)名称`与`队列名称` 相同@Beanpublic Queue queue02(){return new Queue("def");}}
/**
*消息提供者
*/
@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;public void def_sent_test(Object obj){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend(//没有名字(名字为空字符串)"","def",obj);//消息内容}
}

默认交换机名字是空字符串 。每个新建队列(queue)都会自动绑定到默认交换机上,绑定的路由键(routing key)名称队列名称 相同

3.2消息消费者

@Component
@Slf4j
public class MqConsumer {/*** 接收消息*/@RabbitListener(queues = {"def"})public void receivedD02(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}}

3.3测试结果

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send02() throws InterruptedException {// 循环发送消息while (true) {mqProducer.def_sent_test("测试默认交换机");Thread.sleep(3500);}}
}

在这里插入图片描述

四、扇型交换机fanout exchange

扇型交换机(fanout exchange)将消息路由给绑定到它身上的所有队列,而不理会绑定的路由键。如果N个队列绑定到某个扇型交换机上,当有消息发送给此扇型交换机时,交换机会将消息的拷贝分别发送给这所有的N个队列。扇型用来交换机处理消息的广播路由(broadcast routing)
这个交换机上的路由键将失效
在这里插入图片描述

4.1配置类

@Configuration
public class QueueConfig {/*** 创建多个队列* @return*/@Beanpublic Queue queue03_1(){return new Queue("fanout03_1");}@Beanpublic Queue queue03_2(){return new Queue("fanout03_2");}@Beanpublic Queue queue03_3(){return new Queue("fanout03_3");}/*** 创建一个扇形交换机*/@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("fanoutExchange");}/*** 队列和扇形交换机绑定*/@Beanpublic Binding binding_3_1(){Binding binding= BindingBuilder.bind(queue03_1()).to(fanoutExchange());return binding;}@Beanpublic Binding binding_3_2(){Binding binding= BindingBuilder.bind(queue03_2()).to(fanoutExchange());return binding;}@Beanpublic Binding binding_3_3(){Binding binding= BindingBuilder.bind(queue03_3()).to(fanoutExchange());return binding;}
}

4.2消息提供者

 @Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 扇形交换机*/public void fanout_sent_test(Object o){//convertAndSend(交换机的名字,交换机中路由键名称,参数)rabbitTemplate.convertAndSend("fanoutExchange","",//扇形交换机也没有路由建o);}}

注意:扇形交换机也没有路由key 也用空字符串

4.3消息消费者

@Component
@Slf4j
public class MqConsumer {@RabbitListener(queues = {"fanout03_1"})public void receivedD03_1(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列一 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"fanout03_2"})public void receivedD03_2(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列二 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"fanout03_3"})public void receivedD03_3(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("绑定队列三 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}
}

4.4测试类

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send03() throws InterruptedException {int a=1;// 循环发送消息while (true) {mqProducer.fanout_sent_test("测试扇形交换机 第"+ a++ +"次循环");Thread.sleep(3500);}}
}

在这里插入图片描述

五、主题交换机topic exchanges

主题交换机(topic exchanges)通过对消息的路由键队列到交换机的绑定模式之间的匹配,将消息路由 一个或多个队列。主题交换机经常用来实现各种分发/订阅模式及其变种。主题交换机通常用来实现消息的多播路由(multicast routing)。

在这里插入图片描述

5.1配置类

@Configuration
public class QueueConfig {/*** 创建;两个队列*/@Beanpublic Queue topicQueue_1(){return new Queue("topicQueue_1");}@Beanpublic Queue topicQueue_2(){return new Queue("topicQueue_2");}/*** 创建主题交换机*/@Beanpublic TopicExchange TopicExchange(){return new TopicExchange("TopicExchange");}/*** 根据不同的key绑定不同的队列*/@Beanpublic Binding bindingTopicExchange_1(){Binding binding= BindingBuilder.bind(topicQueue_1()).to(TopicExchange()).with("key1");return binding;}@Beanpublic Binding bindingTopicExchange_2(){Binding binding= BindingBuilder.bind(topicQueue_2()).to(TopicExchange()).with("key2");return binding;}
}

5.2消息提供者

@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 主题交换机*/public void topic_sent_test(Object o,String key){rabbitTemplate.convertAndSend("TopicExchange",key, //后面动态的传递keyo);}
}

5.3消息消费者

@Component
@Slf4j
public class MqConsumer1 {/*** 接收消息*/@RabbitListener(queues = {"topicQueue_1"})public void topicQueue_1(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("队列一 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}@RabbitListener(queues = {"topicQueue_2"})public void topicQueue_2(Message message, Channel channel)throws Exception{String msg=new String(message.getBody());log.info("队列二 当前时间:{},消费者收到消息:{}",new Date().toString(),msg);}}

5.4测试

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_send04() throws InterruptedException {// 循环发送消息int a=1;while (true) {if(a%2 == 0){mqProducer.topic_sent_test("!!给队列二的消息==第"+ a++ +"次循环","key2");}else{mqProducer.topic_sent_test("!!给队列一的消息==第"+ a++ +"次循环","key1");}Thread.sleep(3500);}}
}

在这里插入图片描述

使用案例:

  • 分发有关于特定地理位置的数据,例如销售点
  • 由多个工作者(workers)完成的后台任务,每个工作者负责处理某些特定的任务
  • 股票价格更新(以及其他类型的金融数据更新)
  • 涉及到分类或者标签的新闻更新(例如,针对特定的运动项目或者队伍)
  • 云端的不同种类服务的协调
  • 分布式架构/基于系统的软件封装,其中每个构建者仅能处理一个特定的架构或者系统。

六、头交换机 headers exchange

有时消息的路由操作会涉及到多个属性,此时使用消息头就比用路由键更容易表达,头交换机(headers exchange)就是为此而生的。头交换机使用多个消息属性代替 路由键建立路由规则。通过判断消息头的值能否与指定的绑定相匹配来确立路由规则。
在这里插入图片描述

6.1配置类

@Configuration
public class QueueConfig {/*** 创建2个队列*/@Bean(name = "headersQ1")public Queue queue1() {return new Queue("headersQ1");}@Bean(name = "headersQ2")public Queue queue2() {return new Queue("headersQ2");}/*** 创建交换机* @return*/@Beanpublic HeadersExchange headersExchange() {return new HeadersExchange("headersExchange");}/*** 绑定交换机和队列*/@Beanpublic Binding binding1() {HashMap<String, Object> header = new HashMap<>();header.put("queue", "queue1");header.put("bindType", "whereAll");return BindingBuilder.bind(queue1()).to(headersExchange()).whereAll(header).match();}@Beanpublic Binding binding2() {HashMap<String, Object> header = new HashMap<>();header.put("queue", "queue2");header.put("bindType", "whereAny");return BindingBuilder.bind(queue2()).to(headersExchange()).whereAny(header).match();}
}

6.2创建消息提供者

@Component
public class MqProducer {@Resourceprivate RabbitTemplate rabbitTemplate;/*** 头交换机* @param msg*/public void headers_send(String msg,int a) {//a用来控制头信息 达到传递给不同的队列效果MessageProperties messageProperties = new MessageProperties();if(  a % 3 ==0){messageProperties.setHeader("queue", "queue2");messageProperties.setHeader("bindType", "whereAny");}else{messageProperties.setHeader("queue", "queue1");messageProperties.setHeader("bindType", "whereAll");}Message message = new Message(msg.getBytes(), messageProperties);rabbitTemplate.convertAndSend("headersExchange", null, message);}
}

6.3消息消费者

@Component
@Slf4j
public class MqConsumer1 {/*** 接收消息*/@RabbitListener(queues = "headersQ1")public void receive1(String msg) {log.info("接收到 headersQ1 发送的消息:" + msg);}@RabbitListener(queues = "headersQ2")public void receive2(String msg) {log.info("接收到 headersQ2 发送的消息:" + msg);}}

6、4测试结果

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class SpringRunnerTest {@Resourceprivate MqProducer mqProducer;//注入消息提供者@Testpublic void test_headers_send() throws InterruptedException {// 循环发送消息int a=1;while (true) {mqProducer.headers_send("消息"+a,a++);Thread.sleep(3500);}}
}

在这里插入图片描述

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

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

相关文章

C语言-ubuntu下的命令

目录 linux命令 【1】打开关闭终端 【2】终端 【3】ls命令 【4】cd 切换路径 【5】新建 【6】删除 【7】复制 【8】移动 【9】常用快捷键 【10】vi编辑器 【11】简单编程步骤 任务&#xff1a; linux命令 【1】打开关闭终端 打开终端&#xff1a; 1. 直接点击 …

数学建模的赛题类型

一、预测类 指通过分析已有的数据或者现象&#xff0c;找出其内在发展规律&#xff0c;然后对未来情形做出预测的过程。 根据已知条件和求解目的&#xff0c;往往将预测类问题分为&#xff1a;小样本内部预测&#xff0c;大样本内部预测。 解决预测类赛题的一般步骤&#xff…

vue3 实现 Map 地图区域组件封装

图例&#xff1a;重庆区域 一、安装echarts 坑&#xff1a;地图echarts版本必须在5.0.0以下&#xff0c;否则不能显示&#xff0c;此处指定安装 echarts4.9.0 即可 cnpm install echarts4.9.0 --save 二、下载 “重庆” 区域地图json文件 下载地址&#xff1a;https://www.…

『表面』在平面模型上提取凸(凹)多边形

原始点云 直通滤波,z轴0~1.1 分割模型为平面&#xff0c;分割结果进行投影 提取多边形 代码: #include <pcl/ModelCoefficients.h> // 模型系数的数据结构&#xff0c;如平面、圆的系数 #include <pcl/io/pcd_io.h>#include <pcl/point_types.h> // 点云数据…

TCP和UDP的区别

连接&#xff1a;TCP 是面向连接的传输层协议&#xff0c;传输数据前先要建立连接&#xff1b;UDP 是不需要连接&#xff0c;即刻传输数据。首部开销&#xff1a;TCP 首部长度较长&#xff0c;首部在没有使用「选项」字段时是 20 个字节&#xff0c;如果使用了「选项」字段则会…

k8s服务发现之第二弹Service详解

创建 Service Kubernetes Servies 是一个 RESTFul 接口对象&#xff0c;可通过 yaml 文件创建。 例如&#xff0c;假设您有一组 Pod&#xff1a; 每个 Pod 都监听 9376 TCP 端口每个 Pod 都有标签 appMyApp apiVersion: v1 kind: Service metadata:name: my-service spec:s…

Modbus TCP/BACnet IP/MQTT物联网网关IOT-810介绍及其典型应用

伴随着计算机技术以及互联网的发展&#xff0c;物联网这个概念已经逐渐进入我们的日常生活&#xff0c;例如智能泊车&#xff0c;智能家居&#xff0c;智能照明&#xff0c;智能楼宇等。智能楼宇是将传统的楼宇自控系统与物联网技术相融合&#xff0c;把系统中常见的传感器、设…

设计模式 ~ 观察者模式

概念 观察者模式是一种设计模式&#xff0c;也被称为发布-订阅模式或事件模式&#xff1b; 用于在对象之间建立一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新&#xff1b; ~ 如&#xff1a;DOM事件、vue …

AVLTree深度剖析(单旋)

前言 二叉树搜索树是存在一定的缺陷问题的&#xff0c;当我们要插入的数据是有序&#xff0c;或者说接近于有序&#xff0c;&#xff0c;二叉搜索树及有可能退化为单支树&#xff0c;查找元素相当于在顺序表当中搜索元素&#xff0c;效率低下 --------------------------------…

Python对Excel不同的行分别复制不同的次数

本文介绍基于Python语言&#xff0c;读取Excel表格文件数据&#xff0c;并将其中符合我们特定要求的那一行加以复制指定的次数&#xff0c;而不符合要求的那一行则不复制&#xff1b;并将所得结果保存为新的Excel表格文件的方法。 这里需要说明&#xff0c;在我们之前的文章Pyt…

【C++】list的使用及底层实现原理

本篇文章对list的使用进行了举例讲解。同时也对底层实现进行了讲解。底层的实现关键在于迭代器的实现。希望本篇文章会对你有所帮助。 文章目录 一、list的使用 1、1 list的介绍 1、2 list的使用 1、2、1 list的常规使用 1、2、2 list的sort讲解 二、list的底层实现 2、1 初构…

等保测评包过是真的吗?安全吗?

最近有小伙伴在问&#xff0c;等保测评包过是真的吗&#xff1f;安全吗&#xff1f;哪位大哥来解答一下&#xff1f; 等保测评包过是真的吗&#xff1f;安全吗&#xff1f; 【回答】&#xff1a;等级保护采用备案与测评机制&#xff0c;而非认证机制&#xff0c;因此不存在“包…