RabbitMQ学习一

RabbitMQ学习

  • RabbitMQ相关概念
  • Virtual host数据隔离
  • SpringAMQP
    • 第一种 基本消息模型
    • 第二种 WorkQueues模型
    • 第三种 发布订阅模型(fanout交换机)
      • fanout交换机实例
    • 第四种 Direct交换机
      • direct交换机实例
      • 基于注解的方式声明——direct交换机
    • 第五种Topic交换机
      • 基于注解的方式声明——Topic交换机
  • 消息转换器
  • 配置JSON转换器

RabbitMQ相关概念

在这里插入图片描述
其中包含几个概念:
1. publisher:生产者,也就是发送消息的一方
2. consumer:消费者,也就是消费消息的一方
3. queue:队列,存储消息。生产者投递的消息会暂存在消息队列中,等待消费者处理
4. exchange:交换机,负责消息路由。生产者发送的消息由交换机决定投递到哪个队列。
5. virtual host:虚拟主机,起到数据隔离的作用(相当于独立的数据库)。每个虚拟主机相互独立,有各自的exchange、queue

Virtual host数据隔离

这里的用户都是RabbitMQ的管理或运维人员。目前只有安装RabbitMQ时添加的itheima这个用户。仔细观察用户表格中的字段,如下:
在这里插入图片描述

  • Name:itheima,也就是用户名
  • Tags:administrator,说明itheima用户是超级管理员,拥有所有权限
  • Can access virtual host: /,可以访问的virtual host,这里的/是默认的virtual host

对于小型企业而言,出于成本考虑,我们通常只会搭建一套MQ集群,公司内的多个不同项目同时使用。这个时候为了避免互相干扰, 我们会利用virtual host的隔离特性,将不同项目隔离。一般会做两件事情:

  • 给每个项目创建独立的运维账号,将管理权限分离。
  • 给每个项目创建不同的virtual host,将每个项目的数据隔离。

创建用户hmall 并分配administrator权限
在这里插入图片描述
此时hmall用户是没有任何virtual host的访问权限
在这里插入图片描述
然后切切换用户hmall进行登录,并给项目创建一个单独的virtual host,进行项目之间的隔离
在这里插入图片描述
由于我们是登录hmall账户后创建的virtual host,因此回到users菜单,你会发现当前用户已经具备了对/hmall这个virtual host的访问权限了:
在这里插入图片描述
之前在virual host为/下创建的队列、交换机就看不到了。

SpringAMQP

RabbitMQ官方提供的Java客户端编码相对复杂,一般生产环境下我们更多会结合Spring来使用。而Spring的官方刚好基于RabbitMQ提供了这样一套消息收发的模板工具:SpringAMQP

  • RabbitMQ提供了6中消息模型,但是第6种RPC,并不属于MQ
  • 其实3、4、5都属于订阅模型,只不过路由的方式不同
    在这里插入图片描述

第一种 基本消息模型

其实就是生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。(可以直接向队列发送消息,跳过交换机)——这种模式比较简单,很少在生产中使用。
在这里插入图片描述

第二种 WorkQueues模型

Work queues,任务模型。简单来说就是让多个消费者绑定到一个队列,共同消费队列中的消息,主要处理消息堆积,可以使用work 模型,多个消费者共同处理消息,消息处理的速度就能大大提高了。
在这里插入图片描述

  • 但WorkQueues 是平均分配给每个消费者,并没有考虑到消费者的处理能力。导致1个消费者空闲,另一个消费者忙的不可开交。没有充分利用每一个消费者的能力
  • 可以在spring中简单的配置,可以解决这个问题,我们修改consumer服务的application.yml文件,添加配置
spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

第三种 发布订阅模型(fanout交换机)

发布订阅模型,添加两个队列,分别各用一个消费者监听,设置一个交换机,类型为广播(fanout),生产者将消息发送给交换机,而交换机将消息投递给所有与本交换机绑定(routingKey)的队列中。
在这里插入图片描述
交换机只能转发消息,不能存储消息,有队列绑定就转发到队列里,没有队列时候,交换机里的消息会立马丢失。

  • 1) 可以有多个队列
  • 2) 每个队列都要绑定到Exchange(交换机)
  • 3) 生产者发送的消息,只能发送到交换机
  • 4) 交换机把消息发送给绑定过的所有队列
  • 5) 订阅队列的消费者都能拿到消息

