微服务——服务异步通讯RabbitMQ

 前置文章

消息队列——RabbitMQ基本概念+容器化部署和简单工作模式程序_北岭山脚鼠鼠的博客-CSDN博客

消息队列——rabbitmq的不同工作模式_北岭山脚鼠鼠的博客-CSDN博客

消息队列——spring和springboot整合rabbitmq_北岭山脚鼠鼠的博客-CSDN博客

目录

Work queues 工作队列模式 

案例:

 在生产者端

在消费者端

结果如下

 消费预取限制

 发布订阅模型

 Fanout Exchange(配置文件实现)

案例

消费者代码

生产者代码

 Direct Exchange (注解实现)

 案例

消费者代码

生产者代码

Topic Exchange

案例 

 消费者代码

生产者代码

 消息转换器

生产者代码

JSON方式序列化

生产者代码 (jackson)

 消费者代码(jackson)

 总结


Work queues 工作队列模式 

这里用的不是上面第三篇文章里面的定义配置类的形式。

案例:

 在生产者端

队列要存在才可以上传。不然代码运行不会报错,但是消息也会不知道发到哪里去。

    @Testpublic void testSendMessage2() throws InterruptedException {String queue_Name= "simple.queue";String message="hello 鼠鼠";for(int i=1;i<=50;i++)rabbitTemplate.convertAndSend(queue_Name,message+i);Thread.sleep(20);}

在消费者端

定义了两个消费者监听上面的队列,本来想三个的,但是不知道默认的交换机名字,所以弄了两个。并且根据注解的不同,第一个是可以直接创建一个队列,第二个需要队列已存在才行。

@Component
public class RabbitMQListener {//自动创建队列@RabbitListener(queuesToDeclare=@Queue("simple.queue"))public void ListenerWorkQueue1(Message message) throws InterruptedException {System.out.println("11111"+message.getBody());Thread.sleep(20);}//需要在rabbit_mq上手动创建队列,不然会报错@RabbitListener(queues="simple.queue")public void ListenerWorkQueue2(Message message) throws InterruptedException {System.out.println("22222"+message.getBody());Thread.sleep(200);}//3. 自动创建队列,Exchange 与 Queue绑定
//    @RabbitListener(bindings = @QueueBinding(
//            value = @Queue("simple.queue"),
//            exchange = @Exchange("/")  //绑定默认交换机
//    ))
//    public void ListenerWorkQueue3(Message message) throws InterruptedException {
//        System.out.println("33333"+message.getBody());
//        Thread.sleep(200);
//    }
}

结果如下

两个队列轮流取消息导致反而变慢了。

 消费预取限制

要指定队列才有效果。

 这里就相当于指定了在simple前缀的队列上每次只能获取一条消息。

运行结果如下,大多数都交给了快的队列执行。

 发布订阅模型

 Fanout Exchange(配置文件实现)

消息路由到每个绑定的消息队列。

案例

 

消费者代码

 spring读取到这个Bean之后就会向RabbitMq发请求,创建交换机,绑定队列了。 

