四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?

这篇具有很好参考价值的文章主要介绍了四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

如果能确认这两步,那么我们就可以认为消息发送成功了。

如果这两步中任一步骤出现问题,那么消息就没有成功送达,此时我们可能要通过重试等方式去重新发送消息,多次重试之后,如果消息还是不能到达,则可能就需要人工介入了。

经过上面的分析,我们可以确认,要确保消息成功发送,我们只需要做好三件事就可以了:

  1. 确认消息到达 Exchange。

  2. 确认消息到达 Queue。

  3. 开启定时任务,定时投递那些发送失败的消息。

2. RabbitMQ 的努力


上面提出的三个步骤,第三步需要我们自己实现,前两步 RabbitMQ 则有现成的解决方案。

如何确保消息成功到达 RabbitMQ?RabbitMQ 给出了两种方案:

  1. 开启事务机制

  2. 发送方确认机制

这是两种不同的方案,不可以同时开启,只能选择其中之一,如果两者同时开启,则会报如下错误:

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

我们分别来看。以下所有案例都在 Spring Boot 中展开,文末可以下载相关源码。

2.1 开启事务机制

Spring Boot 中开启 RabbitMQ 事务机制的方式如下:

首先需要先提供一个事务管理器,如下:

@Bean

RabbitTransactionManager transactionManager(ConnectionFactory connectionFactory) {

return new RabbitTransactionManager(connectionFactory);

}

接下来,在消息生产者上面做两件事:添加事务注解并设置通信信道为事务模式:

@Service

public class MsgService {

@Autowired

RabbitTemplate rabbitTemplate;

@Transactional

public void send() {

rabbitTemplate.setChannelTransacted(true);

rabbitTemplate.convertAndSend(RabbitConfig.JAVABOY_EXCHANGE_NAME,RabbitConfig.JAVABOY_QUEUE_NAME,“hello rabbitmq!”.getBytes());

int i = 1 / 0;

}

}

这里注意两点:

  1. 发送消息的方法上添加 @Transactional 注解标记事务。

  2. 调用 setChannelTransacted 方法设置为 true 开启事务模式。

这就 OK 了。

在上面的案例中,我们在结尾来了个 1/0 ,这在运行时必然抛出异常,我们可以尝试运行该方法,发现消息并未发送成功。

当我们开启事务模式之后,RabbitMQ 生产者发送消息会多出四个步骤:

  1. 客户端发出请求,将信道设置为事务模式。

  2. 服务端给出回复,同意将信道设置为事务模式。

  3. 客户端发送消息。

  4. 客户端提交事务。

  5. 服务端给出响应,确认事务提交。

上面的步骤,除了第三步是本来就有的,其他几个步骤都是平白无故多出来的。所以大家看到,事务模式其实效率有点低,这并非一个最佳解决方案。我们可以想想,什么项目会用到消息中间件?一般来说都是一些高并发的项目,这个时候并发性能尤为重要。

所以,RabbitMQ 还提供了发送方确认机制(publisher confirm)来确保消息发送成功,这种方式,性能要远远高于事务模式,一起来看下。

2.2 发送方确认机制

2.2.1 单条消息处理

首先我们移除刚刚关于事务的代码,然后在 application.properties 中配置开启消息发送方确认机制,如下:

spring.rabbitmq.publisher-confirm-type=correlated

spring.rabbitmq.publisher-returns=true

第一行是配置消息到达交换器的确认回调,第二行则是配置消息到达队列的回调。

第一行属性的配置有三个取值:

  1. none:表示禁用发布确认模式,默认即此。

  2. correlated:表示成功发布消息到交换器后会触发的回调方法。

  3. simple:类似 correlated,并且支持 waitForConfirms()waitForConfirmsOrDie() 方法的调用。

接下来我们要开启两个监听,具体配置如下:

@Configuration

