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

RabbitMQ讲解与整合

RabbitMq安装

类型概念

租户
RabbitMQ 中有一个概念叫做多租户,每一个 RabbitMQ 服务器都能创建出许多虚拟的消息服务器,这些虚拟的消息服务器就是我们所说的虚拟主机(virtual host),一般简称为 vhost。
每一个 vhost 都是一个独立的小型 RabbitMQ 服务器,这个 vhost 中会有自己的消息队列、消息交换机以及相应的绑定关系等等,并且拥有自己独立的权限,不同的 vhost 中的队列和交换机不能互相绑定,这样技能保证运行安全又能避免命名冲突
交换机
在这里插入图片描述

交换机
属性意义意义
type类型direct默认的直接交换机
根据交换机下队列绑定的routingKey直接匹配
fanout扇形交换机
简单来说就是发布订阅
队列直接绑定在交换机下,统一发布消息
headers头部交换机,通过message header头部信息进行比对
可以根据定义全匹配、部分匹配等规则
topic主题交换机
通过绑定routingKey进行模糊匹配
Durability耐用
(持久化)
durable持久化,数据存放于硬盘
transient瞬态,数据存放于内存
Auto delete自动删除Yes没有绑定队列时自动删除,针对的是曾经有过但后来没有的事物
No不自动删除
Internal内部使用Yes该路由绑定的队列不会被用户消费
No不自动删除

队列

在这里插入图片描述

队列
属性意义意义
type类型Default for virtual host租户配置的默认选项,下列三种其一
默认Classic无需设置
Classic传统的队列类型
数据存储在单个节点上
不具备quorum队列的高可用性和数据保护特性
ps:单机时使用
Quorum高可用性队列
数据会被复制到多个节点
提供更好的数据可靠性和持久性
ps:部署多节点时使用
Stream特殊类型的队列
用于支持事件流处理(event streaming)
具有类似于Kafka的流式处理特性
ps:听说不成熟,暂时用不上
Durability耐用
(持久化)
durable持久化,数据存放于硬盘
transient瞬态,数据存放于内存

参数:

显示参数实际参数作用
Auto expirex-expires设置队列的过期时间,单位为毫秒。当队列在指定时间内未被使用,将会被自动删除
Message TTLx-message-ttl设置队列中消息的过期时间(Time-To-Live),单位为毫秒。消息在队列中存放的时间超过设定的过期时间后会被自动删除
Overflow behaviourx-overflow设置队列溢出行为,可选值为 drop-head(删除最旧的消息)或 reject-publish(拒绝发布新消息)
Single active consumerx-single-active-consumer配置队列是否只允许单个消费者消费消息。当设置了x-single-active-consumer参数时,表示队列只允许有一个消费者活跃地消费消息,其他消费者将被阻塞,直到当前的消费者停止消费或断开连接
Dead letter exchangex-dead-letter-exchange设置队列中的死信消息转发到的交换机名称。当消息成为死信时,将会被转发到指定的交换机
Dead letter routing keyx-dead-letter-routing-key设置死信消息转发时的路由键。死信消息将通过指定的路由键转发到目标交换机
Max lengthx-max-length设置队列的最大长度,即队列中消息的最大数量。当队列中消息数量达到设定的最大长度后,新消息将无法入队
Max length bytesx-max-length-bytes设置队列消息的最大总字节数。当队列中消息的总字节数达到设定的最大值后,新消息将无法入队
Leader locatorx-queue-leader-locator配置队列的领导者(Leader)定位器,集群中使用

SpringBoot整合

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId><version>2.6.3</version>
</dependency>

配置数据源

spring: rabbitmq:addresses: xxx.xxx.xx.xx:5672username: adminpassword: xxxxxxvirtual-host: /

配置交换机和队列