@Configuration
public class FanoutConfig {//itcast.fanout@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("itcast.fanout");}//fanout.queue1@Beanpublic Queue fanoutQueue1(){return new Queue("fannout.queue1");}//绑定队列1到交换机@Beanpublic Binding fanoutBinding1(Queue fanoutQueue1, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}//fanout.queue1@Beanpublic Queue fanoutQueue2(){return new Queue("fannout.queue2");}//绑定队列2到交换机@Beanpublic Binding fanoutBinding2(Queue fanoutQueue2, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}

定义两个监听用的方法

@Component
public class RabbitMQListener {
//    @RabbitListener(queues="boot_queue")
//    public void ListenerQueue(Message message){
//        System.out.println(message);
//    }//自动创建队列//    @RabbitListener(queuesToDeclare=@Queue("simple.queue"))
//    public void ListenerWorkQueue1(Message message) throws InterruptedException {
//        System.out.println("11111"+message.getBody()+ LocalDateTime.now());
//        Thread.sleep(20);
//    }
//
//    //需要在rabbit_mq上手动创建队列,不然会报错
//    @RabbitListener(queues="simple.queue")
//    public void ListenerWorkQueue2(Message message) throws InterruptedException {
//        System.out.println("22222"+message.getBody()+ LocalDateTime.now());
//        Thread.sleep(200);
//    }//3. 自动创建队列,Exchange 与 Queue绑定
//    @RabbitListener(bindings = @QueueBinding(
//            value = @Queue("simple.queue"),
//            exchange = @Exchange("/")  //绑定默认交换机
//    ))
//    public void ListenerWorkQueue3(Message message) throws InterruptedException {
//        System.out.println("33333"+message.getBody());
//        Thread.sleep(200);
//    }@RabbitListener(queuesToDeclare=@Queue("fanout.queue1"))public void ListenerFanoutQueue1(Message message) throws InterruptedException {System.out.println("11111"+message.getBody());}@RabbitListener(queuesToDeclare=@Queue("fanout.queue2"))public void ListenerFanoutQueue2(Message message) throws InterruptedException {System.out.println("22222"+message.getBody());}
}

生产者代码

@SpringBootTest
@RunWith(SpringRunner.class)
public class ProducerTest {//1.注入RabbitTemplate@Autowiredprivate RabbitTemplate rabbitTemplate;//    @Test
//    public void testSend(){
//        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_NAME,"boot.haha","hello 鼠鼠");
//    }//    @Test
//    public void testSendMessage2() throws InterruptedException {
//        String queue_Name= "simple.queue";
//        String message="hello 鼠鼠";
//
//        for(int i=1;i<=50;i++)
//        rabbitTemplate.convertAndSend(queue_Name,message+i);
//        Thread.sleep(20);
//    }@Testpublic void testSendFanoutExchange(){//交换机名称String exchangeName="itcast.fanout";//消息String message="hello 鼠鼠";//发送消息rabbitTemplate.convertAndSend(exchangeName,"",message);}
}

 Direct Exchange (注解实现)

 案例

消费者代码


@Component
public class RabbitMQListener {   @RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1"),exchange = @Exchange(name="itcast.direct" , type= ExchangeTypes.DIRECT),key={"red","blue"}))public void listenDirectQueue1(String msg){System.out.println("消费者接收到:"+msg);}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue2"),exchange = @Exchange(name="itcast.direct" , type= ExchangeTypes.DIRECT),key={"red","yellow"}))public void listenDirectQueue2(String msg){System.out.println("消费者接收到:"+msg);}
}