public class RabbitConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {

public static final String JAVABOY_EXCHANGE_NAME = “javaboy_exchange_name”;

public static final String JAVABOY_QUEUE_NAME = “javaboy_queue_name”;

private static final Logger logger = LoggerFactory.getLogger(RabbitConfig.class);

@Autowired

RabbitTemplate rabbitTemplate;

@Bean

Queue queue() {

return new Queue(JAVABOY_QUEUE_NAME);

}

@Bean

DirectExchange directExchange() {

return new DirectExchange(JAVABOY_EXCHANGE_NAME);

}

@Bean

Binding binding() {

return BindingBuilder.bind(queue())

.to(directExchange())

.with(JAVABOY_QUEUE_NAME);

}

@PostConstruct

public void initRabbitTemplate() {

rabbitTemplate.setConfirmCallback(this);

rabbitTemplate.setReturnsCallback(this);

}

@Override

public void confirm(CorrelationData correlationData, boolean ack, String cause) {

if (ack) {

logger.info(“{}:消息成功到达交换器”,correlationData.getId());

}else{

logger.error(“{}:消息发送失败”, correlationData.getId());

}

}

@Override

public void returnedMessage(ReturnedMessage returned) {

logger.error(“{}:消息未成功路由到队列”,returned.getMessage().getMessageProperties().getMessageId());

}

}

关于这个配置类,我说如下几点:

  1. 定义配置类,实现 RabbitTemplate.ConfirmCallbackRabbitTemplate.ReturnsCallback 两个接口,这两个接口,前者的回调用来确定消息到达交换器,后者则会在消息路由到队列失败时被调用。

  2. 定义 initRabbitTemplate 方法并添加 @PostConstruct 注解,在该方法中为 rabbitTemplate 分别配置这两个 Callback。

这就可以了。

接下来我们对消息发送进行测试。

首先我们尝试将消息发送到一个不存在的交换机中,像下面这样:

rabbitTemplate.convertAndSend(“RabbitConfig.JAVABOY_EXCHANGE_NAME”,RabbitConfig.JAVABOY_QUEUE_NAME,“hello rabbitmq!”.getBytes(),new CorrelationData(UUID.randomUUID().toString()));

注意第一个参数是一个字符串,不是变量,这个交换器并不存在,此时控制台会报如下错误:

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

接下来我们给定一个真实存在的交换器,但是给一个不存在的队列,像下面这样:

rabbitTemplate.convertAndSend(RabbitConfig.JAVABOY_EXCHANGE_NAME,“RabbitConfig.JAVABOY_QUEUE_NAME”,“hello rabbitmq!”.getBytes(),new CorrelationData(UUID.randomUUID().toString()));

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

如何快速更新自己的技术积累?

  • 在现有的项目里,深挖技术,比如用到netty可以把相关底层代码和要点都看起来。
  • 如果不知道目前的努力方向,就看自己的领导或公司里技术强的人在学什么。
  • 知道努力方向后不知道该怎么学,就到处去找相关资料然后练习。
  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?,程序员,rabbitmq,ruby,分布式

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
么学,就到处去找相关资料然后练习。

  • 学习以后不知道有没有学成,则可以通过面试去检验。

我个人觉得面试也像是一场全新的征程,失败和胜利都是平常之事。所以,劝各位不要因为面试失败而灰心、丧失斗志。也不要因为面试通过而沾沾自喜,等待你的将是更美好的未来,继续加油!

以上面试专题的答小编案整理成面试文档了,文档里有答案详解,以及其他一些大厂面试题目

[外链图片转存中…(img-qr3rY2T2-1712415642600)]

