RabbitMq的使用

最近处理访客记录所以,来学习下rabbitMQ。之前同事已经写好了,这里只需要进行消费,后续会逐渐完善。

0.介绍

0.1交换机(Exchanges)

rabbitmq中生产者发送的消息都是发送到交换机,再由交换机推入队列。所以生产者不知道队列去了哪里,就靠Exchage来控制,交换机总共有以下几种类型。

0.1.1广播模式(fanout)

扇出所有消息进入队列,类似广播。

0.1.2直接交换(direct)

绑定相关的routerKey分发到不同的队列,简单说就是direct交换机接收了消息后,根据关键词分发队列。

0.1.2主题模式(topic)

direct路由比较单一,所以提升了routerKey的能力,在关键词标记下加上了通配符。
*(星号)可以代替一个单词
#(井号)可以替代零个或多个单词

1.公共配置类

spring:rabbitmq:host: 127.0.0.1port: 5672username: guestpassword: guest
/*** 类描述:RabbitMQ公共配置类** @ClassName RabbitMQConfig* @Author ward* @Date 2023-08-18 10:28*/
public class RabbitMQConfig {/*** RabbitMQ的队列主题名称*/public static final String RABBITMQ_TOPIC = "rabbitmqTopic";/*** RabbitMQ的DIRECT交换机名称*/public static final String RABBITMQ_DIRECT_EXCHANGE = "rabbitmqDirectExchange";/*** RabbitMQ的Direct交换机和队列绑定的匹配键 DirectRouting*/public static final String RABBITMQ_DIRECT_ROUTING = "rabbitmqDirectRouting";
}

2.消费消息的两种方式

把记录塞进队列里的时候,只是完成了第一步,那你肯定要对他进行消费。分为两种推模式和拉模式:推模式就是生产者发布消息时,主动推送给消费者;拉模式则是消费者发送请求后才会发送。

2.1


3.监听队列的两种方式

一种是@RabbitListener注解的方式,一种是实现springboot:ChannelAwareMessageListener接口的方式

3.1@RabbitListener

如果demoData想不转换成String直接推,得在这个数据流实现序列化。

innerRabbitTemplate.convertAndSend(InnerMQConfig.TOPIC_EXCHANGE, msgKey, JSONObject.toJSONString(demoData));
@Component
public class DemoRabbitMQListener {//定义方法进行信息的监听(queues表示队列名称)@RabbitListener(queues = "demo_queue")@RabbitHandlerpublic void demoQueue(Message message){System.out.println("message:"+message.getBody());}
}

3.2实现ChannelAwareMessageListener接口

听前辈说直接实现这个接口,就不用管底层是谁的消息队列了,因为是基于Springboot,后续我会逐步求证,做需求只能先用着。这个实现起来有点麻烦,我总结了以下顺序:

3.2.1.创建连接工厂(ConnectionFactory——MQ连接工厂 )