fanout交换机实例

//发布订阅模式的配置,包括两个队列和对应的订阅者,发布者的交换机类型使用fanout(子网广播),两根网线binding用来绑定队列到交换机
@Configuration
public class FanoutExchangeConfig {

 	@Bean
    public Queue myQueue1() {
       Queue queue=new Queue("queue1");
       return queue;
    }
 	
 	@Bean
    public Queue myQueue2() {
       Queue queue=new Queue("queue2");
       return queue;
    }

	/**
	 * 声明交换机
	 */
	@Bean
 	public FanoutExchange fanoutExchange(){
 		FanoutExchange fanoutExchange=new FanoutExchange("fanout");
 		return fanoutExchange;
 	}
	/**
	 * 绑定队列到交换机上
	 */
 	@Bean
 	public Binding binding1(){
 		Binding binding=BindingBuilder.bind(myQueue1()).to(fanoutExchange());
 		return binding;
 	}
	/**
	 * 绑定队列2到交换机上
	 */
 	@Bean
 	public Binding binding2(){
 		Binding binding=BindingBuilder.bind(myQueue2()).to(fanoutExchange());
 		return binding;
 	}
 	
}

查看交换机
在这里插入图片描述
绑定到交换机下的队列
在这里插入图片描述

第四种 Direct交换机

在Fanout模式中,一条消息,会被所有订阅的队列都消费。但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。
在这里插入图片描述
在Direct模型下:

  • 队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
  • 消息的发送方在 向 Exchange发送消息时,也必须指定消息的 RoutingKey。
  • Exchange不再把消息交给每一个绑定的队列,而是根据消息的Routing Key进行判断,只有队列的Routingkey与消息的 Routing key完全一致,才会接收到消息

direct交换机实例

direct模式由于要绑定多个KEY,会非常麻烦,每一个Key都要编写一个binding:

//direct直连模式的交换机配置,包括一个direct交换机,两个队列,4根网线binding
@Configuration
public class DirectExchangeConfig {
	@Bean
 	public DirectExchange directExchange(){
		DirectExchange directExchange=new DirectExchange("direct");
 		return directExchange;
 	}
	
	@Bean
    public Queue directQueue1() {
       Queue queue=new Queue("directqueue1");
       return queue;
    }
 	@Bean
    public Queue directQueue2() {
       Queue queue=new Queue("directqueue2");
       return queue;
    }
 	//4个binding将交换机和相应队列连起来
 	@Bean
 	public Binding bindingblack2(){
 		Binding binding=BindingBuilder.bind(directQueue1()).to(directExchange()).with("black");
 		return binding;
 	}
	@Bean
	public Binding bindingorange(){
		Binding binding=BindingBuilder.bind(directQueue1()).to(directExchange()).with("orange");
		return binding;
	}
 	@Bean
 	public Binding bindingblack(){
 		Binding binding=BindingBuilder.bind(directQueue2()).to(directExchange()).with("black");
 		return binding;
 	}
 	
 	@Bean
 	public Binding bindinggreen(){
 		Binding binding=BindingBuilder.bind(directQueue2()).to(directExchange()).with("green");
 		return binding;
 	}

}

基于注解的方式声明——direct交换机

基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。

例如,我们同样声明Direct模式的交换机和队列:

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

第五种Topic交换机

Topic类型Exchange可以让队列在绑定BindingKey 的时候使用通配符!
BindingKey 一般都是有一个或多个单词组成,多个单词之间以“ .”分割,例如: item.insert

通配符规则:

  • #:匹配一个或多个词
  • *:匹配不多不少恰好1个词

举例:
item.#:能够匹配item.spu.insert 或者 item.spu
item.*:只能匹配item.spu

在这里插入图片描述

基于注解的方式声明——Topic交换机

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

消息转换器

在数据传输时,它会把你发送的消息序列化为字节发送给MQ,接收消息的时候,还会把字节反序列化为Java对象。 只不过,默认情况下Spring采用的序列化方式是JDK序列化。众所周知,JDK序列化存在下列问题:

  • 数据体积过大
  • 有安全漏洞
  • 可读性差

配置JSON转换器