[外链图片转存中…(img-Y2TFs646-1712415642601)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-848705.html

到了这里,关于四种策略确保 RabbitMQ 消息发送可靠性!你用哪种?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • rabbitmq消息可靠性之消息回调机制

    rabbitmq消息可靠性之消息回调机制 rabbitmq在消息的发送与接收中,会经过上面的流程,这些流程中每一步都有可能导致消息丢失,或者消费失败甚至直接是服务器宕机等,这是我们服务接受不了的,为了保证消息的可靠性,rabbitmq提供了以下几种机制 生产者确认机制 消息持久

    2024年02月08日
    浏览(39)
  • RabbitMQ消息的可靠性

    面试题: Rabbitmq怎么保证消息的可靠性? 1.消费端消息可靠性保证: 消息确认(Acknowledgements) : 消费者在接收到消息后,默认情况下RabbitMQ会自动确认消息(autoAck=true)。为保证消息可靠性,可以设置autoAck=false,使得消费者在处理完消息后手动发送确认(basicAck)。如果消费

    2024年04月14日
    浏览(60)
  • RabbitMQ-保证消息可靠性

    消息从发送,到消费者接收,会经理多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收到消息后未消费就宕机 针对这些问题,RabbitMQ分别给出了

    2024年02月07日
    浏览(37)
  • RabbitMQ保证消息的可靠性

    消息从发送,到消费者接收,会经理多个过程: 其中的每一步都可能导致消息丢失,常见的丢失原因包括: 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收到消息后未消费就宕机 针对这些问题,RabbitMQ分别给出了

    2024年02月19日
    浏览(39)
  • RabbitMQ如何保证消息可靠性

    目录 1、RabbitMQ消息丢失的可能性 1.1 生产者消息丢失场景 1.2 MQ导致消息丢失 1.3 消费者丢失 2、如何保证生产者消息的可靠性 2.1 生产者重试机制 2.2 生产者确认机制 2.3 实现生产者确认 2.3.1 配置yml开启生产者确认 2.3.2 定义ReturnCallback 2.3.3 定义ConfirmCallback 3、MQ消息可靠性 3.1

    2024年02月20日
    浏览(41)
  • RabbitMQ高级篇---消息可靠性

    1、消息可靠性: 消息从发送到消费者接受,会经历多个过程,每个消息传递的过程都可能导致消息的丢失: 常见的丢失原因: 发送时消息丢失原因: 生产者发送的消息未送达exchange 消息到达exchange后未到达queue MQ宕机,queue将消息丢失 consumer接收到消息后未消费就宕机 Rab

    2024年01月20日
    浏览(40)
  • RabbitMQ消息可靠性(一)-- 生产者消息确认

    目录 前言 一、消息确认流程图 二、生产者消息确认 1、publisher-confirm(发送者确认) 2、publisher-return(发送者回执) 三、代码实现 1、修改application.yml 配置 2、ConfirmCallback函数和ReturnCallback函数 在项目中,引入了RabbitMQ这一中间件,必然也需要在业务中增加对数据安全性的一

    2024年02月04日
    浏览(60)
  • RabbitMQ原理(三):发送者的可靠性

    首先,我们一起分析一下消息丢失的可能性有哪些。 消息从发送者发送消息,到消费者处理消息,需要经过的流程是这样的: 消息从生产者到消费者的每一步都可能导致消息丢失: 发送消息时丢失: 生产者发送消息时连接MQ失败 生产者发送消息到达MQ后未找到 Exchange 生产者

    2024年02月08日
    浏览(23)
  • RabbitMQ 能保证消息可靠性吗

    手把手教你,本地RabbitMQ服务搭建(windows) 消息队列选型——为什么选择RabbitMQ RabbitMQ灵活运用,怎么理解五种消息模型 推或拉? RabbitMQ 消费模式该如何选择 死信是什么,如何运用RabbitMQ的死信机制? 前面我们在做MQ组件选型时,提到了rabbitMQ的消息可靠性,那么它到底可靠

    2024年02月16日
    浏览(35)
  • Rabbitmq怎么保证消息的可靠性?

    一、消费端消息可靠性保证 : 消息确认(Acknowledgements) : 消费者在接收到消息后,默认情况下RabbitMQ会自动确认消息(autoAck=true)。为保证消息可靠性,可以设置autoAck=false,使得消费者在处理完消息后手动发送确认(basicAck)。如果消费者在处理过程中发生异常或者未完成

    2024年04月14日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包