RabbitMQ常见问题持续汇总

news2024/10/25 13:58:00

文章目录

  • 消息分发
    • 不公平分发
    • 限流-basic.qos
      • 主要功能
      • 使用场景
      • 示例代码
  • 消费者默认concurrency数量
    • prefetch和concurrency结合?
  • spring.rabbitmq.template.retry.enabled=true和spring.rabbitmq.listener.simple.retry.enabled=true有什么区别
    • 1. `spring.rabbitmq.template.retry.enabled=true`
    • 2. `spring.rabbitmq.listener.simple.retry.enabled=true`
    • 总结
  • 多机器(集群部署)同时消费某个队列的消息理解
    • 负载均衡
    • 高可用性
    • 和Fanout发布订阅对比理解
  • TODO--持续更新

这篇文章主要是汇总一些杂七杂八的问题,核心内容参考前三章节

RabbitMQ系列文章
深入RabbitMQ世界:探索3种队列、4种交换机、7大工作模式及常见概念
不止于纸上谈兵,用代码案例分析如何确保RabbitMQ消息可靠性?
不止于方案,用代码示例讲解RabbitMQ顺序消费
RabbitMQ常见问题持续汇总

消息分发

不公平分发

RabbitMQ 默认分发消息采用的轮训分发,但是在某种场景下这种策略并不是很好,比方说有两个消费者在处理务,其中有个消费者 1 处理任务的速度非常快,而另外一个消费者 2 处理速度却很慢,这个时候我们还是采用轮训分发的化就会到这处理速度快的这个消费者很大一部分时间处于空闲状态,而处理慢的那个消费者一直在干活,这种分配方式在这种情况下其实就不太好,但是RabbitMQ 并不知道这种情况它依然很公平的进行分发。

为了避免这种情况,我们可以设置参数 channel.basicQos(1); 意思就是如果这个任务我还没有处理完或者我还没有应答你,你先别分配给我,我目前只能处理一个任务,然后 rabbitmq 就会把该任务分配给没有那么忙的那个空闲消费者,当然如果所有的消费者都没有完成手上任务,队列还在不停的添加新任务,队列有可能就会遇到队列被撑满的情况,这个时候就只能添加新的 worker 或者改变其他存储任务的策略。

限流-basic.qos

通过使用 basic.qos 方法设置“预取计数”值来完成的。该值定义通道上允许的未确认消息的最大数量。100 到 300 范围内的值通常可提供最佳的吞吐量,并且不会给消费者带来太大的风险。预取值为 1 是最保守的。

prefetch默认值以前是1,这可能会导致高效使用者的利用率不足。从spring-amqp 2.0版开始,默认的prefetch值是250,这将使消费者在大多数常见场景中保持忙碌,从而提高吞吐量。

basic.qos 是 RabbitMQ 的一个方法,用于设置消息消费的流控(Quality of Service, QoS)。具体来说,它允许你限制在消费者确认(acknowledge)消息之前,RabbitMQ 能够推送给该消费者的消息数量。这样可以防止消费者因为处理不过来而被淹没在大量未处理的消息中。

 com.rabbitmq.client.Channel#basicQos(int, int, boolean)	
	/**
     * 请求对此通道应用特定的prefetchCount“服务质量”设置
     *
     * @param prefetchCount 服务器将交付的最大消息数,如果不限制则为0
     * @throws java.io.IOException 如果遇到错误
     * 
     * 注意: 该方法是基本服务质量机制的一部分,用于流量控制
     * 客户端可以通过设置prefetchCount来避免被服务器压垮
     */
void basicQos(int prefetchCount) throws IOException;

主要功能

配置如下

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        concurrency: 1
        max-concurrency: 3
        # 消费者预取1条数据到内存,默认为250条
		# 消费端限流:每个消费者未确认的未处理消息的最大数量
        prefetch: 1  
  1. 设置预取计数(prefetch count):

    prefetch_countbasic_qos 方法中的一个参数,用于指定消费者可以接收的未确认消息的最大数量。在 RabbitMQ 中,prefetch_count 的值可以是 0 到 65535 之间的任意整数,其中 0 表示无限制 。RabbitMQ 允许为每个消费者独立设置 prefetch_count,而不是像 AMQP 0-9-1 协议中那样在通道级别共享 。

    • basic.qos 允许设置每个消费者在未确认的情况下能接收的最大消息数量。比如,basic.qos(1) 表示每个消费者在没有确认上一条消息之前不会再接收新的消息。这有助于实现公平调度,确保消费者不会被淹没。
  2. 限制消息分发:

    • 当有多个消费者时,basic.qos 通过限制每个消费者处理消息的数量,确保消息分发更均衡。消费者处理完消息并发送确认后,RabbitMQ 才会将新的消息发送给它。
  3. 避免消息堆积:

    • 通过合理设置 prefetch count,可以防止消费者端消息堆积,避免因为过多未处理的消息导致的内存消耗问题。