@Component
public class RabbitMqConfig {// 定义交换机名称public static final String FANOUT_EXCHANGE = "fanout.test";@Bean(name = FANOUT_EXCHANGE)public FanoutExchange fanoutExchange() {// 交换机类型按需创建,这里用的是Fanout,发布订阅,绑定在该交换机下的队列都会收到消息// 参数2:是否持久化// 参数3:是否自动删除return new FanoutExchange(FANOUT_EXCHANGE, true, false);}//  定义队列public static final String FANOUT_QUEUE1 = "queue1";@Bean(name = FANOUT_QUEUE1)public Queue fanoutQueue1() {// 后三个不写也行,这是默认值// 参数2:是否持久化数据到磁盘(防止意外关闭数据丢失)// 参数3:是否具有排他性// 参数4:队列不再使用时是否自动删除return new Queue(FANOUT_QUEUE1, true, false, false);}public static final String FANOUT_QUEUE2 = "queue2";@Bean(name = FANOUT_QUEUE2)public Queue fanoutQueue2() {return new Queue(FANOUT_QUEUE2, true, false, false);}@Beanpublic Binding bindingSimpleQueue1(@Qualifier(FANOUT_QUEUE1) Queue fanoutQueue1,@Qualifier(FANOUT_EXCHANGE) FanoutExchange fanoutExchange) {// 将交换机和队列绑定return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}@Beanpublic Binding bindingSimpleQueue2(@Qualifier(FANOUT_QUEUE2) Queue fanoutQueue2,@Qualifier(FANOUT_EXCHANGE) FanoutExchange fanoutExchange) {// 将交换机和队列绑定return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}

测试发一条消息到队列

@SpringBootTest(classes = TemplateApplication.class)
public class RabbitMQTest {@AutowiredRabbitMessagingTemplate rabbitMessagingTemplate;@Testpublic void testSent(){//指定交换机->指定队列(因为创建的交换机是FanoutExchange,所以绑定该交换机的队列都会收到一条消息)rabbitMessagingTemplate.convertAndSend("fanout.test","发送数据到FanoutExchange");// 如果创建队列不绑定交换机和路由键,那么实际上会有默认的交换机和路由键,均为空,直接将消息发送给队列,队列名则和路由键保持一致,仍然可以成功发送消息。}
}

测试接收队列消息

写个监听类接收消息:

@Component
public class RabbitMqListenter {@RabbitListener(queues = {RabbitMqConfig.FANOUT_QUEUE1,RabbitMqConfig.FANOUT_QUEUE2})public void reciveLogAll(String msg) throws Exception {System.out.println("消费到数据:" + msg);}
}

-------------基础的使用到这里就结束了-------------

拓展事项

rabbitMqPusher

自己封装一个更加方便使用的发送工具,可有可无,其中可以使用RabbitMessagingTemplate和RabbitTemplate,RabbitMessagingTemplate和RabbitTemplate都是Spring AMQP提供的用于与RabbitMQ进行交互的工具类如果只是简单使用,那么RabbitMessagingTemplate就够用了,如果需要更精细的控制,可以选择使用RabbitTemplate

,但它们在使用方式和功能上有一些不同点:

RabbitMessagingTemplate:

RabbitMessagingTemplate是MessagingTemplate的子类,用于在Spring应用程序中发送和接收消息。
它提供了一种更高级别的抽象,使得在Spring框架中更容易使用消息发送和接收的功能。
可以直接与Spring的消息通道(MessageChannel)集成,方便进行消息的发送和接收。

RabbitTemplate:

RabbitTemplate是Spring AMQP提供的用于与RabbitMQ进行交互的核心类,提供了丰富的方法来发送和接收消息。
它是一个强大而灵活的工具,可以直接与RabbitMQ的交互进行细粒度的控制。
可以设置消息的属性、监听发送确认、接收确认等功能,更加灵活地处理消息发送和接收的细节。

public interface RabbitMqPublish {void send(String quene, String message);void send(String exchange, String routingKey, String message);void send(String quene, String message, Integer expiration);void send(String exchange, String routingKey, String message, Integer expiration);}
package com.template.rabbitmq.producer.impl;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
@Slf4j
public class RabbitMqPublishImpl implements RabbitMqPublish {@Autowiredprivate RabbitTemplate rabbitTemplate;/*** 发送消息* @param quene   队列名称 或 交换机名称* @param message 消息内容*/public void send(String quene, String message) {rabbitTemplate.send(quene, MessageBuilder.withBody(message.getBytes()).build());log.info("发送消息---> quene:{} ---> message:{}", message, quene);}/*** 直接发送消息到队列* 超过有效期丢弃** @param quene      队列名称* @param message    消息内容* @param expiration 有效期(毫秒)*/public void send(String quene, String message, Integer expiration) {rabbitTemplate.send(quene, MessageBuilder.withBody(message.getBytes()).setExpiration(String.valueOf(expiration)).build());log.info("发送消息---> quene:{} ---> message:{} ---> expiration:{}", quene, message, expiration);}/*** 发送消息* 超过有效期丢弃** @param exchange   交换机名称* @param routingKey 路由键* @param message    消息内容* @param expiration 有效期(毫秒)*/public void send(String exchange, String routingKey, String message, Integer expiration) {rabbitTemplate.send(exchange, routingKey, MessageBuilder.withBody(message.getBytes()).setExpiration(String.valueOf(expiration)).build());log.info("发送消息---> exchange:{} ---> routingKey:{} ---> message:{} ---> expiration:{}", exchange, routingKey, message, expiration);}/*** 发送消息** @param exchange   交换机名称* @param routingKey 路由键* @param message    消息内容*/public void send(String exchange, String routingKey, String message) {rabbitTemplate.send(exchange, routingKey, MessageBuilder.withBody(message.getBytes()).build());log.info("发送消息---> exchange:{} ---> routingKey:{} ---> message:{}", exchange, routingKey, message);}}

在RabbitMQ中,如果队列没有设置过期时间(即没有声明x-message-ttl属性),那么即使在发送消息时设置了消息的过期时间也会失效。消息的过期时间只有在队列设置了过期时间的情况下才会生效。
实测以上列代码的方式直接对消息设置有效期是生效的。

死信队列

和普通队列一样,只不过是对其他队列进行配置,将过期的消息路由到死信队列中。
创建死信交换机和死信路由

