RabbitMQ高可用

生产者确认

生产者确认就是:发送消息的人,要确保消息发送给了消息队列,分别是确保到了交换机,确保到了消息队列这两步。

1、在发送消息服务的application.yml中添加配置

spring:rabbitmq:publisher-confirm-type: correlated  # 异步回调publisher-returns: truetemplate:mandatory: true

2、确保消息到交换机

package cn.zsh.mq.spring;import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.connection.CorrelationData;
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 org.springframework.util.concurrent.ListenableFutureCallback;import java.util.UUID;@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testConfirmCallBack() {// 1、定义消息String message = "ABC";// 设置一个消息的唯一IDCorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());// 3、confirm-ackcorrelationData.getFuture().addCallback(new ListenableFutureCallback<CorrelationData.Confirm>() {@Overridepublic void onFailure(Throwable ex) {System.out.println("消息发送异常:" + ex.toString());}@Overridepublic void onSuccess(CorrelationData.Confirm result) {if (result.isAck()) {// 说明到了交换机System.out.println("publish-confirm:ack==消息发送成功:" + correlationData.getId());} else {// 消息没有到交换机System.out.println("publish-confirm:nack==消息发送失败:" + correlationData.getId());}}});// 4、消息发送rabbitTemplate.convertAndSend("191exchange","191",message,correlationData);}}

3、确保消息从交换机路由到队列

创建公开CommonConfig类

package cn.zsh.mq.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;/*** 发送消息到交换机没有到消息队列*/
@Slf4j
@Configuration
public class CommonConfig implements ApplicationContextAware {@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 1、获取RabbitTemplate(获取启动中的Bean的方式)RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);// 2、设置回调函数rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {@Overridepublic void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {log.error("发送消息失败,没到队列===消息:{}, 交换机:{}, 路由Key:{}, 响应CODE:{}, 相应内容:{}", message,exchange,routingKey,replyCode,replyText);}});}
}

消息持久化

消息持久化就是:确保消息不会在交换机或者队列中丢失。

案例:

使用SpringAMQP创建出来的交换机和队列,默认就是做了持久化的

