首页 > 其他分享 >RabbitMQ如何保证消息的可靠性

RabbitMQ如何保证消息的可靠性

时间:2023-09-15 17:56:18浏览次数:40  
标签:可靠性 队列 Redis RabbitMQ 投递 重试 保证 消息

RabbitMQ如何保证消息的可靠性
1、保证消息不丢失(三步)
开启事务(不推荐)
开启confirm(推荐)
开启RabbitMQ持久化(交换机、队列、消息)
关闭RabbitMQ自动ack(改成手动)
2、保证消息不重复消费
幂等性 ( 每个消息用一个唯一标识来区分,消费前先判断标识有没有被消费过,若已消费过,则直接 ACK)
3、RabbitMQ如何保证消息的顺序性
将消息放入同一个交换机,交给同一个队列,这个队列只有一个消费者,消费者只允许同时开启一个线程
4、RabbitMQ消息重试机制
消费者在消费消息的时候,如果消费者业务逻辑出现程序异常,这时候应该如何处理?
使用消息重试机制 (SpringBoot 默认 3 次消息重试机制 )
如何合适选择重试机制?
消费者取到消息后,调用第三方接口,接口无法访问,需要使用重试机制
消费者取到消息后,抛出数据转换异常,不需要重试机制,需要发布者进行解决。
5、SpringBoot消息重试机制
@EnableRetry 注解:表示启用重试机制(value 表示哪些异常需要触发重试, maxAttempts 设置最大重试次数,delay 表示重试的延迟时间, multiplier 表示上一次延时时间是这一次的倍数 )
eg 、 @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,
multiplier = 1.5))
@Recover 注解:当重试次数达到设置的最大次数的时候,程序还是执行异常,调用的回调函数。
6、RabbitMQ死信队列
死信队列是当消息在一个队列因为下列原因 :
a 、消息被拒绝 (basic.reject 或 basic.nack) 并且 requeue=false.
b 、消息 TTL 过期
c 、队列达到最大长度 ( 队列满了,数据无法添加到 mq 中 )
变成了 “ 死信队列 ” 后被重新投递 (publish) 到另一个 Exchange ,然后重新消费。说白了就是没有被消费 的消息换个地方重新被消费
7、RabbitMQ解决分布式事务
经典案例,以目前流行的外卖为例,用户下单后,调用订单服务,订单服务调用派单系统通知送外卖人 员送单,这时候订单系统与派单系统采用MQ 异步通讯。
RabbitMQ 解决分布式事务原理
答案:采用最终一致性原理 需要保证以下三要素 :
a 、确保生产者一定要将数据投递到 MQ 服务器中 ( 采用 MQ 消息确认机制 )
b 、确保消费者能够正确消费消息,采用手动 ACK 模式 ( 注意重试、幂等性问题 )
c 、如何保证第一个事务先执行,采用补偿机制,在创建一个补单消费者进行监听,如果订单没有创建成 功,进行补单。( 如果第一个事务中出错,补单消费者会在重新执行一次第一个事务,例如第一个事务是 添加订单表,如果失败在补单的时候重新生成订单记录,由于订单号唯一,所以不会重复)
8、RabbitMQ保证消息不丢失的具体方案
前提 :
(1)开启confirm
(2)开启RabbitMQ的持久化(交换机、队列、消息)
(3)关闭RabbitMQ的自动ack(改成手动)
(4)配置消费重试次数,消费重试间隔时间等
涉及到的技术点:
MQ、Redis、定时任务
8.1、保证投放消息不丢失
(1)先将消息放入生产者Redis(此时消息的状态为未投放),再放入队列
(2)根据confirm(ReturnCallback和ConfirmCallback)的结果来确定消息是否投递成功,
投递成功的,修改生产者redis中消息的投递状态为已投递
投递失败的消息将会放入失败的Redis,并从生产者Redis中删除,由定时任务定期扫描并重新投递
(3)生产者Redis定时任务
生产者Redis定时任务专门扫描生产者Redis中存放了一定时间,但是状态还是未投放的消息
此消息会被认为已经投递,但是没有任何反馈结果(由于不可知因素,导致没有ReturnCallback,也没有 ConfirmCallback),
此类消息被扫描到后,会放入失败的Redis,并从生产者Redis中删除,由定时任务定期扫描并重新投递
(4)还需要一个专门的定时任务扫描生产者Redis中存放了很久,仍然未消费的数据(状态为已投递),此类 消息被扫描到后,会放入失败的Redis,并从生产者Redis中删除,由定时任务定期扫描并重新投递
(5)扫描失败的Redis的定时任务都遵循一条原则,一条消息最多被重新投递三次,若投递了三次仍然失 败,则记录日志,记录到数据库,不会再投递,需要人工干预处理
8.2、保证消费消息不丢失
(1)消费者取到消息后,从消息中取出唯一标识,先判断此消息有没有被消费过,若已消费过,则直接 ACK(避免重复消费)
(2)正常处理成功后,将生产者Redis中的此消息删除,并ACK(告诉server端此消息已成功消费)
(3)遇到异常时,捕获异常,验证自己在消息中设定的重试次数是否超过阀值,若超过,则放入死信队 列,若未超过,则向将消息中的重试次数加1,抛出自定义异常,进入重试机制
(4)有专门的消费者用于处理死信队列中消费多次仍未消费成功的数据,可以记录日志,入库,人工干预 处理
————————————————
版权声明:本文为CSDN博主「powerfuler」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/dingjianmin/article/details/121031996

