解决RabbitMq消息队列Qos Prefetch消息堵塞问题

 更新时间:2022年1月31日 22:54  点击:391 作者:james_searcher

mq是实现代码扩展的有利手段,个人喜欢用概念来学习新知识,介绍堵塞问题的之前,先来段概念的学习。

ConnectionFactory:创建connection的工厂类

Connection: 简单理解为socket

Channel:和mq交互的接口,定义queue、exchange和绑定queue、exhange等接口都是它。

接下来就是和mq的交互类

exchange:简单地看成路由,类型不是重点,看看官网即可

queue:客户端监听的是queue,而不是exchange,但是使用queue的前提要先将exchange和queue绑定。用过java queue工具类应该很容易上手,queue分为写和读,各自可以有自己频率,写得快读得慢,容易堵塞;写得慢读得快又容易造成消费者的空闲。

Prefetc:一个重要却容易被忽略的指标,也是这次遇到的问题。

prefetch与消息投递

prefetch是指单一消费者最多能消费的unacked messages数目。

如何理解呢?

mq为每一个 consumer设置一个缓冲区,大小就是prefetch。每次收到一条消息,MQ会把消息推送到缓存区中,然后再推送给客户端。当收到一个ack消息时(consumer 发出baseack指令),mq会从缓冲区中空出一个位置,然后加入新的消息。但是这时候如果缓冲区是满的,MQ将进入堵塞状态。

更具体点描述,假设prefetch值设为10,共有两个consumer。也就是说每个consumer每次会从queue中预抓取 10 条消息到本地缓存着等待消费。同时该channel的unacked数变为20。而Rabbit投递的顺序是,先为consumer1投递满10个message,再往consumer2投递10个message。如果这时有新message需要投递,先判断channel的unacked数是否等于20,如果是则不会将消息投递到consumer中,message继续呆在queue中。之后其中consumer对一条消息进行ack,unacked此时等于19,Rabbit就判断哪个consumer的unacked少于10,就投递到哪个consumer中。

我遇到的问题是一个粗心的程序员,在编写代码的时候,他对某些消息处理方式是这样的

  if (success) {
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                    } else {
                        logger.error("######### The message is not delete from queue : {}", body);
                    }

首先他讲ack机制设置为手动的,然后他的理解是如果处理成功的消息,就ack给MQ,期望MQ就可以删除完成的数据。不然,保留数据再次被处理。

这里的误区就是就是对ack的理解,失败的时候,如果需要让程序继续处理,应该使用basicNack,并告诉mq将消息再次放入队列

    if (success) {
                            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        } else {
                            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                        }

对于客户端意外宕机的情况,没有ack服务器确实不会删除掉数据,但是consumer重启以后,对于服务器就是一个新的消费者了,也就是它的缓冲区又被重置为原来的n-prefetch,所以这个问题被粗心的小哥想当然地测试通过了。

prefetch的大小应该为多少

这篇文章给了很好的建议,我简单地说一下我的理解。

理想状况下,计算MQ SERVER 从缓冲区中拿到消息并推送到消费端,加上消费端处理完ack消息到MQ server,的时间,假设为100ms,其中消费端处理业务话费了10ms。

这里可以得出我们 prefetch = 100ms / 10ms = 10,也就是消息来回的总时间/业务处理的时间,这里要求我们 prefetch >= 10。一般计算这个时间不会太准确只能毛姑姑的,所以prefetch一般要大一点。但是这个值也不能太大,不然消费端就一只处于空闲状态了。

所以如果你保证所有的消息都ack了,但是还是出现比较长时间的堵塞,你就或者加大一点prefetch,或者多加一些机器,或者减少业务处理的时间了。一开始建议采用或者,使用一个线程池来处理这些业务逻辑。

以上就是解决RabbitMqQosPrefetch消息堵塞问题的详细内容,更多关于RabbitMqQosPrefetch消息堵塞的资料请关注猪先飞其它相关文章!

原文出处:https://blog.csdn.net/james_searcher/article/details/7030856

[!--infotagslink--]

