RabbiMQ怎么保证可靠性

RabbiMQ怎么保证可靠性

  • 前言
  • 生产端问题
    • 解决方案
    • 代码
    • 验证
  • RabbitMQ问题
  • 消费端问题
    • 解决方案
    • 代码
    • 验证
  • 总结

前言

RabbitMQ相信大家都非常熟悉了,今天咱们来聊聊怎么保证RabbitMQ的可靠性。

那什么时候会出现问题呢?

第一种是生产端出现的问题。我们向队列中发送消息的时候,消息不一定可以发送到MQ中,这个时候如果我们不做任何处理,这样消息丢失了。

第二种则是RabbitMQ出现的问题。也就是说现在生产端的成功将消息发送到了RabbitMQ,但由于MQ并没有做持久化,这样宕机重启之后消息可能就丢失了。

第三种则是消费端的问题。消费端处理消息时如果出现异常,默认的解决方式是在重复消费多次,当次数超过阈值时直接删除消息,这也导致消息丢失。

接下来咱们就看看怎么应对以上三种问题。

生产端问题

解决方案

这里我们需要清楚发送的一个大体流程。

生产端发送消息到MQ之后,会收到一个结果,这个结果有acknack两种。

其中ack代表消息成功到达了交换机,但并不意味者消息到达了队列。不过ack的情况下消息未送达队列,会有相应的错误信息提醒。

nack就代表消息并未送达交换机

那么,怎么才能知道消息发送情况呢?

可以设置callback来获取消息发送结果。

代码

局部callback设置如下

    @GetMapping("testmq")
    public Result testmq(){
        String orderId = String.valueOf(UUID.randomUUID());
        String messageData = "下订单!";
        String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Map<String,Object> map=new HashMap<>();
        map.put("orderId",orderId);
        map.put("messageData",messageData);
        map.put("createTime",createTime);

//        设置发送的callback
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        correlationData.getFuture().addCallback(result -> {
            // 判断结果
            if (result.isAck()) {
                log.info("发送成功");
            } else {
                log.error("消息未达到交换机,发送失败");
            }
        }, ex -> {
            log.error("出现异常,发送失败");
        });

        rabbitTemplate.convertAndSend(RabbitMQConfig.NORMALEXCHANGE, RabbitMQConfig.TESTROUTING, map, message -> {
            message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            return message;
        }, correlationData);
        return Result.succ("ok");
    }

验证

消息发送成功
在这里插入图片描述
交换机名称有误
在这里插入图片描述
队列路由出错
虽然没有错误,但给了我们warning。
在这里插入图片描述

RabbitMQ问题

这里就比较简单了,那就是做下持久化就可以了

首先是交换机,队列和消息的持久化
交换机

@Bean
    DirectExchange normalExchange() {
        /**
         * durable 是否持久化
         * autoDelete 没有queue绑定时是否自动删除
         */
        return new DirectExchange(NORMALEXCHANGE, true, false);
    }

队列

@Bean
    public Queue cleanDQueue() {
        return QueueBuilder.durable(CLEANQUEUE)
                .build();
    }

消息的持久化

rabbitTemplate.convertAndSend(RabbitMQConfig.NORMALEXCHANGE, RabbitMQConfig.TESTROUTING, map, message -> {
			// 设置消息持久化
           message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            return message;
        }, correlationData);

消费端问题

解决方案

消费端出现错误时,会进行重试,当重试次数超过阈值之后有三种解决方案,如下

  • RejectAndDontRequeueRecoverer:超过阈值,直接丢失消息。
  • ImmediateRequeueMessageRecoverer:超过阈值,返回nack,然后消息重新入队。
  • RepublishMessageRecoverer:超过阈值直接将消费失败的消息投递到指定交换机。

这里我们以RepublishMessageRecoverer为例做下演示。

代码

首先需要声明消费消息失败后传递的交换机和队列

   @Bean
    DirectExchange normalExchange() {
        /**
         * durable 是否持久化
         * autoDelete 没有queue绑定时是否自动删除
         */
        return new DirectExchange(NORMALEXCHANGE, true, false);
    }
//  用于处理消费失败消息的队列
    @Bean
    public Queue republishQueue() {
        return QueueBuilder.durable(REPULISHQUEUE)
                .build();
    }
//  绑定失败消费消息队列
    @Bean
    Binding bindingRepublish() {
        return BindingBuilder.bind(republishQueue()).to(normalExchange()).with(REPULISHROUTING);
    }