package cn.zsh.mq.config;import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** 创建交换机与队列*/
@Component
public class FoundQueue {@Beanpublic DirectExchange qiuExchange(){// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除return new DirectExchange("qiu.deirect",true,false);}@Beanpublic Queue piqiuQueue(){// 使用QueueBuilder构建队列,durable就是持久化的return QueueBuilder.durable("piqiu.queue").build();}
}

消费者确认

消费者确认就是:消费者把消息从队列中获取出来,然后要消费成功,队列中的消息才能被删除掉。

方案一:消费者确认

加入这个配置以后,消费者消费失败,会直接重试或者删除,具体取决于设置的是none还是auto。

默认是none,不建议设置为auto模式因为会一直不断地尝试,这样会导致服务器压力很大。

spring:rabbitmq:listener:simple:acknowledge-mode: auto # none:投递完立马删除  auto:失败后让你再次重试(重新投递到队列)知道成功

方案二:消费者失败重试,重试固定次数后,则删除当前消息

加入这个配置以后,消费者消费失败会重试固定的次数,然后将消息删除。

spring:rabbitmq:listener:simple:retry:enabled: true # 开启消费者失败重试initial-interval: 1000  # 初始的失败等待时长为1秒multiplier: 1 # 下次失败的等待时长倍数,下次等待时长 = multiplier * initial-intervalmax-attempts: 3 # 最大重试次数stateless: true # ture:无状态    false:有状态。如果业务中包含事务,这里改成false

方案三:消费者失败重试,重试固定次数后,将当前消息发送给error交换机路由给error队列

加入这个配置之后,重试固定次数后,会将这条消费失败的消息发送给error交换机,路由给error队列。

1、在消费者(消息接收者)中加入配置

spring:rabbitmq:listener:simple:retry:enabled: true # 开启消费者失败重试initial-interval: 1000  # 初始的失败等待时长为1秒multiplier: 1 # 下次失败的等待时长倍数,下次等待时长 = multiplier * initial-intervalmax-attempts: 3 # 最大重试次数stateless: true # ture:无状态    false:有状态。如果业务中包含事务,这里改成false

2、创建error交换机和队列并绑定

package cn.zsh.mq.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;@Component
public class ErrorConfig {/*** 定义交换机* @return*/@Beanpublic DirectExchange errorExchange2(){return new DirectExchange("error.direct");}/*** 定义队列* @return*/@Beanpublic Queue errorQueue2(){return new Queue("error.queue");}@Beanpublic Binding bindErrorQueue(DirectExchange errorExchange2,Queue errorQueue2){return BindingBuilder.bind(errorQueue2).to(errorExchange2).with("error");}
}

3、在启动类或者配置类中加入配置

package cn.zsh.mq;import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.retry.MessageRecoverer;
import org.springframework.amqp.rabbit.retry.RepublishMessageRecoverer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class ConsumerApplication {public static void main(String[] args) {SpringApplication.run(ConsumerApplication.class, args);}@Beanpublic MessageRecoverer messageRecoverer(RabbitTemplate rabbitTemplate){return new RepublishMessageRecoverer(rabbitTemplate, "error.direct","error");}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Redis的特性ubuntu进行安装

文章目录 1.六大特性1.1内存存储数据1.2可编程1.3可扩展1.4持久化1.5集群1.6高可用1.7速度快 2.具体应用场景&#xff08;了解&#xff09;3.Ubuntu安装Redis3.1安装指令3.2查看状态3.3查找配置文件3.4修改文件内容3.5重启服务器生效3.6安装客户端并进行检查 4.Redis客户端介绍…

本地音乐服务器(三)

6. 删除音乐模块设计 6.1 删除单个音乐 1. 请求响应设计 2. 开始实现 首先在musicmapper新增操作 Music findMusicById(int id);int deleteMusicById(int musicId); 其次新增相对应的.xml代码&#xff1a; <select id"findMusicById" resultType"com.exa…

leetcode【滑动窗口】相关题目分析讲解:leetcode209,leetcode904

经典滑动窗口(leetcode209) 题干 题目难度&#xff1a;简单 题目分析 要求找到符合大于等于target的长度最小的子数组的常规思路便是暴力破解——遍历数组&#xff0c;通过两层遍历&#xff0c;找到最小的子数组并返回。 但显而易见&#xff0c;这样时间复杂度会是O(n2)级…

ArkTS组件结构和状态管理

1. 认识基本的组件结构 ArkTS通过装饰器Component 和Entry 装饰 struct 关键字声明的数据结构&#xff0c;构成一个自定义组件 自定义组件中提供了一个build函数&#xff0c;开发者需要在函数内以链式调用的方式进行基本的UI描述&#xff0c;UI描述的方法请参考UI描述规范srtuc…

语义分割(semantic segmentation)

语义分割(semantic segmentation) 文章目录 语义分割(semantic segmentation)图像分割和实例分割代码实现 语义分割指将图片中的每个像素分类到对应的类别&#xff0c;语义区域的标注和预测是 像素级的&#xff0c;语义分割标注的像素级的边界框显然更加精细。应用&#xff1a…

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…

【母线槽分类与选型】

母线槽是一种高效、安全、节能的输电设备&#xff0c;广泛应用于各类建筑和工业领域。母线槽可以根据不同的分类方式进行划分&#xff0c;例如根据其结构、用途、导体材质等。母线槽以铜或铝作为导体、用非烯性绝缘支撑&#xff0c;然后装到金属槽中而形成的新型导体。在高层建…

一些任务调度的概念杂谈

任务调度 1.什么是调度任务 依赖&#xff1a;依赖管理是整个DAG调度的核心。调度依赖包括依赖策略和依赖区间。 依赖分为任务依赖和作业依赖&#xff0c;任务依赖是DAG任务本身的依赖关系&#xff0c;作业依赖是根据任务依赖每天的作业产生的。两者在数据存储模型上有所不同…

Unifying Top-down and Bottom-up Scanpath Prediction Using Transformers

Abstract 大多数视觉注意力模型旨在预测自上而下或自下而上的控制&#xff0c;这些控制通过不同的视觉搜索和自由观看任务进行研究。本文提出了人类注意力变换器&#xff08;Human Attention Transformer&#xff0c;HAT&#xff09;&#xff0c;这是一个能够预测两种形式注意力…

解决MindSpore-2.4-GPU版本的安装问题

问题背景 虽说在MindSpore-2.3之后的版本中不在正式的发行版中支持GPU硬件后端&#xff0c;但其实在开发分支版本中对GPU后端是有支持的&#xff1a; 但是在安装的过程中可能会遇到一些问题或者报错&#xff0c;这里复现一下我的Ubuntu-20.04环境下的安装过程。 Pip安装 基本的…

【拥抱AI】如何使用BERT等预训练模型计算语义相似度

使用BERT等预训练模型计算语义相似度是一种非常有效的方法&#xff0c;可以捕捉句子之间的深层次语义关系。下面是一个详细的步骤指南&#xff0c;介绍如何使用BERT和Sentence-BERT来计算语义相似度。 1. 环境准备 1.1 安装必要的库 首先&#xff0c;确保你已经安装了必要的…

Excel常用技巧分享

excel单元格内换行 直接按回车会退出当前单元格的编辑&#xff0c;如果需要在单元格中换行&#xff0c;需要按下AltEnter。 excel插入多行或多列 WPS 在WPS中想要插入多行&#xff0c;只需在右键菜单中输入对应的数字即可。 Office Excel excel中相对麻烦一些&#xff0c;比…

C# .NET环境下调用ONNX格式YOLOV8模型问题总结

我的环境是&#xff1a; Visual Studio: 2019 显卡&#xff1a; 一、遇到问题 1、EntryPointNotFoundException:无法在DLL“onnxruntime”中找到名为“OrtGetApiBase”的入口点。差了下原因&#xff0c;入口点是启动项中的问题。 原因&#xff1a;之前用yolov7时安装的版本在C…

【PTA】【数据库】【SQL命令】编程题1

数据库SQL命令测试题1 10-1 显示教工编号以02开头的教师信息 作者 冰冰 单位 广东东软学院 显示教工编号以02开头的教师信息 提示&#xff1a;请使用SELECT语句作答。 表结构: CREATE TABLE teacher ( TId CHAR(5) NOT NULL, -- 教师工号&#xff0c;主键 DId CHAR(2) …

VSCode快速生成vue组件模版

1&#xff0c;点击设置&#xff0c;找到代码片段 2&#xff0c;搜索vue&#xff0c;打开vue.json 3&#xff0c;添加模版 vue2模板 "vue2": {"prefix": "vue2","body": ["<template>"," <div>$0</di…

理解DOM:前端开发的基础

理解DOM 在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;是一个至关重要的概念。它不仅定义了如何通过编程方式访问和修改网页内容&#xff0c;还为我们提供了一种结构化的方式来与页面交互。本文将带你了解DOM的基本概念、不同节点的操作以及何时可以进行更…

如何将几个音频合成一个音频?非常简单的几种合成方法

如何将几个音频合成一个音频&#xff1f;音频合成不仅仅是将不同的音频文件按顺序排列&#xff0c;它还可能涉及到音量调节、剪辑、淡入淡出、音效调整等多个方面。对于一些专业的音频制作人员来说&#xff0c;音频的每一部分细节都可能需要精心打磨&#xff0c;以确保最终合成…

虚拟化表格(Virtualized Table)性能优化

文章目录 功能介绍一开始的代码领导让我们分析一下开始优化如何监听事件和传参&#xff1f;定位操作栏更加优化 功能介绍 菜鸟最近做的一个功能如下&#xff1a; 后端返回两个很大的数组&#xff0c;例如&#xff1a;数组a 1w条&#xff0c;数组b 2w条&#xff0c;然后要操作b…

Orcad 输出有链接属性的PDF

安装adobe pdf安装Ghostscript修改C:\Cadence\SPB_16.6\tools\capture\tclscripts\capUtils\capPdfUtil.tcl ​ 设置默认打印机为 Adobe PDF ​ 将Ghostscript的路径修改正确 打开cadence Orcad &#xff0c;accessories->candece Tcl/Tk Utilities-> Utilities->PD…

从源头保障电力安全:输电线路动态增容与温度监测技术详解

在电力系统中&#xff0c;输电线路是电能传输的关键环节。然而&#xff0c;当导线温度过高时&#xff0c;会加速导线老化&#xff0c;降低绝缘性能&#xff0c;甚至引发短路、火灾等严重事故&#xff0c;对电网安全运行构成巨大威胁。近日&#xff0c;某地区因持续高温和用电负…