相关文章

  • C#使用RabbitMq队列(Sample,Work,Fanout,Direct等模式的简单使用)

    这篇文章主要介绍了C#使用RabbitMq队列(Sample,Work,Fanout,Direct等模式的简单使用),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-12-08
  • C#操作RabbitMQ的完整实例

    这篇文章主要为大家详细介绍了C#操作RabbitMQ的完整实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • springboot+rabbitmq实现指定消费者才能消费的方法

    当项目部署到测试环境后,QA测试过程中,总是“莫名其妙”的发现所保存的用户付款单数据有问题。这篇文章主要介绍了springboot+rabbitmq实现指定消费者才能消费,需要的朋友可以参考下...2021-11-01
  • SpringMVC和rabbitmq集成的使用案例

    这篇文章主要介绍了SpringMVC和rabbitmq集成的使用案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-20
  • SpringBoot整合RabbitMQ实现消息确认机制

    这篇文章主要介绍了SpringBoot整合RabbitMQ实现消息确认机制,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-31
  • RabbitMQ .NET消息队列使用详解

    这篇文章主要为大家详细介绍了RabbitMQ .NET消息队列使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • 运用.net core中实例讲解RabbitMQ高可用集群构建

    这篇文章主要介绍了运用.net core中实例讲解RabbitMQ高可用集群构建,文中相关示例代码讲解的非常清晰,感兴趣的小伙伴可以参考一下这篇文章,相信可以帮助到你...2021-09-07
  • 关于利用RabbitMQ实现延迟任务的方法详解

    最近在使用RabbitMQ来实现延迟任务的时候发现,这其中的知识点还是挺多的,所以下面这篇文章主要给大家介绍了关于利用RabbitMQ实现延迟任务的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。...2021-09-22
  • C#调用RabbitMQ实现消息队列的示例代码

    这篇文章主要介绍了C#调用RabbitMQ实现消息队列的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • .Net使用RabbitMQ即时发消息Demo

    RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统,下面这篇文章主要给大家介绍了关于.Net使用RabbitMQ即时发消息的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-09-22
  • C#实现rabbitmq 延迟队列功能实例代码

    本篇文章主要介绍了C#实现rabbitmq 延迟队列功能实例代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。...2020-06-25
  • .Net RabbitMQ实现HTTP API接口调用

    RabbitMQ Management插件还提供了基于RESTful风格的HTTP API接口来方便调用。本文就主要介绍了.Net RabbitMQ实现HTTP API接口调用,感兴趣的可以了解一下...2021-09-22
  • .net平台的rabbitmq使用封装demo详解

    这篇文章主要整对rabbitmq学习后封装RabbitMQ.Client的一个分享,文章最后,我会把封装组件和demo奉上,对.net平台的rabbitmq使用封装相关知识感兴趣的朋友一起看看吧...2021-09-14
  • SpringBoot中使用 RabbitMQ的教程详解

    这篇文章主要介绍了SpringBoot中使用 RabbitMQ的教程详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-11-16
  • springboot中rabbitmq实现消息可靠性机制详解

    这篇文章主要介绍了springboot中rabbitmq实现消息可靠性机制详解,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下...2021-09-25
  • 解决SpringMVC项目连接RabbitMQ出错的问题

    这篇文章主要介绍了解决SpringMVC项目连接RabbitMQ出错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-20
  • 运用.NetCore实例讲解RabbitMQ死信队列,延时队列

    这篇文章主要运用.NetCore实例讲解RabbitMQ死信队列,延时队列,,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-22
  • RabbitMQ的配置与安装教程全纪录

    这篇文章主要给大家介绍了关于RabbitMQ的配置与安装的相关资料,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • Docker部署rabbitmq遇到的两个问题

    当使用docker部署rabbitmq时遇到两个问题,访问交换机时报错,另一种是访问channel时报错,本文给大家分享解决方案,感兴趣的朋友跟随小编一起看看吧...2021-07-12
  • RabbitMQ交换机与Springboot整合的简单实现

    这篇文章主要介绍了RabbitMQ交换机与Springboot整合的简单实现,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-07-24