使用场景

  • 资源密集型任务: 如果你的消费者在处理某些需要消耗较多资源(如CPU、内存)的任务时,需要限制其一次处理的消息数量,以避免资源耗尽。
  • 分布式系统: 在分布式系统中,basic.qos 可以帮助实现更公平的负载均衡,确保每个消费者都能公平地获取消息处理。

示例代码

// 设置每个消费者最多处理3条未确认的消息
channel.basicQos(3);

通过上述设置,RabbitMQ 在每个消费者确认消息前只会推送3条消息,这样就能有效控制消息处理的并发量。

消费者默认concurrency数量

首先说一下concurrency配置,这个配置是设置listener初始化时的线程数,即消费者的数量,即消费者同时消费消息的数量。

那么如果没有显性设置concurrency时,默认的线程数是多少呢,答案是1。

具体的我们可以在源码org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer看到

在这里插入图片描述

prefetch和concurrency结合?

prefetch默认值以前是1,这可能会导致高效使用者的利用率不足。从spring-amqp 2.0版开始,默认的prefetch值是250,这将使消费者在大多数常见场景中保持忙碌,从而提高吞吐量。

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
		# 全局并发设置
		concurrency: 1  
        max-concurrency: 3
        # 消费者预取1条数据到内存,默认为250条
		# 消费端限流:每个消费者未确认的未处理消息的最大数量
        prefetch: 10  

若一个消费者配置prefetch=10,concurrency=2,即会开启2个线程去消费消息,每个线程都会抓取10个线程到内存中(注意不是两个线程去共享内存中抓取的消息)。

concurrency在注解里面可以配置,配置了以后以注解为准,yml里面相当于是全局的

@Component
public class MyConsumer {
  	//会覆盖配置文件中的参数。
    @RabbitListener(queues = {"myQueue"},concurrency ="2")
    public void receiver(Message msg, Channel channel) throws InterruptedException {
 		//...业务处理
    }
 
}

spring.rabbitmq.template.retry.enabled=true和spring.rabbitmq.listener.simple.retry.enabled=true有什么区别

spring.rabbitmq.template.retry.enabled=truespring.rabbitmq.listener.simple.retry.enabled=true 是 Spring AMQP 中配置 RabbitMQ 消息重试机制的两个不同选项,分别用于不同的场景。

1. spring.rabbitmq.template.retry.enabled=true

  • 作用范围: 这个配置用于通过 RabbitTemplate 进行消息发送时的重试机制。
  • 适用场景: 当你在使用 RabbitTemplate 主动发送消息到 RabbitMQ 时,如果消息发送失败(如网络问题、连接超时等),Spring 会自动进行重试。
  • 默认行为: 如果开启了这个选项,RabbitTemplate 会按照配置的重试策略(如重试次数、重试间隔等)自动重试消息发送操作,直到成功或者达到重试上限。
  • 常见使用: 适用于主动调用 RabbitTemplate.convertAndSend() 或类似方法进行消息发送的场景。

2. spring.rabbitmq.listener.simple.retry.enabled=true

  • 作用范围: 这个配置用于在使用消息监听器(Message Listener)时的重试机制,特别是在使用简单消息监听容器(SimpleMessageListenerContainer)时。
  • 适用场景: 当你使用 @RabbitListener 或其他监听机制从队列中接收和处理消息时,如果消息处理失败(如业务逻辑异常),Spring 会按照配置的重试策略自动进行重试。
  • 默认行为: 如果开启了这个选项,当消费者处理消息时抛出异常,Spring 会自动进行重试,直到处理成功或达到最大重试次数。
  • 常见使用: 适用于使用 @RabbitListener 注解来监听队列消息,并希望在处理失败时自动重试的场景。

总结

  • spring.rabbitmq.template.retry.enabled=true 是用于发送消息失败后的重试机制,针对的是消息的生产者(发送端)。
  • spring.rabbitmq.listener.simple.retry.enabled=true 是用于消费消息时处理失败后的重试机制,针对的是消息的消费者(监听端)。

多机器(集群部署)同时消费某个队列的消息理解

对于这个代码,我们的代码在实际业务中是集群部署的,不同的机器都可能去消费这个队列的消息!

public class MessageConsumer {
    @RabbitListener(queues = "queue1")
    public void receiveMessageFromQueue1(String message) {
     // 处理来自queue1的消息
     System.out.println("Received from queue1: " + message);
    }

}

负载均衡

通过多个消费者实例共同消费同一个队列的消息,负载可以均匀分布在所有消费者上,提高整体系统的处理能力。当多个消费者监听同一个队列时,RabbitMQ 会按照轮询的方式将消息分发给这些消费者。每条消息只会被一个消费者消费,这样可以有效地分摊负载,提高系统的吞吐量和可靠性。