然后配置下RepublishMessageRecoverer策略,随便找个config注入下bean就可以。

 //  设置RepublishMessageRecoverer,消费失败的消息转移到另一队列中,交给管理员手动处理
    @Bean
    public MessageRecoverer republishMessageRecoverer(RabbitTemplate rabbitTemplate) {
        /**
         * NORMALEXCHANGE   接收消费失败消息的交换机
         * REPULISHROUTING  接收消费失败消息的路由key
         */
        return new RepublishMessageRecoverer(rabbitTemplate, NORMALEXCHANGE, REPULISHROUTING);
    }

验证

咱们看看如果消费出错会咋样

我们可以看到被消费的队列中信息被删除了。
在这里插入图片描述
然后我们设置的转入队列中的消息数加一,这时候我们可以接收下该队列中的信息,存储到数据库中,方便维护人员手动进行处理。
在这里插入图片描述

总结

从生产端、RabbitMQ以及消费端三方面介绍了一下怎么保证RabbitMQ的可靠性,另外还有关于死信队列和延迟队列的内容在这篇博客中,大家有兴趣可以看一下。

RabbitMQ的死信队列和延迟队列

在这里插入图片描述

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

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

相关文章

CTFHUB-信息泄露-目录遍历和PHPINFO

目录 目录遍历 PHPINFO 目录遍历 很简单&#xff0c;挨着把每个目录都点开看一下 发现2目录下有个 flag.txt 文件&#xff0c;点开发现了本关的flag PHPINFO 这关也很简单&#xff0c;进来之后是一个phpinfo页面&#xff0c;按 CTRL F键打开查询&#xff0c;输入flag&#…

成功解决“ypeError: An Integer Is Required”错误的全面指南

成功解决“ypeError: An Integer Is Required”错误的全面指南 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x…

【科研基础】证明积累