	// 配置交换机的文件中继续增加配置public static final String DIRECT_GP_DEAD_LETTER_EXCHANGE = "DIRECT_GP_DEAD_LETTER_EXCHANGE";public static final String DIRECT_GP_DEAD_LETTER_QUEUE = "DIRECT_GP_DEAD_LETTER_QUEUE";@Bean(DIRECT_GP_DEAD_LETTER_EXCHANGE)public DirectExchangedirectDeadLetterExchange() {return new DirectExchange(DIRECT_GP_DEAD_LETTER_EXCHANGE, true, false, new HashMap<>());}@Bean(DIRECT_GP_DEAD_LETTER_QUEUE)public Queue directDeadLetterQueue() {return new Queue(DIRECT_GP_DEAD_LETTER_QUEUE, true, false, false, new HashMap<>());}

设置队列消息有效期并绑定死信队列

	@Bean(name = DIRECT_QUEUE1)public Queue directQueue1() {HashMap<String, Object> headers = new HashMap<>();// 配置消息有效期,消息发送到队列10秒后如果未被消费者消费,则过期headers.put("x-message-ttl",10000);// 配置超期交换机,消息过期后会发送到此交换机headers.put("x-dead-letter-exchange",DIRECT_GP_DEAD_LETTER_EXCHANGE);// 配置超期routingKey,消息过期后转移消息时指定的routingKeyheaders.put("x-dead-letter-routing-key",DIRECT_GP_DEAD_LETTER_QUEUE);// 如果只配置了有效期,未配置交换机和routingKey,则消息会被直接丢弃return new Queue(DIRECT_QUEUE1, true, false, false,headers);}

配置完成后,尝试向DIRECT_QUEUE1发送一条消息,不启动消费者,10秒后消息会自动转移到死信队列中,可在可视化管理界面进行验证。

延时队列
延时队列场景举例:

预定一个会议室,两个小时后开始,要求提前十分钟通知参会人员进行开会。
如果不使用延时队列,那么就需要不断轮询,查看是否到达需要通知的时间,进行消息通知。

延时队列的实现方式:

死信队列+消息有效期
预定时间到提前十分钟通知中间有110分钟,那么创建一条通知消息,设置有效期110分钟丢入队列,不用消费者去监听,等待消息过期后路由到指定的死信队列,再去消费死信队列中的消息即可。
所以延时队列实际上是一种实现方案,而不是一种特定的队列类型。

相关文章:

RabbitMQ讲解与整合

RabbitMq安装 类型概念 租户 RabbitMQ 中有一个概念叫做多租户&#xff0c;每一个 RabbitMQ 服务器都能创建出许多虚拟的消息服务器&#xff0c;这些虚拟的消息服务器就是我们所说的虚拟主机&#xff08;virtual host&#xff09;&#xff0c;一般简称为 vhost。 每一个 vhos…...

python 基础知识点(蓝桥杯python科目个人复习计划56)

今日复习内容&#xff1a;做题 例题1&#xff1a;最小的或运算 问题描述&#xff1a;给定整数a,b&#xff0c;求最小的整数x&#xff0c;满足a|x b|x&#xff0c;其中|表示或运算。 输入格式&#xff1a; 第一行包括两个正整数a&#xff0c;b&#xff1b; 输出格式&#…...

【vue】vue中数据双向绑定原理/响应式原理,mvvm,mvc、mvp分别是什么

关于 vue 的原理主要有两个重要内容&#xff0c;分别是 mvvm 数据双向绑定原理&#xff0c;和 响应式原理 MVC&#xff08;Model-View-Controller&#xff09;&#xff1a; Model&#xff08;模型&#xff09;&#xff1a;表示应用程序的数据和业务逻辑。View&#xff08;视图&…...

基于反光柱特征的激光定位算法思路

目录 1. 识别反光柱2. 数据关联2.1 基于几何形状寻找匹配2.2 暴力寻找匹配 3. 位姿估计&#xff08;最小二乘求解&#xff09;4. 问题4.1 精度问题4.2 快速旋转时定位较差 1. 识别反光柱 反光柱是特殊材料制成&#xff0c;根据激光雷达对反光材料扫描得到的反射值来提取特征。…...

CSM是什么意思?

CSM(Customer Service Management)是企业客户服务管理的信息化&#xff08;IT&#xff09;解决方案架构。本着以客户为中心的管理理念&#xff0c;搭建企业客户服务管理平台&#xff0c;实现企业以客户为中心的管理时代的竞争战略。 CSM的核心是以客户为中心&#xff0c;实现对…...

ES6 面试题

1. const、let 和 var 的区别是什么&#xff1f; 答案&#xff1a; var 声明的变量是函数作用域或全局作用域&#xff0c;而 const 和 let 声明的变量是块级作用域。使用 var 声明的变量可以被重复声明&#xff0c;而 const 和 let 不允许重复声明同一变量。const 声明的变量…...

智能指针(C++)

目录 一、智能指针是什么 二、为什么需要智能指针 三、智能指针的使用和原理 3.1、RALL 3.2 智能指针的原理 3.3、智能指针的分类 3.3.1、auto_ptr 3.3.2、unique_ptr 3.3.3、shared_ptr 3.2.4、weak_ptr 一、智能指针是什么 在c中&#xff0c;动态内存的管理式通过一…...

社区店商业模式探讨:如何创新并持续盈利?

在竞争激烈的商业环境中&#xff0c;社区店要想获得成功并持续盈利&#xff0c;需要不断创新和优化商业模式。 作为一名开鲜奶吧5年的创业者&#xff0c;我将分享一些关于社区店商业模式创新的干货和见解&#xff0c;希望能给想开实体店或创业的朋友们提供有价值的参考。 1、…...

一些可以访问gpt的方式

1、Coze扣子是新一代 AI 大模型智能体开发平台。整合了插件、长短期记忆、工作流、卡片等丰富能力&#xff0c;扣子能帮你低门槛、快速搭建个性化或具备商业价值的智能体&#xff0c;并发布到豆包、飞书等各个平台。https://www.coze.cn/ 2、https://poe.com/ 3、插件阿里…...

springer模板参考文献不显示

Spring期刊模板网站&#xff0c;我的问题是23年12月的版本 https://www.springernature.com/gp/authors/campaigns/latex-author-support/see-where-our-services-will-take-you/18782940 参考文献显示问好&#xff0c;在sn-article.tex文件中&#xff0c;这个sn-mathphys-num…...

【【C语言简单小题学习-1】】

实现九九乘法表 // 输出乘法口诀表 int main() {int i 0;int j 0;for (i 1; i < 9; i){for (j 1; j < i;j)printf("%d*%d%d ", i , j, i*j);printf("\n"); }return 0; }猜数字的游戏设计 #define _CRT_SECURE_NO_WARNINGS 1 #include<stdi…...

mongoDB 优化(1)索引

1、创建复合索引&#xff08;多字段&#xff09; db.collection_test1.createIndex({deletedVersion: 1,param: 1,qrYearMonth: 1},{name: "deletedVersion_1_param_1_qrYearMonth_1",background: true} ); 2、新增索引前&#xff1a; 执行查询&#xff1a; mb.r…...

stable diffusion webUI之赛博菩萨【秋葉】——工具包新手安裝与使用教程

stable diffusion webUI之赛博菩萨【秋葉】——工具包新手安裝与使用教程 AI浪潮袭来&#xff0c;还是学习学习为妙赛博菩萨【秋葉】简介——&#xff08;葉ye&#xff0c;四声&#xff0c;同叶&#xff09;A绘世启动器.exe&#xff08;sd-webui-aki-v4.6.x&#xff09;工具包安…...

鸿蒙应用程序包安装和卸载流程

开发者 开发者可以通过调试命令进行应用的安装和卸载&#xff0c;可参考多HAP的调试流程。 图1 应用程序包安装和卸载流程&#xff08;开发者&#xff09; 多HAP的开发调试与发布部署流程 多HAP的开发调试与发布部署流程如下图所示。 图1 多HAP的开发调试与发布部署流程 …...

C语言数组全面解析:从初学到精通

数组 1. 前言2. 一维数组的创建和初始化3. 一维数组的使用4. 一维数组在内存中的存储5. 二维数组的创建和初始化6. 二维数组的使用7. 二维数组在内存中的存储8. 数组越界9. 数组作为函数参数10. 综合练习10.1 用函数初始化&#xff0c;逆置&#xff0c;打印整型数组10.2 交换两…...

2024-02-28(Kafka,Oozie,Flink)

1.Kafka的数据存储形式 一个主题由多个分区组成 一个分区由多个segment段组成 一个segment段由多个文件组成&#xff08;log&#xff0c;index&#xff08;稀疏索引&#xff09;&#xff0c;timeindex&#xff08;根据时间做的索引&#xff09;&#xff09; 2.读数据的流程 …...

Window下编写的sh文件在Linux/Docker中无法使用

Window下编写的sh文件在Linux/Docker中无法使用 一、sh文件目的1.1 初始状态1.2 目的 二、过程与异常2.1 首先获取标准ubuntu20.04 - 正常2.2 启动ubuntu20.04容器 - 正常2.3 执行windows下写的preInstall文件 - 报错 三、检查和处理3.1 评估异常3.2 处理异常3.3 调整后运行测试…...

第16章-DNS

目录 1. 域名 1.1 产生背景 1.2 概述 1.3 域名的树形层次化结构 2. DNS 2.1 概述 2.2 工作机制 3. DNS查询模式 3.1 递归查询&#xff1a; 3.2 迭代查询&#xff1a; 4. 相关知识点 4.1 集中式DNS 4.2 国内通用DNS 4.3 配置DNS代理 1. 域名 1.1 产生背景 ① IP…...

Leetcoder Day27| 贪心算法part01

语言&#xff1a;Java/Go 理论 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 什么时候用贪心&#xff1f;可以用局部最优退出全局最优&#xff0c;并且想不到反例到情况 贪心的一般解题步骤 将问题分解为若干个子问题找出适合的贪心策略求解每一个子…...

SpringBoot自动配置中bean的加载控制

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

LOOI机器人的技术实现解析:从手势识别到边缘检测

LOOI机器人作为一款创新的AI硬件产品&#xff0c;通过将智能手机转变为具有情感交互能力的桌面机器人&#xff0c;展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家&#xff0c;我将全面解析LOOI的技术实现架构&#xff0c;特别是其手势识别、物体识别和环境…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

Linux 下 DMA 内存映射浅析

序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存&#xff0c;但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程&#xff0c;可以参考这篇文章&#xff0c;我觉得写的非常…...