publisherConfirms:消息发送到exchange,返回成功或者失败。
publishReturns:消息从exchange到queue,发送成功或者失败。
后续在DemoRabbitTemplate会演示回调

    @Bean(name = "DemoConnectionFactory")@Primarypublic ConnectionFactory connectionFactory() {//创建连接CachingConnectionFactory connectionFactory = new CachingConnectionFactory();// 主机地址connectionFactory.setHost(host);// 连接端口;默认为 5672connectionFactory.setPort(port);// 连接用户名;默认为guestconnectionFactory.setUsername(username);// 连接密码;默认为guestconnectionFactory.setPassword(password);// 虚拟主机名称;默认为 /connectionFactory.setVirtualHost(virtualHost);// 开启消息发送至RabbitMQ 的回调connectionFactory.setPublisherConfirms(true);// 开启消息发送至队列失败的回调connectionFactory.setPublisherReturns(true);return connectionFactory;}

3.2.2.初始化组件(rabbitAdmin ——对MQ进行初始化的Spring组件)

    @Bean(name = "DemoRabbitAdmin")@Primarypublic RabbitAdmin rabbitAdmin(@Qualifier("DemoConnectionFactory") ConnectionFactory connectionFactory) {RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);// 只有设置为 true,spring 才会加载 RabbitAdmin 这个类rabbitAdmin.setAutoStartup(true);return rabbitAdmin;}

3.2.3.创建交换器(exchange)

这里提供了两种等价的方式,喜欢哪种就用哪种。
durable:是否持久化,RabbitMQ关闭后,没有持久化的Exchange将被清除
autoDelete:是否自动删除,如果没有与之绑定的Queue,直接删除
internal:是否内置的,如果为true,只能通过Exchange到Exchange
arguments:结构化参数
在这里插入图片描述

看了源码之后发现默认只有名字的时候,其实持久化是开的的,自动删除默认就是关闭的。在这里插入图片描述

    /*创建交换器*/@Bean(DEMO_EXCHANGE)public TopicExchange exchange() {return new TopicExchange(DEMO_EXCHANGE, true, false);}
    /*创建交换器*/@Bean(DEMO_EXCHANGE)public Exchange exchange() {return ExchangeBuilder.topicExchange(DEMO_EXCHANGE).durable(true).build();}

3.2.4.创建队列(queue)

创建队列主要掌握这几个参数:
name: 队列名称。
durable: 队列是否持久化。 队列默认是存放到内存中的,rabbitmq重启则丢失,若想重启之后还存在则队列要持久化,保存到Erlang自带的Mnesia数据库中,当rabbitmq重启之后会读取该数据库。
exclusive:是否排他的队列。有两个作用:连接关闭时该队列自动删除;该队列只允许一个消费者访问。
autoDelete:是否自动删除,当最后一个消费者断开连接之后队列是否自动被删除。
arguments: 队列中的消息什么时候会自动被删除 (设置死信交换器和死信队列等设置)
在这里插入图片描述

    /*创建*/@Bean(QUEUE_NAME)public Queue QUEUE_DEMO() {return new Queue(QUEUE_NAME, true, false, false);}

3.2.5.绑定队列到交换机(binding)

    //绑定队列到交换机@Beanpublic Binding BINGING_EXCHANGE_QUEUE(@Qualifier(QUEUE_NAME) Queue queue,@Qualifier(DEMO_EXCHANGE) Exchange exchange) {return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY).noargs();}

3.2.6.创建监听容器(SimpleMessageListenerContainer)

    //创建监听容器@Beanpublic SimpleMessageListenerContainer simpleMessageListenerContainer(@Qualifier("DemoConnectionFactory") ConnectionFactory connectionFactory,DemoRabbitMQListener demoRabbitMQListener,@Qualifier(QUEUE_NAME) Queue queue) throws AmqpException {SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer(connectionFactory);//消费者个数listenerContainer.setConcurrentConsumers(listenerSize);listenerContainer.setQueues(queue);listenerContainer.setExposeListenerChannel(true);//设置接收方式,AUTO-自动接收,MANUAL-手动接收,NULL-不接收listenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO);//监听处理类(自己消费端写的类)listenerContainer.setMessageListener(demoRabbitMQListener);return listenerContainer;}

3.2.7.创建操作类(RabbitTemplate)

setConfirmCallback的消息回调是在生产者端要把参数丢进去的。

    @Bean(name = "DemoRabbitTemplate")@Primary//多个实现类使用该注解public RabbitTemplate rabbitTemplate(@Qualifier("DemoConnectionFactory") ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);//触发setReturnCallback回调必须设置mandatory=true,否则Exchange没有找到Queue就会丢弃掉消息,而不会触发回调rabbitTemplate.setMandatory(true);//设置连接工厂rabbitTemplate.setConnectionFactory(connectionFactory);//消息是否成功发送到Exchange回调rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {/*** 确认消息送到交换机(Exchange)回调* @param correlationData* @param ack* @param cause*/@Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {log.info("确认消息送到交换机(Exchange)结果:");log.info("相关数据:{}", correlationData);boolean ret = false;if (ack) {log.info("消息发送到交换机成功, 消息 = {}", correlationData.getId());//下面可自定义业务逻辑处理,如入库保存信息等} else {log.error("消息发送到交换机失败! 消息: {}}; 错误原因:cause: {}", correlationData.getId(), cause);//下面可自定义业务逻辑处理,如入库保存信息等}}});//消息是否从Exchange路由到QueuerabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {/*** 失败回调:只有消息没有投递给指定的队列* @param message  投递失败的消息详细信息* @param replyCode 回复的状态码* @param replyText 回复的文本内容* @param exchange 当时这个消息发给那个交换机* @param routingKey 当时这个消息用那个路由键*/@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {//获取消息idString messageId = message.getMessageProperties().getMessageId();// 内容String result = null;try {result = new String(message.getBody(), "UTF-8");} catch (Exception e) {log.error("消息发送失败", e);}log.error("消息发送失败, 消息ID = {}; 消息内容 = {}", messageId, result);//下面可自定义业务逻辑处理,如入库保存信息等}});return rabbitTemplate;}

3.2.8.监听消费(RabbitMQListener)

这个类要注意用@Service或者@Compet注解让他交给IOC

@Service
@Slf4j
public class DemoRabbitMQListener implements ChannelAwareMessageListener {@Overridepublic void onMessage(Message message, Channel channel) throws Exception {log.info("message:{}", message.getBody());//todo: 接下来就是各自的业务逻辑,就是消费环节}
}

3.子标题

正文

在这里插入代码片

4.子标题

正文

在这里插入代码片

5.子标题

正文

在这里插入代码片

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

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

相关文章

解决:Appium Inspector刷新页面一直加载转圈

目录 问题:Appium Inspector刷新页面一直加载转圈 解决办法: 1.进入设置页面-电池-后台耗电管理 2.找到下面3个应用,修改为允许后台高耗电 问题:Appium Inspector刷新页面一直加载转圈 1、手机进行操作后,Appium I…

Windows 11 下使用 VMWare Workstation 17 Pro 新建 CentOS Stream 9 64位 虚拟机 并配置网络

文章目录 为什么选择 CentOS Stream 9下载安装访问连接快照克隆网络配置 为什么选择 CentOS Stream 9 CentOS Linux 8: 已经过了 End-of-life (EOL)CentOS Linux 7: EOL Jun 30th, 2024CentOS Stream 8: EOL May 31st, 2024CentOS Stream 9: End of RHEL9 full support phase …

python中的matplotlib画折线图(数据分析与可视化)

先导包(必须安装了numpy 、pandas 和matplotlib才能导包): import numpy as np import pandas as pd import matplotlib.pyplot as plt核心代码: import numpy as np import pandas as pd import matplotlib.pyplot as pltpd.se…

【Linux操作系统】Linux系统编程中信号捕捉的实现

在Linux系统编程中,信号是一种重要的机制,用于实现进程间通信和控制。当某个事件发生时,如用户按下CtrlC键,操作系统会向进程发送一个信号,进程可以捕获并相应地处理该信号。本篇博客将介绍信号的分类、捕获与处理方式…

前端需要理解的HTML知识

HTML(超文本标记语言,HyperText Markup Language)不是编程语言,而是定义了网页内容的含义和结构的标记语言。。“超文本”(hypertext)是指连接单个网站内或多个网站间的网页的链接。HTML 使用“标记”&…

2023年国赛数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林?2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

C语言:选择+编程(每日一练Day6)

目录 ​编辑选择题: 题一: 题二: 题三: 题四: 题五: 编程题: 题一:至少是其他数字两倍的最大数 思路一: 思路二: 题二:两个数组的交集…

C#详解-Contains、StartsWith、EndsWith、Indexof、lastdexof

目录 简介: 过程: 举例1.1 举例1.2 ​ 总结: 简介: 在C#中Contains、StarsWith和EndWith、IndexOf都是字符串函数。 1.Contains函数用于判断一个字符串是否包含指定的子字符串,返回一个布尔值(True或False)。 2.StartsWith函数用于判断一…

将AI融入CG特效工作流;对谈Dify创始人张路宇;关于Llama 2的一切资源;普林斯顿LLM高阶课程;LLM当前的10大挑战 | ShowMeAI日报

👀日报&周刊合集 | 🎡生产力工具与行业应用大全 | 🧡 点赞关注评论拜托啦! 🤖 将AI融入CG特效工作流,体验极致的效率提升 BV1pP411r7HY 这是 B站UP主 特效小哥studio 和 拓星研究所 联合投稿的一个AI特…

01、Cannot resolve MVC View ‘xxxxx前端页面‘

Cannot resolve MVC View ‘xxxxx前端页面’ 没有找到对应的mvc的前端页面。 代码&#xff1a;前端这里引入了 thymeleaf 模板 解决&#xff1a; 需要添加 thymeleaf 的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>s…

Vue3 中引入液晶数字字体(通常用于大屏设计)

一、下载 .ttf 字体文件到本地&#xff0c;放在 src 中的 assets 文件下 下载液晶字体 DS-Digital.ttf 二、在 css 文件中引入字体 /* src/assets/fonts/dsfont.css */ font-face {font-family: electronicFont;src: url(./DS-Digital.ttf);font-weight: normal;font-styl…

Docker关于下载,镜像配置,容器启动,停止,查看等基础操作

系列文章目录 文章目录 系列文章目录前言一、安装Docker并配置镜像加速器二、下载系统镜像&#xff08;Ubuntu、 centos&#xff09;三、基于下载的镜像创建两个容器 &#xff08;容器名一个为自己名字全拼&#xff0c;一个为首名字字母&#xff09;四、容器的启动、 停止及重启…

【中危】Apache Ivy<2.5.2 存在XXE漏洞 (CVE-2022-46751)

漏洞描述 Apache Ivy 是一个管理基于 ANT 项目依赖关系的开源工具&#xff0c;文档类型定义(DTD)是一种文档类型定义语言,它用于定义XML文档中所包含的元素以及元素之间的关系。 Apache Ivy 2.5.2之前版本中&#xff0c;当解析自身配置、Ivy 文件或 Apache Maven 的 POM 文件…

数据结构与算法:通往编程高地的必修课(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

mybatis入门的环境搭建及快速完成CRUD(增删改查)

又是爱代码的一天 一、MyBatis的介绍 ( 1 ) 背景 MyBatis 的背景可以追溯到 2002 年&#xff0c;当时 Clinton Begin 开发了一个名为 iBATIS 的持久化框架。iBATIS 的目标是简化 JDBC 编程&#xff0c;提供一种更直观、易用的方式来处理数据库操作。 在传统的 JDBC 编程中&…

如何再钉钉内跳转自己的网页链接

1.跳转网页转码(工具地址) 原网页:https://www.baidu.com/ 转码后:https%3A%2F%2Fwww.baidu.com%2F 2:地址拼接(官方跳转地址:dingtalk://dingtalkclient/page/link?urlURL&pc_slidetrue) 替换URL: dingtalk://dingtalkclient/page/link?urlhttps%3A%2F%2Fwww.baidu.co…

【Git版本控制工具使用---讲解一】

Git版本控制工具使用 安装设置用户名签名和邮箱Git常用的命令 初始化本地库查看本地状态Git 命令添加暂存区提交本地库查看版本信息修改文件版本穿梭 安装 首先根据自身电脑的配置选择性的安装是32位的还是64位的Git版本控制工具 我这边安装的是64位的 以下是我安装的时候的过…

运维作业7

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。 1&#xff09;拉取mysql5.6和owncloud镜像 2)登录本机ip地址&#xff0c;输入用户名密码 2、安装搭建私有仓库 Harbor 1)安装docker-compose编排工具 2&#xff09;安装harbor [rootserver ~]# tar xf harbor-…

Transformer在医学影像中的应用综述-分类

文章目录 COVID-19 Diagnosis黑盒模型可解释的模型 肿瘤分类黑盒模型可解释模型 视网膜疾病分类小结 总体结构 COVID-19 Diagnosis 黑盒模型 Point-of-Care Transformer(POCFormer)&#xff1a;利用Linformer将自注意的空间和时间复杂度从二次型降低到线性型。POCFormer有200…

数据库结构差异对比工具

简介 前几年写了一个数据库对比工具&#xff0c;但是由于实现方式的原因&#xff0c;数据库支持有限&#xff0c;所以重新设计了一下&#xff0c;便于支持多种数据库&#xff0c;并且更新了UI。 新版地址&#xff1a;https://gitee.com/xgpxg/db-diff 旧版地址&#xff1a;h…