标签:可靠性,队列,Redis,RabbitMQ,投递,重试,保证,消息
From: https://www.cnblogs.com/faweidd/p/17705622.html

相关文章

  • springboot引入rabbitmq
    RabbitMQ是一个开源的消息代理软件,用于处理应用程序之间的消息传递。SpringBoot是一种让Spring开发变得更简单的工具,你可以使用它来快速地创建基于Spring的应用程序。一、如何在SpringBoot中引入RabbitMQ:首先,你需要在项目的pom.xml文件中添加RabbitMQ的依赖。如果你使用的是Maven......
  • RabbitMQ如果保证消息可靠性
    这是RabbitMQ消息从生产者到消费者的流程。从图中可以看出消息可能在以下几个地方丢失生产者处丢失:消息没有正确到达RabbitMQ的交换机。解决策略:confirm机制RabbitMQ本身将消息丢失:因为一些原因导致RabbitMQ重启,导致内存中的消息丢失。解决策略:消息持久化消费者处丢失:消......
  • RabbitMq
     如何保证消息的可靠性Rabbit消息传输路径是生产者到路由到队列到消费者消费。而Rabbitmq丢消息有以下几种情况1生产者发送消息到RabbitMQ服务器过程中,RabbitMQ服务器如果宕机停止服务,消息会丢失。RabbitMQ是支持消息持久化的,消息持久化需要设置:Exchange为持久化和Queu......
  • MQ消息可靠性等
    RabbitMQ如何保证消息可靠性?首先RabbirMQ是一个开源的支持多协议的性能优秀的消息中间件,他的消息可靠性,消息延迟以及可用性比较高,但是单机消息吞吐量比较一般。消息的可靠性是指,消息准确无误的到达消费者手中,不能出现消息的丢失等问题,消息丢失又分为:①生产者发送消息为到达交换......
  • 保证接口数据安全的10种方案
    前言我们日常开发中,如何保证接口数据的安全性呢?个人觉得,接口数据安全的保证过程,主要体现在这几个方面:一个就是数据传输过程中的安全,还有就是数据到达服务端,如何识别数据,最后一点就是数据存储的安全性。今天跟大家聊聊保证接口数据安全的10个方案。1.数据加密,防止报文明文传输。......
  • RabbitMQ、RocketMQ和Kafka的不同之处
    RabbitMQ、RocketMQ和Kafka是三种常见的消息队列系统,它们在设计和使用方面有一些不同之处:架构设计:RabbitMQ:RabbitMQ是一个基于AMQP(高级消息队列协议)的开源消息队列系统,采用的是传统的Broker架构模式,其中包括生产者、消费者和中间件(Broker)。RocketMQ:RocketMQ是一个基于分布式......
  • 消息队列 RabbitMQ
    发布者:生产者,消息的发送方。连接:网络连接。Channel:信道,多路复用连接中的一条独立的双向数据流通道。Exchange:交换器(路由器),负责消息的路由到相应队列。类型:direct、fanout、topicBinding:队列与交换器间的关联绑定。消费者将关注的队列绑定到指定交换器上,以便Exchange能准确分发消息......
  • RabbitMQ - Exception (504) Reason: "channel id space exhausted"
    使用go的第三方包:github.com/rabbitmq/amqp091-go出现报错:getmqchannelerror{"error":"Exception(504)Reason:channelidspaceexhausted"}ctx:=context.Background()results,err:=global.Redis.LRange(ctx,abListName,0,-1).Result()......
  • rabbitmq详细实例
    1.概述RabbitMQ是由LShift提供的一个AdvancedMessageQueuingProtocol(AMQP)的开源实现,由以高性能、健壮以及可伸缩性出名的Erlang写成,因此也是继承了这些优点。FROM《维基百科——RabbitMQ》Rabbit科技有限公司开发了RabbitMQ,并提供对其的支持。起初,Rabbit......
  • 消息可靠性-生产者确认原理
        ......