假设有两个消费者(Consumer A 和 Consumer B),都监听同一个队列 queue1。RabbitMQ 将会按如下方式分发消息:

  • 消息 1 发送给 Consumer A
  • 消息 2 发送给 Consumer B
  • 消息 3 发送给 Consumer A
  • 依此类推…

高可用性

如果某个消费者实例宕机,RabbitMQ 会自动将新的消息发送给其他存活的消费者,确保消息不会丢失,业务处理不中断。

和Fanout发布订阅对比理解

FanoutExchange 的数据交换策略是把所有到达 FanoutExchange 的消息转发给所有与它绑定的 Queue 上,在这种策略中,routingkey 将不起任何作用,FanoutExchange 配置方式如下:

在这里插入图片描述

也就是说发送一条消息A,假设有队列1、队列2都订阅了这个消息A,那么这监听这两个队列的消费者都会去消费消息A,同时,在集群部署的情况下,对应监听队列1、2的消费者都会有多个,但是每次MQ都会采用负载均衡策略(默认轮询),这样每个队列对应实际只会有一个消费者去消费!

下面展示了消息A被两个队列订阅,并且每个队列有多个消费者,但在负载均衡策略下,每次只有一个消费者去消费消息A的情况。

在这里插入图片描述

如图所示:

  • 消息A被发送到两个队列:队列1和队列2。
  • 每个队列有多个消费者:队列1有消费者1、消费者2和消费者3,队列2有消费者4、消费者5和消费者6。
  • 在负载均衡策略下,每次只有一个消费者去消费消息A。例如,队列1的消息A可能会被消费者1、消费者2或消费者3中的一个消费,队列2的消息A可能会被消费者4、消费者5或消费者6中的一个消费。

TODO–持续更新

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

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

相关文章

中药大数据(二)中药方剂表设计与导入

中药大数据(二)中药方剂表设计与导入 最近在做一个中药大数据的单子,已经爬取到了中药和方剂的数据,现在根据爬取到的数据设计数据库和导入neo4j形成知识图谱。 1 中药方剂数据表设计 爬取到的字段有 方剂名 title 处方 presc…

自动化部署-01-jenkins安装

文章目录 前言一、下载安装二、启动三、问题3.1 jdk版本问题3.2 端口冲突3.3 系统字体配置问题 四、再次启动五、配置jenkins5.1 解锁5.2 安装插件5.3 创建管理员用户5.4 实例配置5.5 开始使用5.6 完成 总结 前言 spingcloud微服务等每次部署到服务器上,都需要本地…

【判断推理】逻辑论证之数量论证

3.1 比例类论证 看比例而不是单看分子! 逻辑类似于抛开剂量谈毒性没有价值。不明确基数大小,单纯比较数量没有价值。 本题中,平民总数可能有1000万,军队综述可能就50万,死亡率不可能相似。 论点:家人吸…

利用Pixabay API获取免费图片和视频的完整指南

视觉内容在吸引受众和有效传达信息方面发挥着举足轻重的作用。然而,获取这些内容往往需要付出高昂的代价。 幸运的是,Pixabay 提供了 440 多万种免费资产,从令人惊叹的照片到引人入胜的视频,所有这些都可以通过其 API 访问。 在…

处理Hutool的Http工具上传大文件报OOM