显然,JDK序列化方式并不合适。我们希望消息体的体积更小、可读性更高,因此可以使用JSON方式来做序列化和反序列化。

在publisher和consumer两个服务中都引入依赖:


<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.10</version>
</dependency>
@Bean
public MessageConverter messageConverter(){
    // 1.定义消息转换器
    Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();
    // 2.配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息
    jackson2JsonMessageConverter.setCreateMessageIds(true);
    return jackson2JsonMessageConverter;
}

消息转换器中添加的messageId可以便于我们将来做幂等性判断。
在consumer服务中定义一个新的消费者,publisher是用什么类型发送,那么消费者也一定要用什么类型接收,格式如下:

@RabbitListener(queues = "object.queue")
public void listenSimpleQueueMessage(Map<String, Object> msg) throws InterruptedException {
    System.out.println("消费者接收到object.queue消息:【" + msg + "】");
}

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

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

相关文章

[原创]Delphi的SizeOf(), Length(), 动态数组, 静态数组的关系.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…

MySQL核心知识点整理大全1-笔记

MySQL 是一种流行的关系型数据库管理系统&#xff0c;它是以C和C语言编写的&#xff0c;最初是由瑞典公司MySQL AB开发的&#xff0c;现在是由Oracle公司维护和支持。MySQL是开源软件&#xff0c;可在Windows、Linux、Mac OS、FreeBSD等各种操作系统上运行。MySQL的主要特点是速…

图像增强与复原、车牌检测与识别,交通最优路径搜索模型,并且基于PyQt完成GUI设计

背景&#xff1a; 综合实训教学大纲 一、实训科目设置&#xff1a; 序号 内容提要 教学 条件 一 图像增强与复原、车牌检测与识别&#xff0c;并且基于PyQt完成GUI设计 计算机、Python软件 二 交通最优路径搜索模型&#xff0c;并且基于PyQt完成GUI设计 计算机、Pytho…

[每周一更]-(第75期):Go相关粗浅的防破解方案

Go作为编译语言&#xff0c;天然存在跨平台的属性&#xff0c;我们在编译完成后&#xff0c;可以再不暴露源代码的情况下&#xff0c;运行在对应的平台中&#xff0c;但是 还是架不住有逆向工程师的反编译、反汇编的情形&#xff1b;&#xff08;当然我们写的都不希望被别人偷了…

ringboot-cve_2021_21234:latestSpring Boot 目录遍历 (CVE-2021-21234)漏洞复现

Spring Boot 目录遍历 &#xff08;CVE-2021-21234&#xff09;漏洞复现 Spring-boot-actuator-logview 0.2.13之前版本存在路径遍历漏洞&#xff0c;攻击者可通过该缺陷读取系统任意文件。 名称: Spring Boot 目录遍历 &#xff08;CVE-2021-21234&#xff09; 描述: Sprin…

【Java 基础】13 异常

1.异常是什么 异常是指在程序运行过程中可能发生的、与正常执行流程不符的事件。这些事件可能包括错误、不合理的输入、资源不足等。在 Java 中&#xff0c;异常是通过 throw 语句抛出的&#xff0c;可以是 Java 内置的异常类&#xff0c;也可以是自定义的异常类。 2. 异常类…

12月01日,每日信息差//阿里国际发布3款AI设计生态工具//美团买菜升级为“小象超市”//外国人永居证换新、6国游客免签来华

_灵感 &#x1f396; 阿里国际发布3款AI设计生态工具 &#x1f384; AITO问界系列11月交付新车18827辆 &#x1f30d; 美团买菜升级为“小象超市” &#x1f30b; 全球首个金融风控大模型国际标准出炉&#xff0c;由腾讯牵头制定 &#x1f381; 支付宝&#xff1a;支持外国人…

【代码】基于算术优化算法(AOA)优化参数的随机森林(RF)六分类机器学习预测算法/matlab代码

代码名称&#xff1a;基于算术优化算法&#xff08;AOA&#xff09;优化参数的随机森林&#xff08;RF&#xff09;六分类机器学习预测算法/matlab代码 使用算术优化算法&#xff08;AOA&#xff09;优化分类预测模型的参数&#xff0c;收敛性好&#xff0c;准确率提升明显&am…

中职组网络安全-web-PYsystem003.img-(环境+解析)