生产者代码

    @Testpublic void testSendDirectExchange(){//交换机名称String exchangeName="itcast.direct";//消息String message="hello 鼠鼠";//发送消息rabbitTemplate.convertAndSend(exchangeName,"blue",message);}

此条代码只有绑定了blue这个key的队列才可以收到。

换成red就是两个队列都可以收到了。

Topic Exchange

案例 

 

 消费者代码

    @RabbitListener(bindings = @QueueBinding(value=@Queue(name="topic.queue1"),exchange=@Exchange(name="itcast.topic",type = ExchangeTypes.TOPIC),key="japan.#"))public void listenTopicQueue1(String msg){System.out.println("消费者接收到:"+msg);}@RabbitListener(bindings = @QueueBinding(value=@Queue(name="topic.queue2"),exchange=@Exchange(name="itcast.topic",type = ExchangeTypes.TOPIC),key="#.news"))public void listenTopicQueue2(String msg){System.out.println("消费者接收到:"+msg);}

生产者代码

    @Testpublic void testSendTopicExchange(){//交换机名称String exchangeName="itcast.topic";//消息String message="北岭山脚鼠鼠横死街头,究竟是人性的沦丧还是道德的....";//发送消息rabbitTemplate.convertAndSend(exchangeName,"japan.news",message);}

两个都符合,所以都能收到。

 消息转换器

定义一个队列

    @Beanpublic Queue objectQueue(){return new Queue("object.queue");}

生产者代码

    @Testpublic void testSendObjectQueue(){//消息Map<String,Object> msg=new HashMap<>();msg.put("name","北岭山脚鼠鼠");msg.put("age","22");//发送消息rabbitTemplate.convertAndSend("object.queue",msg);}

可以看见消息被转换成了一长串字符,content_type写着java的序列化。

效率差,安全性也差。 

JSON方式序列化

声明好MessageConveter之后就可以自动覆盖默认序列化方式了。

导入一个核心依赖

        <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>

生产者代码 (jackson)

 修改生产者的启动类代码,加上一个Bean

@SpringBootApplication
public class ProducerApplication {public static void main(String[] args) {SpringApplication.run(ProducerApplication.class);}@Beanpublic Jackson2JsonMessageConverter messageConverter(){return new Jackson2JsonMessageConverter();}
}

启动测试类之后可以看见新的消息出现了。

 消费者代码(jackson)

 然后可以正常接受到消息

如果消费者不使用对应jackson解析的话,代码会报错

 总结

推荐使用jackson的方式 

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

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

相关文章

设计模式 - 工厂模式

一、 简单工厂&#xff08;Simple Factory Pattern&#xff09; 1、概念 一个工厂对象决定创建出哪一种产品类的实力&#xff0c;但不属于GOF23种设计模式。 简单工厂适用于工厂类负责创建的对象较少的场景&#xff0c;且客户端只需要传入工厂类的参数&#xff0c;对于如何创…

Andrew算法求凸包模板

前置知识 向量的叉乘: 设 a ⃗ ( x a , y a , z a ) , b ⃗ ( x b , y b , z b ) \vec a(x_a,y_a,z_a), \vec b(x_b, y_b,z_b) a (xa​,ya​,za​),b (xb​,yb​,zb​), 令 a ⃗ \vec a a 和 b ⃗ \vec b b 的叉乘为 c ⃗ \vec c c , 有: c ⃗ ∣ i j k x a y a z a x b y…

【深度学习】GPT-3

2020年5月&#xff0c;OpenAI在长达72页的论文《https://arxiv.org/pdf/2005.14165Language Models are Few-Shot Learners》中发布了GPT-3&#xff0c;共有1750亿参数量&#xff0c;需要700G的硬盘存储&#xff0c;(GPT-2有15亿个参数)&#xff0c;它比GPT-2有了极大的改进。根…

钉钉返回:访问ip不在白名单之中,请参考FAQ

新版钉钉 在开发管理-服务器出口IP-配置返回错误信息返回给你的requestIp

k8s部署新版elasticsearch+kibana并配置快照备份

版本:es 7.17.6 kibana 7.17.6 k8s:1.19.16 一、介绍 Elasticsearch和Kibana是一对强大的开源工具&#xff0c;通常一起使用以构建实时数据分析和可视化解决方案。 Elasticsearch: Elasticsearch是一个分布式、高性能的实时搜索和分析引擎。它构建在开源搜索引擎库Lucene之上…

【C++】开源:Redis数据库配置与使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Redis数据库配置与使用。 无专精则不能成&#xff0c;无涉猎则不能通。。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

边缘计算对现代交通的重要作用

边缘计算之所以重要&#xff0c;是在于即使在5G真正商用之时&#xff0c;可以实现超大带宽&#xff08;eMBB&#xff09;的应用场景&#xff0c;但庞大数据量的涌现也就意味着需要在云和端传输过程中找到一个承接点&#xff0c;对数据进行预处理再选择是否上云。 边缘计算应用演…

【Python入门【推导式创建序列、字典推导式、集合推导式】(九)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…

SkyWalking链路追踪-技术文档首页

SkyWalking 文档中文版&#xff08;社区提供&#xff09; (skyapm.github.io)https://skyapm.github.io/document-cn-translation-of-skywalking/ SkyWalking-基本概念 SkyWalking链路追踪是一个用于分布式系统的性能监控工具&#xff0c;它帮助开发人员了解系统中各组件之间…

工程安全监测无线振弦采集仪在建筑物的应用分析

工程安全监测无线振弦采集仪在建筑物的应用分析 工程安全监测无线振弦采集仪是一种在建筑物中应用的重要设备。它通过无线采集建筑物内部的振动信息&#xff0c;对建筑物的安全性进行监测和评估&#xff0c;为建筑物的施工和使用提供了可靠的技术支持。本文将详细介绍工程安全…

ElasticSearch基础篇-安装与基本操作

ElasticSearch基础篇 安装 官网 下载地址 下载完成后对文件进行解压&#xff0c;项目结构如下 进入bin目录点击elasticsearch.bat启动服务 9300 端口为 Elasticsearch 集群间组件的通信端口&#xff0c; 9200 端口为浏览器访问的 http协议 RESTful 端口 打开浏览器&#…

力扣热门100题之矩阵置0【中等】

题目描述 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 示例 2&#xff…

C++ - list介绍 和 list的模拟实现

list介绍 list 是一个支持在常数范围内&#xff0c;任意位置进行插入删除的序列式容器&#xff0c;且这个容器可以前后双向迭代。我们可以把 list 理解为 双向循环链表的结构。 于其他结构的容器相比&#xff0c;list在 任意位置进行插入和函数的效率要高很多&#xff1b;而li…

SWF格式视频怎么转换成AVI格式?简单的转换方法分享

当你想要在不同的设备上播放视频时&#xff0c;将SWF格式视频转换成AVI格式是非常有用的。因为SWF格式通常只能在特定的软件或网页上播放&#xff0c;而AVI格式则可以在更广泛的设备上播放&#xff0c;包括智能手机&#xff0c;平板电脑和电视机等。那么我们怎么将SWF转换成AVI…

AI学习笔记四:yolov5训练自己的数据集

若该文为原创文章&#xff0c;转载请注明原文出处。 一般情况下&#xff0c;大部分人的电脑都是没有cpu的&#xff0c;cpu也是可以训练的&#xff0c;但花费的时间太长&#xff0c;实际200张图片&#xff0c;使用CPU训练300轮花了3天&#xff0c;本章记录使用云服务器来训练自…

SkyWalking链路追踪-搭建-spring-boot-cloud-单机环境 之《10 分钟快速搭建 SkyWalking 服务》

首先了解一下单机环境 第一步&#xff0c;搭建一个 Elasticsearch 服务。第二步&#xff0c;下载 SkyWalking 软件包。第三步&#xff0c;搭建一个 SkyWalking OAP 服务。第四步&#xff0c;启动一个 Spring Boot 应用&#xff0c;并配置 SkyWalking Agent。第五步&#xff0c;…

Docker Compose 容器编排

Docker compose Docker compose 实现单机容器集群编排管理&#xff08;使用一个模板文件定义多个应用容器的启动参数和依赖关系&#xff0c;并使用docker compose来根据这个模板文件的配置来启动容器&#xff09; 通俗来说就是把之前的多条docker run启动容器命令 转换为docker…

【小白学编程5】我的房子在哪儿?理解类型和变量

我的房子在哪儿? 理解类型和变量 - 《小白学编程》系列第五讲 - 《小白学编程》系列课程过半&#xff0c;为满足更多同学的时间需求&#xff0c;课程直播时间改为了晚上八点。 昨晚八点准时开始课程的第五讲&#xff0c;其主题为&#xff1a;“我的房子在哪儿&#xff1f;理解…

学习 C语言第二天 :C语言数据类型和变量(下)

目录&#xff1a; 1.变量的介绍以及存储 2.算术操作符、赋值操作符、单目操作符 3.scanf和printf的介绍 1.变量的介绍以及存储 1.1.变量的创建 了解了什么是类型了&#xff0c;类型是用来创建变量的。 变量是什么呢&#xff1f;在C语言当中不经常变的量称为常量&#xff0c;经常…

【雕爷学编程】Arduino动手做(95)---GY9960手势传感器模块3

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…