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
     * */
    @Bean
    public Queue queue01(){
    
        return new Queue("direct1",true);//true表示持久化
    }

    /**
     * 创建一个直连交换机 名为directExchange
     * */
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("directExchange");
    }

    /**
     * 在让队列和直连交换机绑定在一起
     * */
    @Bean
    public Binding binding(){
        Binding binding= BindingBuilder
                .bind(queue01())
                .to(directExchange()).with("routingKey01");
        return binding;
    }

}

2.2消息提供者

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

    }
}

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 {
    @Resource
    private MqProducer mqProducer;//注入消息提供者
    @Test
    public 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)名称`与`队列名称` 相同
    @Bean
    public Queue queue02(){
        return new Queue("def");
    }

}
/**
*消息提供者
*/
@Component
public class MqProducer {
    @Resource
    private 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 {
    @Resource
    private MqProducer mqProducer;//注入消息提供者
    
  	@Test
    public 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
     */
    @Bean
    public Queue queue03_1(){
        return new Queue("fanout03_1");
    }
    @Bean
    public Queue queue03_2(){
        return new Queue("fanout03_2");
    }
    @Bean
    public Queue queue03_3(){
        return new Queue("fanout03_3");
    }

    /**
     * 创建一个扇形交换机
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("fanoutExchange");
    }

    /**
     * 队列和扇形交换机绑定
     */
    @Bean
    public Binding binding_3_1(){
        Binding binding= BindingBuilder
                .bind(queue03_1())
                .to(fanoutExchange());
        return binding;
    }
    @Bean
    public Binding binding_3_2(){
        Binding binding= BindingBuilder
                .bind(queue03_2())
                .to(fanoutExchange());
        return binding;
    }
    @Bean
    public Binding binding_3_3(){
        Binding binding= BindingBuilder
                .bind(queue03_3())
                .to(fanoutExchange());
        return binding;
    }
}

4.2消息提供者

 @Component
public class MqProducer {

    @Resource
    private 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 {
    @Resource
    private MqProducer mqProducer;//注入消息提供者
   
    @Test
    public 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 {

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

5.2消息提供者

@Component
public class MqProducer {

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

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 {
    @Resource
    private MqProducer mqProducer;//注入消息提供者
   @Test
    public 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
     */
    @Bean
    public HeadersExchange headersExchange() {
        return new HeadersExchange("headersExchange");
    }
    /**
     * 绑定交换机和队列
     */
    @Bean
    public 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();
    }
    @Bean
    public 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 {

    @Resource
    private 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 {
    @Resource
    private MqProducer mqProducer;//注入消息提供者
    
    @Test
    public void test_headers_send() throws InterruptedException {
        // 循环发送消息
        int a=1;
        while (true) {
            mqProducer.headers_send("消息"+a,a++);
            Thread.sleep(3500);
        }
    }
}

在这里插入图片描述

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

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

相关文章

Makefile:6: *** missing separator. Stop.

Makefile:2: *** missing separator. Stop. Windows下用VS CODE编写makefile文件&#xff0c;编译报出这个错误 可以查看一下VS CODE左下角&#xff0c;如果是下图“空格&#xff1a;4”这样&#xff0c;需要更改一下。 在“空格&#xff1a;4”上左键单击一下&#xff0c;在…

涂鸦智能打造专业家庭智能生活助手,实现人机交互升级

近年来&#xff0c;智能家居设备的品类不断拓展&#xff0c;同时&#xff0c;人们对AI与智能家居的联动愈发憧憬。自然语言交互是未来人机交互的主要趋势之一&#xff0c;其关键在于使AI具备主动理解信息的能力&#xff0c;让用户的交互更轻松。如何将智能场景的交互变得更“善…

【动手学深度学习】--15.含并行连结的网络GoogLeNet

文章目录 含并行连结的网络GoogLeNet1.Inception块2.GoogLeNet模型3.训练模型 含并行连结的网络GoogLeNet 学习视频&#xff1a;含并行连结的网络 GoogLeNet / Inception V3【动手学深度学习v2】 官方笔记&#xff1a;含并行连结的网络&#xff08;GoogLeNet&#xff09; 1.…

基于Web API drap事件的简单拖拽功能

基于Web API drap事件的简单拖拽功能 效果示例图代码示例 效果示例图 代码示例 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">* {padding: 0px;margin: 0px;box-s…

单例模式、指令重排序、锁、有序性

今天在回顾单例模式时&#xff0c;我们都知道懒汉式单例中有一种叫做双重检查锁的单例模式。 我们来看下下面的代码有没有问题&#xff1a; 这段代码我们可以看到&#xff0c;即优化了性能&#xff0c;在多线程情况下&#xff0c;如果实例不为空了&#xff0c;则直接返回了。…

Vue成绩案例实现添加、删除、显示无数据、添加日期、总分均分以及数据本地化等功能

一、成绩案例 ✅✅✅通过本次案例实现添加、删除、显示无数据、添加日期、总分均分以及数据本地化等功能。 准备成绩案例模板&#xff0c;我们需要在这些模板上面进行功能操作。 <template><div class"score-case"><div class"table">…

Rsync(二十七)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 二、特性 三、应用场景 四、数据的同步方式 五、rsync传输模式 六、rsync应用 七、rsync 命令 1. 格式 1.1 作为远程命令 1. 2 作为rsync服务 2. 选项 3.…

解密:GPT-4框架与训练过程,数据集组成,并行性的策略,专家权衡,推理权衡等细节内容

大家好&#xff0c;我是微学AI&#xff0c;今天给大家解密一下GPT-4框架与训练过程&#xff0c;数据集组成&#xff0c;并行性的策略&#xff0c;专家权衡&#xff0c;推理权衡等细节内容。2023年3月14日&#xff0c;OpenAI发布GPT-4&#xff0c;然而GPT-4的框架没有公开&#…

【ArcGIS Pro二次开发】(46):要素类从上到下、从左到右排序

要素类经过编辑之后&#xff0c;【OBJECTID】字段会变得不规律。应部分网友要求&#xff0c;做了这个从上到下、从左到右排序的工具。 不过后来在ArcGIS Pro中发现了一个【排序】工具&#xff0c;已经可以完美实现这个功能需求&#xff0c;发现自己做了个白工。 不过做了不能白…

【最新教程】树莓派安装系统及VNC远程桌面连接

大家好&#xff0c;今天就不给大家介绍PYTHONL ,今天我作为一个刚入坑树莓派的小白&#xff0c;整理了一下自己安装树莓派的整个过程&#xff0c;分享给大家。 目录 树莓派 准备工作&#xff1a; 树莓派远程ssh失败access denied 原因&#xff1a; 树莓派系统安装 1、下载…

hive常用方法

日期类 Date_sub 日期进行加减 &#xff0c;正的减&#xff0c;负的加 select current_date -- 当前日期,date_sub(current_date,1) -- 前一日,date_sub(current_date,-1) -- 后一日 from edw.test;字符类 split 该函数是分割字符串 &#xff0c;按照…

ChatGPT火热之下的冷思考

作为一款基于人工智能的自然语言处理(NLP)​​聊天机器人​​程序&#xff0c;ChatGPT通过大量来自互联网的文本进行训练&#xff0c;并使用深度学习和机器学习算法来理解用户的问题并提供准确的回答。并且&#xff0c;ChatGPT还内置了情感分析、关键字提取和实体识别等功能&am…

【QT】——QListWidget的使用

目录 1.QListWidget和QListWidgetItem 2.外观 2.1列表模式 2.2图标模式 3.常用接口 4.示例 删除列表项 添加列表项 1.QListWidget和QListWidgetItem QListWidget 是qt中的列表框控件&#xff0c;它用于显示多个列表项&#xff0c;列表项对应的类是QListWidgetItem. Q…

qt和vue交互

1、首先在vue项目中引入qwebchannel /******************************************************************************** Copyright (C) 2016 The Qt Company Ltd.** Copyright (C) 2016 Klarlvdalens Datakonsult AB, a KDAB Group company, infokdab.com, author Milian …

MobPush Android For Unity

本文档以unity2020.3.41演示 集成准备 注册账号 使用MobSDK之前&#xff0c;需要先在MobTech官网注册开发者账号&#xff0c;并获取MobTech提供的AppKey和AppSecret&#xff0c;详情可以点击查看注册流程 下载.unitypackage包 打开 Github 下载 MobPush-For-Unity 项目&am…

java项目之贝儿米幼儿教育管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的贝儿米幼儿教育管理系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java…

队列的表示和操作

队列&#xff1a;队列是仅在表尾进行插入操作&#xff0c;在表头进行删除操作的线性表。 表尾即an端&#xff0c;称为队尾&#xff0c;表头即a1端&#xff0c;称为队头。 队列的存储方式&#xff1a;顺序队列和链式队列 队列顺序表示 #define MAXQSIZE 100 //最大队列长度 …

使用php数组实现双色球的随机选号

一、双色球彩票介绍 双色球是中国福利彩票的一种常见玩法&#xff0c;也是全国彩民最爱的彩种之一。玩法规则是在33个红色球中选择6个数字&#xff0c;在16个蓝色球中选择1个数字&#xff0c;红色球号码区间为1-33&#xff0c;蓝色球号码区间为1-16。可以单式投注或者复式投注…

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

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

Python爬虫——urllib_post请求百度翻译

post请求&#xff1a; post的请求参数&#xff0c;是不会拼接在url后面的&#xff0c;而是需要放在请求对象定制的参数中 post请求的参数需要进行两次编码&#xff0c;第一次urlencode&#xff1a;对字典参数进行Unicode编码转成字符串&#xff0c;第二次encode&#xff1a;将字…