1-Bayesian Estimation (P317) Suppose that x = θ + ν w h e r e ν i s a n N ( 0 , σ ) random variable and θ is the value of a n N ( θ 0 , σ 0 ) random variable θ (Fig. 8-7). Find the bayesian estimate θ o f θ . \begin{align…

神经网络与深度学习——第6章 循环神经网络

本文讨论的内容参考自《神经网络与深度学习》https://nndl.github.io/ 第6章 循环神经网络 给网络增加记忆能力 延时神经网络 有外部输入的非线性自回归模型 循环神经网络 简单循环网络 循环神经网络的计算能力 循环神经网络的通用近似定理 图灵完备 应用到机器学习 序列到类…

用贪心算法计算十进制数转二进制数(小数部分)

在上一篇博文用贪心算法计算十进制数转二进制数&#xff08;整数部分&#xff09;-CSDN博客中&#xff0c;小编介绍了用贪心算法进行十进制整数转化为二进制数的操作步骤&#xff0c;那么有朋友问我&#xff0c;那十进制小数转二进制&#xff0c;可以用贪心算法来计算吗&#x…

支付系统对接商户

target&#xff1a;离开柬埔寨倒计时-214day 还是美女作为开篇 前言 昨天没有写文章&#xff0c;因为部门团建&#xff0c;我得去给他们画饼&#xff0c;说起来也真的是唏嘘&#xff0c;我一个已经都在计划着离开柬埔寨的人&#xff0c;昨天聚餐还一个个给他们描述未来的前景&a…

5G无线标准演进综述及新技术引入

摘 要 随着经济和社会的发展&#xff0c;5G业务越来越丰富多彩&#xff0c;1080P高清视频、裸眼3D、网联汽车、云手机等新业务、新终端对网络的要求也越来越高&#xff1b;另一方面&#xff0c;5G标准持续演进&#xff0c;在MIMO、载波聚合、移动性管理、uRLLC、切片、定位等方…

海思SD3403,SS928/926,hi3519dv500,hi3516dv500移植yolov7,yolov8(19)-Yolov10探索

YOLOv10 开源有几天了,看性能是比较强的,但是试过的一些人说没有YOLOv8好,实际效果以测试结果为准,这里创新点算是去掉了之前YOLO的NMS步骤,论文题目也说了NMS-Free,以此来提高小目标检测率,减少计算冗余,也没有NMS的计算时间提高实时性。 这个倒是让我看到了以后可以…

以sqlilabs靶场为例,讲解SQL注入攻击原理【18-24关】

【less-18】 打开时&#xff0c;获取了自己的IP地址。&#xff0c;通过分析源码知道&#xff0c;会将用户的user-agent作为参数记录到数据库中。 提交的是信息有user-Agent、IP、uname信息。 此时可以借助Burp Suite 工具&#xff0c;修改user_agent&#xff0c;实现sql注入。…

STM32之USART(串口)通信学习

1.通信接口 在开始通信之前&#xff0c;我们要了解什么是通信&#xff0c;通信就是将一个设备的数据传送到另一个设备。 同时按照双方规定的协议即通信协议&#xff0c;指定通信规则通信双方按照规则进行数据的收发。 应用场景&#xff1a;单片机的串口可以使单片机与单片机…

软件架构设计属性之5:可维护性属性分析与应用

文章目录 引言一、可维护性定义和重要性1.1 定义1.2 重要性 二、可维护性关键要素2.1 模块化2.2 单一职责2.3 低耦合2.4 高内聚2.5 抽象和封装2.6 实践建议 三、设计原则3.1 开闭原则3.2 依赖倒置原则3.3 评估方法3.4 挑战与解决方案 四、实战应用总结 引言 在当今数字化飞速发…

利用GNSS IMU集成提高车道级定位精度

准确的定位对于很多不同的事情都是至关重要的。导航系统可以引导我们去某个地方&#xff0c;自动驾驶汽车可以利用这些数据在道路上安全行驶。尽管全球导航卫星系统(GNSS)在定位方面非常出色&#xff0c;但它们可能并不总是提供最准确的车道水平事实。解决这个问题的一个有希望…

大模型对齐方法笔记四:针对领域问答来进行知识对齐方法KnowPAT

KnowPAT KnowPAT(Knowledgeable Preference AlignmenT) 出自2023年11月的论文《Knowledgeable Preference Alignment for LLMs in Domain-specific Question Answering》&#xff0c;主要针对领域问答来进行知识对齐。 在领域问答有两个挑战&#xff1a;希望输出满足用户的要…

15-通过JS代码处理窗口滚动条

selenium并不是万能的&#xff0c;页面上有些操作无法实现时&#xff0c;就需要借助JS代码来完成了。selenium提供了一个方法&#xff1a;execute_script()&#xff0c;可以执行JS脚本代码。 比如&#xff1a;当页面上的元素超过一屏后&#xff0c;想操作屏幕下方的元素&#x…

git报错prohibited by Gerrit: not permitted: update

git push报错&#xff1a; Push to refs/for/[branch] to create a review, or get Push rights to update the branch. Contact an administrator to fix the permissions (prohibited by Gerrit: not permitted: update)原因&#xff1a; 使用Gerrit代码审核时&#xff0c;本…

IsoBench:多模态基础模型性能的基准测试与优化

随着多模态基础模型的快速发展&#xff0c;如何准确评估这些模型在不同输入模态下的性能成为了一个重要课题。本文提出了IsoBench&#xff0c;一个基准数据集&#xff0c;旨在通过提供多种同构&#xff08;isomorphic&#xff09;表示形式的问题&#xff0c;来测试和评估多模态…

React-表单受控绑定

概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 1.准备一个React状态值 2.通过value属性绑定状态&#xff0c;通过onChange属性绑定状态同步的函数

Web自动化测试-掌握selenium工具用法,使用WebDriver测试Chrome/FireFox网页(Java

目录 一、在Eclipse中构建Maven项目 1.全局配置Maven 2.配置JDK路径 3.创建Maven项目 4.引入selenium-java依赖 二、Chrome自动化脚本编写 1.创建一个ChromeTest类 2.测试ChromeDriver 3.下载chromedriver驱动 4.在脚本中通过System.setProperty方法指定chromedriver的…

《软件方法(下)》8.3.4.5和《设计模式》中用语的区别

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 8.3 建模步骤C-2 识别类的关系 8.3.4 识别关联关系 8.3.4.4 类关系再整理 有了前面的知识&#xff0c;我们需要再整理一下类的关系。用类图表示类的关系如图8-134。 图8-134 “类的…

NextJs 数据篇 - 数据获取 | 缓存 | Server Actions

NextJs 数据篇 - 数据获取 | 缓存 | Server Actions 前言一. 数据获取 fetch1.1 缓存 caching① 服务端组件使用fetch② 路由处理器 GET 请求使用fetch 1.2 重新验证 revalidating① 基于时间的重新验证② 按需重新验证revalidatePathrevalidateTag 1.3 缓存的退出方式 二. Ser…