程序环境 JDK版本: 1.8Hutool版本: 5.8.25 问题描述 客服端文件上传主要代码: HttpRequest httpRequest HttpUtil.createPost(FILE_UPLOAD_URL); Resource urlResource new UrlResource(url, fileName); httpRequest.form("file&q…

nrm之npm镜像源管理工具(NPMRegistryManager)

1. Whats is nrm? 1. 官网地址 https://github.com/Pana/nrm https://www.npmjs.com/package/nrm 2. 关于nrm nrm can help you easy and fast switch between different npm registries, now include: npm, cnpm, taobao, nj(nodejitsu). nrm可以帮助您在不同的 npm 注册表…

智能AI监测系统燃气安全改造方案的背景及应用价值

随着燃气行业的迅速发展和城市化进程的加快,燃气安全管理成为企业运营和城市管理中不可忽视的关键领域。燃气泄漏、管道破损等事故的发生不仅会造成严重的经济损失,还威胁到人民生命财产安全。传统的安全管理方法往往依赖人工巡检和手动监测,…

Discuz发布原创AI帖子内容生成:起尔 | AI原创帖子内容生成插件开发定制

Discuz发布原创AI帖子内容生成:起尔 | AI原创帖子内容生成插件开发定制 在当今互联网快速发展的时代,内容创作成为了网站运营、社交媒体管理和个人博客维护不可或缺的一部分。然而,高质量内容的创作往往耗时耗力,特别是对于需要频…

webpack 老项目升级记录:从 node-sass 限制的的 node v8 提升至支持 ^node v22

老项目简介 技术框架 vue 2.5.17webpack 4.16.5"webpack-cli": "3.1.0""node-sass": "^4.7.2" 几个阶段 第一步:vue2 升级到最新 第一步:升级 vue2 至最新版本,截止到目前(2024-10-…

用js+css实现圆环型的进度条——js+css基础积累

如果用jscss实现圆环型的进度条&#xff1a; 直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><met…

通信协议——UART

目录 基础概念串行&并行串行的优缺点 单工&双工 UART基本概念时序图思考&#xff1a;接收方如何确定01和0011 基础概念 串行&并行 串行为8车道&#xff0c;并行为1车道 串行的优缺点 通行速度快浪费资源布线复杂线与线之间存在干扰 单工&双工 单工&#xf…

vite脚手架中安装和按需引入vuetify

最近想尝试以下vuetify&#xff0c;然后根据chatgpt的引导安装上了&#xff0c;但是谁知道呢&#xff0c;最后打包后的项目&#xff08;里面什么都没写&#xff0c;只是一个vuetify测试页面&#xff09;大小已经超过了5mb&#xff0c;然后我找了很多资料&#xff0c;最终学会了…

【LeetCode】1297、子串的最大出现次数

【LeetCode】1297、子串的最大出现次数 文章目录 一、定长滑动窗口1.1 定长滑动窗口 二、多语言解法 一、定长滑动窗口 1.1 定长滑动窗口 参考 本题, 只需要 考虑 minSize, 而不需要考虑 maxSize 以例1为例: s “aababcaab”, maxLetters 2, minSize 3, maxSize 4 结论: …

[Linux网络编程]05-TCP状态和端口复用,shutdown函数(主动方建立/关闭连接状态,被动方建立/关闭连接状态,2MSL时长,TCP其他状态)

一.TCP状态图表示 netstat -apn | grep client 查看客户端网络连接状态 netstat -apn | grep port 查看端口的网络连接状态 二.主动方&#xff0c;被动方TCP连接状态 1. 主动发起连接请求端&#xff1a; CLOSE – 发送SYN – SEND_SYN – 接收 ACK、SYN – SEND_SYN – 发送 A…

关于VSCode 一运行终端显示一行以后就剩光标的情况

在配置VSCode C的时候&#xff0c;我发现我每次点击运行&#xff0c;终端那显示&#xff1a; 终端被任务重用&#xff0c;按任意键关闭。 然后&#xff0c;后面终端就什么都没有了剩下一个终端在那里瑟瑟发抖&#xff1a; 然后紧接着弹出一个框&#xff1a; 这段说实话&…

Cursor零基础小白教程系列「技巧」 - Cursor 白嫖方案

最适合小白零基础的Cursor教程 网站lookai.top相同作者&#xff0c;最新文章会在网站更新&#xff0c;欢迎收藏书签 Cursor 白嫖方案 - 低调行事 Cursor简介及定价 前面我们提到了cursor 账户有三种性质 Hobby&#xff1a;免费计划&#xff0c;包括两周 Pro 试用期、每月 200…

室内地图制作-电子地图管理系统源代码公开-室内地图 开源-SDK调用指南(二)

一、室内外电子地图可视化制图项目需求 室内外地图开发需满足开发者可以在Android、iOs、web应用中加入地图相关的功能&#xff0c;包括&#xff1a;地图展示、地图交互、在地图上绘制路线、POI点、搜索、AR导航、蓝牙点位、离线地图等功能。 在开源室内地图编辑-电子地图管理…

003:无人机概述

摘要&#xff1a;本文介绍无人机的定义和分类、无人机系统定义、民用无人机驾驶员分类和应用领域。 一、无人机的定义和分类 1.无人机定义 无人机是一种能够在无人驾驶的条件下完成复杂空中飞行任务和各种负载任务的飞行器&#xff0c;可以被视为“空中机器人”。它利用先进的…

在3D Slicer中使用 Monai Bundle 和 Model Zoo 标注医学影像数据-分割肾子结构:皮质髓质和集合系统

文章持续更新&#xff0c;可以关注微公【医学图像人工智能实战营】获取最新动态。人手有限&#xff0c;文中涉及的链接前往微公对应文章查看。关注Tina姐&#xff0c;一起学习进步~ 在3D Slicer中使用 Monai Bundle 和 Model Zoo 标注医学影像数据-分割肾子结构&#xff1a;皮质…

git安装-Tortoise git 安装汉化教程

1. 安装git 2. 安装git图形化工具Tortoise git 3. 汉化 Tortoise git 汉化安装包