​ web安全渗透 1.通过URL访问http://靶机IP/1&#xff0c;对该页面进行渗透测试&#xff0c;将完成后返回的结果内容作为flag值提交&#xff1b; 访问该网页后发现F12被禁用&#xff0c;使用ctrlshifti查看 ctrlshifti 等效于 F12 flag{fc35fdc70d5fc69d269883a822c7a53e}…

二叉树刷题Leetcode

文章目录 104.二叉树的最大深度100.相同的树965.单值二叉树 104.二叉树的最大深度 int maxDepth(struct TreeNode* root) {if(rootNULL)return 0; int left1maxDepth(root->left); int right1maxDepth(root->right); return left>right?left:right; }处理二叉树最大深…

分享88个清新唯美PPT,总有一款适合您

分享88个清新唯美PPT&#xff0c;总有一款适合您 88个清新唯美PPT下载链接&#xff1a;https://pan.baidu.com/s/1XUUjxjmWFw2fJKENjk6_Yg?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整…

unicloud云函数url化后,客户端通过url地址向云函数发送数据流并传递到云存储中

在不久前录制过这样一门课程&#xff0c;使用uniapp生态开发API接口&#xff0c;通过这套课程&#xff0c;你不需要后后端Java、Python、PHP等后端语言&#xff0c;你只需要用前端的知识就可以构建这样一套API接口&#xff0c;而且使用uniapp生态开发接口更简单高效&#xff0c…

VMware17 下载、安装、成功安装效果、完整卸载

VMware17 下载、安装、卸载 下载 VMware17 安装 更改安装路径 去掉这两个复选框&#xff0c;点击安装。 安装结束&#xff0c;点击许可证。 输入序列号&#xff0c;点击【输入】 序列号&#xff1a;MC60H-DWHD5-H80U9-6V85M-8280D 点击完成 测试安装效果 永不过期&am…

跨模态图像翻译:使用具有感知监督的多生成网络合成MR脑图像的CT图像

Cross-modality image translation: CT image synthesis of MR brain images using multi generative network with perceptual supervision 跨模态图像翻译&#xff1a;使用具有感知监督的多生成网络合成MR脑图像的CT图像背景贡献实验方法损失函数Thinking 跨模态图像翻译&…

【已解决】Cannot find project Scala library 2.11.8 for module XXX

问题描述 在 flink 示例程序调试过程中&#xff0c;reload project 报错 Cannot find project Scala library 2.11.8 for module HbasePrint 报错如下图所示&#xff1a; 问题解决 经过搜索&#xff0c;初步判定是 pom 文件中 Scala 版本配置和项目中实际使用的版本不一致导…

java+springboot停车场小区车库租赁预订系统ssm+jsp

该平台为客户和业主提供等信息服务平台的运营方&#xff0c;管理方&#xff0c;如何通过车库平台建立实现优化管理的方法提供参考。能够实现在一个相对广阔的地域内&#xff08;例如一座城市)的多个停车场的随意停车。管理平台会统一调度车位资源&#xff0c;自动进行交易结算。…

【开源】基于JAVA的大病保险管理系统

项目编号&#xff1a; S 031 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S031&#xff0c;文末获取源码。} 项目编号&#xff1a;S031&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大…

Go语言 值传递

官方说法&#xff0c;Go中只有值传递&#xff0c;没有引用传递 而Go语言中的一些让你觉得它是引用传递的原因&#xff0c;是因为Go语言有值类型和引用类型&#xff0c;但是它们都是值传递。 值类型 有int、float、bool、string、array、sturct等 引用类型有slice&#xff0c…

掌握自动化测试必要的几种技能?

1.自动化测试员技能——编程语言 当我开始担任手动测试人员时&#xff0c;我不喜欢编码。但是&#xff0c;当我逐渐进入自动化领域时&#xff0c;对我来说很清楚&#xff0c;如果没有对编程语言的一些基本了解&#xff0c;就无法编写逻辑自动化测试脚本。 对编程有一点了解&a…

MinkowskiEngine安装

pip install torch ninjagit clone https://github.com/NVIDIA/MinkowskiEngine.git cd MinkowskiEngine安装之前先把并行安装的thread数降低&#xff0c;否则会导致进程卡死。 打开setup.py文件内位于142行的MAX_COMPILATION_THREADS变量值从12改成4。 export CXXg-7 python…