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

RabbitMq深度学习

什么是RabbitMq?

RabbitMQ是一个开源的消息队列中间件,它实现了高级消息队列协议(AMQP)。它被广泛用于分布式系统中的消息传递和异步通信。RabbitMQ提供了一种可靠的、可扩展的机制来传递消息,使不同的应用程序能够相互之间进行通信。它支持多种编程语言和平台,并且具有灵活的路由和队列配置选项。

同步调用 

同步调用的优点:

  • 时效性较强,可以立即得到结果

同步调用的问题:

  • 耦合度高

  • 性能和吞吐能力下降

  • 有额外的资源消耗

  • 有级联失败问题

异步调用

好处:

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速

  • 故障隔离:服务没有直接调用,不存在级联失败问题

  • 调用间没有阻塞,不会造成无效的资源占用

  • 耦合度极低,每个服务都可以灵活插拔,可替换

  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

缺点:

  • 架构复杂了,业务没有明显的流程线,不好管理

  • 需要依赖于Broker的可靠、安全、性能

MQ的种类 

 RabbitMq安装和使用 

 云服务器安装Rabbitmq。

 在docker 中拉去Ribbitmq镜像。

在docker 中运行ribbitmq。

docker run -d -p 5672:5672 -p 15672:15672 -p 25672:25672 --name rabbitmq rabbitmq

 查看rabbitmq的状态。

rabbitmqctl status

接着我们还可以将Rabbitmq的管理面板开启,这样就可以在浏览器上进行实时访问和监控了。 

我们需要先进入rabbitmq容器。

docker exec -it [在docker中对应的ID] [进入容器的路径] #路径一般为/bin/bash

开启rabbitmq的控制面板设置。

rabbitmq-plugins enable rabbitmq_management

打开rabbitmq的控制面板,就是对应的控制面板端口为15672。

账号和密码都是:guest

 消息队列模型

 SpringAMQP

 什么是springAMQP?

Spring AMQP 是一个基于 Spring 框架的 AMQP(高级消息队列协议)的开发框架。它提供了一种简化和抽象化的方式来使用 AMQP,使得在应用程序中使用消息队列变得更加容易。

springAMQP的使用

导入依赖

<!--AMQP依赖,包含RabbitMQ-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

编写发送者

编写applcation.yml文件

spring:rabbitmq:host: 119.9.212.171 # 主机名port: 5672 # 端口virtual-host: / # 虚拟主机username: guest # 用户名password: guest # 密码

进行测试

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException;
import java.util.concurrent.TimeoutException;@RunWith(SpringRunner.class) #如果不加此注解,spring容器无法自动注入RabbitTemplate
@SpringBootTest
public class PublisherTest {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void tess1() {String queueName = "queueName";String message = "hello, tolen";rabbitTemplate.convertAndSend(queueName, message);}
}

测试结果为下:

 可能会出现没有队列生成的情况,这是因为@Test无法自动一个 queue,我们手动创建一个即可。

编写消费者

编辑application.yml文件

spring:rabbitmq:host: 192.168.150.101 # 主机名port: 5672 # 端口virtual-host: / # 虚拟主机username: test # 用户名password: 123456 # 密码

创建消息监听者

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class RabbitMqListener {@RabbitListener(queues = "queueName")public void getMessage(String message) {System.out.println("获取的消息是:" + message);}
}

直接配置即可,在后续的项目中消费者会监听对应的消息进行操作。

WorkQueue

我们可以对一个消息标签设置多个监听者,并且默认的设置是预取,也就是即使服务模块处理能力差的情况也会分配到相同个数的信息,不能达到能者多劳的效果,为了到达此效果,我们可以在application.yml中进行设置。

spring:rabbitmq:listener:simple:prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

发布与订阅

FanoutExchange的使用

在消费者模块编写:新建交换机,新建队列,交换机和队列绑定操作。

在配置类中完成上述操作

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MQConfiguration {//声明交换机FanoutExchange@Beanpublic FanoutExchange fanoutExchange() {
//        设置交换机的名字return new FanoutExchange("tolen.fanout");}
//    创建一个信息队列1@Beanpublic Queue fanoutQueue1() {return new Queue("fanout.queue1");}
//    创建信息队列2@Beanpublic Queue fanoutQueue2() {return new Queue("fanout.queue2");}//将交换机和队列1进行绑定@Beanpublic Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange) {//绑定队列给对应的交换机return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}//将交换机和队列2进行绑定@Beanpublic Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange) {return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}

在消费者模块中创建两个队列的监听器

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class RabbitMqListener {@RabbitListener(queues = "fanout.queue1")public void getMessage1(String message) {System.out.println("消息队列1中获取的消息是:" + message);}@RabbitListener(queues = "fanout.queue2")public void getMessage2(String message) {System.out.println("消息队列2中获取的消息是:" + message);}}

接下来不信消息发送模块,这里需要注意的是,此时我们是向对应的交换机发送消息,通过交换机发送消息给两个消息队列。

发送消息的代码为下:

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.io.IOException;
import java.util.concurrent.TimeoutException;@RunWith(SpringRunner.class)
@SpringBootTest
public class PublisherTest {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void tess1() {String queueName = "queueName";String message = "hello, tolen";rabbitTemplate.convertAndSend(queueName, message);}@Testpublic void fanoutTest() {String exchangeName = "tolen.fanout";String message = "hi, tolen!";//routingKey不进行设置rabbitTemplate.convertAndSend(exchangeName, "", message);}
}

如果不设置routingKey的话,就会默认将消息发送到使用绑定的消息队列上。 

测试结果为下:

交换机状态

监听器接收到的消息 

 DirectExchange

可以设置routingKey,交换机可以向指定的队列发送消息。

配置监听器

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class RabbitMqListener {//使用注解进行绑定, 不再需要configuration配置@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "directQueue1"),exchange = @Exchange(name = "direct"), //默认使用的交换机类型就是directExchangekey = {"red", "blue"}))public void directQueue1(String message) {System.out.println("directQueue2:" + message);}//使用注解进行绑定, 不再需要configuration配置@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "directQueue2"),exchange = @Exchange(name = "direct"), //默认使用的交换机类型就是directExchangekey = {"red"}))public void directQueue2(String message) {System.out.println("directQueue2:" + message);}
}

编写消息发布模块

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class PublisherTest {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void fanoutTest() {String exchangeName = "direct";String message = "hi, tolen!";//设置routingKeyrabbitTemplate.convertAndSend(exchangeName, "blue", message);}
}

测试结果为下:

此时就只有routingKey=blue的监听器才会接收到消息。

TopicExchage

Topic类型的ExchangeDirect相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!

Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

通配符规则:

#:匹配一个或多个词

*:匹配不多不少恰好1个词

修改编写监听器的配置

//使用注解进行绑定, 不再需要configuration配置@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "directQueue2"),exchange = @Exchange(name = "direct", type = ExchangeTypes.TOPIC), //默认使用的交换机类型就是directExchangekey = {"#.new"}))public void directQueue2(String message) {System.out.println("directQueue2:" + message);}

只要发送的消息中的routingKey中尾部为新闻的消息全部会被监听。(routingKey使用"."作间隔)

消息转换器

在springboot中默认使用JDK的序列化,为了提高使用性,我们可以使用json转换器。

在消费者和发送者中都导入对应的依赖。

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId><version>2.9.10</version>
</dependency>

在configuration中配置信息转换器。(消费者和发布者都需要配置)

import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MQConfiguration {@Beanpublic MessageConverter jsonMessageConverter(){return new Jackson2JsonMessageConverter();}
}

进行测试,在发送一个对象类型的消息。

对应的监听器

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.util.Map;
import java.util.Objects;@Component
public class RabbitMqListener {//使用注解进行绑定, 不再需要configuration配置@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "directQueue2"),exchange = @Exchange(name = "direct"), //默认使用的交换机类型就是directExchangekey = {"blue"}))public void directQueue2(Map<String, String> message) {System.out.println("directQueue2:" + message);}
}

对应的发送代码

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.LinkedHashMap;
import java.util.Map;@RunWith(SpringRunner.class)
@SpringBootTest
public class PublisherTest {@AutowiredRabbitTemplate rabbitTemplate;@Testpublic void fanoutTest() {String exchangeName = "direct";Map<String, String> message = new LinkedHashMap<>();message.put("name", "tolen");message.put("age", "19");//设置routingKeyrabbitTemplate.convertAndSend(exchangeName, "blue", message);}
}

测试效果为下:

接收到的数据 。

 消息队列中的数据。

相关文章:

RabbitMq深度学习

什么是RabbitMq? RabbitMQ是一个开源的消息队列中间件&#xff0c;它实现了高级消息队列协议&#xff08;AMQP&#xff09;。它被广泛用于分布式系统中的消息传递和异步通信。RabbitMQ提供了一种可靠的、可扩展的机制来传递消息&#xff0c;使不同的应用程序能够相互之间进行…...

EasyExcel自定义字段对象转换器支持转换实体和集合实体

文章目录 1. 实现ObjectConverter2. 使用3. 测试3.1 导出excel3.2 导入excel 1. 实现ObjectConverter package com.tophant.cloud.common.excel.converters;import cn.hutool.json.JSONUtil; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.…...

Linux重置ROOT密码(CentOS)

解释说明 在CentOS中重置root密码通常需要进入单用户模式&#xff0c;这是一个没有密码限制的特殊模式&#xff0c;允许您以root权限登录系统并更改密码。 重启系统 如果您无法登录到系统&#xff0c;可以通过重启系统来开始这个过程。您可以使用虚拟机控制台、物理服务器控制台…...

【Spring】一文带你彻底搞懂IOC、AOP

目录 首先简单了解一下什么是spring框架 什么是IOC&#xff1f; 什么是依赖注入&#xff08;DI&#xff09;&#xff1f; 控制反转和依赖注入又有什么关系&#xff1f; AOP是什么&#xff1f; SpringAOP的实现 说了这么多抽象概念&#xff0c;举个实例方便理解 首先简单…...

国际旅游网络的大数据分析(数学建模练习题)

题目&#xff1a;国际旅游网络的大数据分析 伴随着大数据时代的到来,数据分析已经深入到现代社会生活中的各个方面。 无论是国家政府部门、企事业单位还是个人&#xff0c;数据分析工作都是进行决策之前的 重要环节。 山东省应用统计学会是在省民政厅注册的学术类社会组织&…...

音视频技术开发周刊 | 308

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 OpenAI首席科学家最新访谈&#xff1a;对模型创业两点建议、安全与对齐、Transformer够好吗&#xff1f; OpenAI首席科学家Ilya Sutskever最近和他的朋友Sven Strohband进…...

多旋翼飞控底层算法开发系列实验 | 多旋翼动力系统设计实验3

多旋翼动力系统设计实验3 01/多旋翼动力系统简介​​​​​​​ 多旋翼无人机的动力系统通常包括螺旋桨、电机、电调以及电池。动力系统是多旋翼最重要的组成部分&#xff0c;它决定了多旋翼的主要性能&#xff0c;如悬停时间、载重能力、飞行速度和飞行距离等。动力系统的部件…...

Redis之Sentinel(哨兵)机制

一、Sentinel是什么&#xff1f; Sentinel&#xff08;哨岗、哨兵&#xff09;是Redis的高可用性&#xff08;high availability&#xff09;解决方案&#xff1a;由一个或多个Sentinel实例&#xff08;instance&#xff09;组成的Sentinel系统&#xff08;system&#xff09;…...

加密的PDF文件,如何解密?

PDF文件带有打开密码、限制编辑&#xff0c;这两种密码设置了之后如何解密&#xff1f; 不管是打开密码或者是限制编辑&#xff0c;在知道密码的情况下&#xff0c;解密PDF密码&#xff0c;我们只需要在PDF编辑器中打开文件 – 属性 – 安全&#xff0c;将权限状态修改为无保护…...

【java】获取当前年份

目录 一、代码示例二、截图示例 一、代码示例 package com.learning;import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.Year; import java.util.Calendar; import java.util.Date;/*** 获取当前年份*/ public class GetCurrentYear {public …...

前端面试话术集锦第一篇

🚗前端面试集锦目录 💖前端面试话术集锦第一篇💖 💖前端面试话术集锦第二篇💖 文章目录 1. 前端需要注意哪些SEO2. \<img>的title和alt有什么区别3. HTTP的⼏种请求⽅法⽤途4. 从浏览器地址栏输⼊url到显示⻚⾯的步骤5. 如何进⾏⽹站性能优化6. HTTP状态码及其…...

NeRFMeshing - 精确提取NeRF中的3D网格

准确的 3D 场景和对象重建对于机器人、摄影测量和 AR/VR 等各种应用至关重要。 NeRF 在合成新颖视图方面取得了成功&#xff0c;但在准确表示底层几何方面存在不足。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 我们已经看到了最新的进展&#xff0c;例如 NVIDIA 的 …...

后端面试话术集锦第五篇:rabbitmq面试话术

🚗后端面试集锦目录 💖后端面试话术集锦第 1 篇:spring面试话术💖 💖后端面试话术集锦第 2 篇:spring boot面试话术💖 💖后端面试话术集锦第 3 篇:spring cloud面试话术💖 💖后端面试话术集锦第 4 篇:ElasticSearch面试话术💖 💖后端面试话术集锦第 5 …...

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【一】

&#x1f600;前言 本篇博文是关于Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【一】&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章…...

vue3之reactive和ref学习篇

<script lang"ts" setup> // reactive参数必须为引用类型 和ref简单类型或者引用类型 import { reactive, ref } from vue; const arr reactive([10]) const count ref(0); let increasing true; console.log(count) const change ()>{if(increasing){c…...

【推荐】Spring与Mybatis集成整合

目录 1.概述 2.集成 2.1代码演示&#xff1a; 3.整合 3.1概述 3.2 进行整合分页 接着上两篇&#xff0c;我已经写了Mybatis动态之灵活使用&#xff0c;mybatis的分页和特殊字符的使用方式接下来把它们集成起来&#xff0c;是如何的呢&#x1f447;&#x1f447;&#x1…...

listdir, makedirs, shuffle, exists, webdriver.Chrome, roll方法快速查阅

1 os.listdir() os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表。 2 os.makedirs(path) 方法用于递归创建目录。 如果子目录创建失败或者已经存在&#xff0c;会抛出一个 OSError 的异常 3 numpy.random.shuffle(x) 由numpy.random调用&#xff0c;可…...

java.nio.ByteBuffer 学习笔记

目录 java 重复使用bytebuffer例子&#xff1a; java验证flip函数&#xff1a; flip讲解 以下内容转自&#xff1a; java.nio.ByteBuffer java 重复使用bytebuffer例子&#xff1a; import java.nio.ByteBuffer;public class ByteBufferExample {public static void main…...

自动化实时在线静电监控系统的构成

自动化实时在线静电监控系统是一种帮助企业监测和管理静电问题的技术解决方案。静电在许多工业和商业环境中都是一个潜在的风险和生产问题。通过使用这样的监控系统&#xff0c;企业可以及时发现并采取对策来预防或减轻可能的静电问题。 该系统通常由以下组成部分构成&#xf…...

Windows 转 mac 记录

初次从Windows转mac可能会不适应&#xff0c;建议先看看 【6分钟搞定MacBook】不懂时无所适从&#xff0c;学会后越用越爽&#xff01;_哔哩哔哩_bilibili 我主要是做一些补充记录 1、Windows的右键等于mac的双击触控板、control单击触控板 2、运行中的应用下方会有一个点&…...

Linux_4_文本处理工具和正则表达式

目录 1文本编辑工具之神VIM1.1 vi和vim简介1.2使用vim1.2.1 vim 命令格式1.2.2三种主要模式和转换 1.3扩展命令模式1.3.1扩展命令模式基本命令1.3.2 地址定界1.3.3查找并替换1.3.4定制vim的工作特性1.3.4.1行号1.3.4.2忽略字符的大小写1.3.4.3白动缩进1.3.4.4复制粘贴保留格式1…...

[Unity]VSCode无代码提示

查看vscode的output窗口&#xff0c;提示加载 csproj 文件失败 It need be converted to new SDK style to work in C# Dev Kit. 把unity的PackageManager里的 Visual Studio Editor 版本升级到2.0.20或以上&#xff0c;重新生成csproj文件就好了。 参考vscode官方&#xff…...

画流程图都可以用哪些工具?

在日常生活中&#xff0c;我相信我们很多人都看到过流程图。对于设计师来说&#xff0c;它还需要涉及流程图来反映用户的旅程和交互方式。那么你知道哪些流行的流程图设计软件呢&#xff1f;作为高级设计师&#xff0c;我今天推荐10款流程图设计软件。你可以和我一起读这篇文章…...

Elasticsearch中倒排索引、分词器、DSL语法使用介绍

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…...

rabbitmq笔记-rabbitmq进阶-数据可靠性,rabbitmq高级特性

消息何去何从 mandatory和immediate是channel.basicPublish方法的两个参数&#xff0c;都有消息传递过程中不可达目的地时将消息返回给生产者的功能。 mandatory参数 true&#xff1a;交换器无法根据自身的类型 和路由键找到符合条件的队列&#xff0c;rabbitmq调用Basic.Re…...

【笔记】判断两个String字符串是否相同(考虑字符串为null的情况)

判断两个字符串是否相同&#xff0c;可用于判断一个字段在逻辑处理前后&#xff0c;值是否有变化。 其中重点是要考虑两个字符串是否有为null的情况&#xff0c;如果其中一个&#xff0c;或者两个都为空&#xff0c;用str1.equals(str2)直接判断&#xff0c;就会报NullPointer…...

【校招VIP】java语言考点之多线程NIO

考点介绍 多线程&NIO考点是校招面试中的常制点之一。 Java NIO是new IO的简称&#xff0c;是一种可以替代Java 10的一套新的IO机制。它提供了一套不同于Java标准1O的操作机制&#xff0c;严格来说&#xff0c;NIO与并发并无直接关系&#xff0c;但是使用NIO技术可以大大提高…...

JVM知识点(一)

1、JVM基础概念 &#xff08;1&#xff09;JVM、JRE、JDK JRE&#xff1a;JVM基本类库组成的运行环境就是JRE。JVM自己是无法完成一次编译&#xff0c;处处运行的&#xff0c;需要有一个基本类库告诉JVM如何操作运行&#xff0c;如如何操作文件&#xff0c;连接网络等&#x…...

网页接口导入postman进行接口请求

postman版本&#xff1a;v10.17.4 一、拷贝接口信息 网页打开开发者工具-networkk&#xff0c;在网页上请求一次接口&#xff0c;鼠标指在接口上&#xff0c;点击鼠标右键-copy-copy as cURL(bash) 二、导入postman 打开postman&#xff0c;点击import-Raw text&#xff0c;…...

【Leetcode】124.二叉树中的最大路径和(Hard)

一、题目 1、题目描述 二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root ,返回其…...