RabbitMq--- 惰性队列

news2024/10/6 22:32:13

前言

消息堆积是Mq消费时常见的问题,这里我们展开说一下消息堆积的原因,以及RabbitMq 中是如何解决这个问题的。

1. 消息堆积问题

当生产者发送消息时的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。最早收到的消息,可能会成为死信,会被丢弃,这就是消息堆积问题。
在这里插入图片描述
解决消息堆积有三种思路:

  • 增加更多的消费者,提高消费速度
  • 在消费者内开启线程池加快消息处理速度
  • 扩大队列容积,提高堆积上限

RabbitMq 中解决消息堆积的思路是扩大队列容积,但是它把消息存储从内存中剥离出来,使用了磁盘。

2. 惰性队列

在 RabbitMq 的 3.6.0 版本开始,就增加了 Lazy Queues 的概念,也就是惰性队列,惰性队列的特征如下:

  • 接收到消息后直接存入磁盘而非内存
  • 消费者消费消息时才会从磁盘中读取并加载到内存
  • 支持百万条的消息存储

2.1 命令行设置

设置一个队列为惰性队列,只需要在声明队列时,指定 x-queue-mode 属性为 lazy 即可。可以通过命令将一个运行中的队列修改为惰性队列

rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues  
  • rabbitmqctl: RabbitMq 的命令行工具
  • set_policy: 添加一个策略
  • Lazy: 策略名称,可以自定义
  • ^lazy-queue$: 用正则表达式匹配队列的名字
  • {“queue-mode”:“lazy”}: 设置队列模式位 lazy 模式
  • –apply-to queues: 策略的作用对象,是所有的队列

而 SpringAMQP 中声明惰性队列分为两种方式, 一种是@Bean 的方式,一种是基于注解的方式

2.2 基于@Bean 的方式

使用 .lazy( ) 开启x-queue-mode为lazy

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** 惰性队列配置 */
@Configuration
public class LazyConfig {

    /** 惰性队列 - 增加了.lazy()属性 */
    @Bean
    public Queue lazyQueue() {
        return QueueBuilder.durable("lazy.queue")
                .lazy() // 开启x-queue-mode为lazy
                .build();
    }
	
	/** 正常队列 */
	@Bean
	public Queue normalQueue()
	{
		return QueueBuilder.durable("normal.queue")
			.build();
	}
}

2.3 基于注解方式:

在消费者端的消息监听中新增方法
使用 @Argument 来标注使用参数的key 和对应参数的值 value

@RabbitListener(queuesToDeclare = @Queue(
        name = "lazy.queue",
        durable = "true",
        arguments = @Argument(name = "x-queue-mode", value = "lazy")
))
public void listenLazyQueue(String msg) {
    log.info("接收到 lazy.queue 的消息:{}", msg);
}

3. 案例测试

这里对正常队列和惰性队列进行十万条数据的测试,启动consumer服务,在publisher服务的SpringAmqpTest类中新增下列两个方法:

/** 测试惰性队列 */
@Test
public void testLazyQueue() throws InterruptedException {
    // 模拟发送十万条数据
    long b = System.nanoTime();
    for (int i = 0; i < 1000000; i++) {
        // 1.准备消息
        Message message = MessageBuilder
                .withBody("hello, LazyQueue".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT) // 改成非持久化,可以看一下LazyQueue的效果
                .build();
        // 2.发送消息
        rabbitTemplate.convertAndSend("lazy.queue", message);
    }
    long e = System.nanoTime();
    System.out.println(e - b);
}

/** 测试正常队列 */
@Test
public void testNormalQueue() throws InterruptedException {
    // 模拟发送十万条数据
    long b = System.nanoTime();
    for (int i = 0; i < 1000000; i++) {
        // 1.准备消息
        Message message = MessageBuilder
                .withBody("hello, Spring".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT) // 改成非持久化,可以看一下正常队列的效果
                .build();
        // 2.发送消息
        rabbitTemplate.convertAndSend("normal.queue", message);
    }
    long e = System.nanoTime();
    System.out.println(e - b);
}

RabbitMQ控制台队列的数据变化:

  • 初始化:
    在这里插入图片描述

  • 运行两个生产者方法后,看一下两个队列总览
    在这里插入图片描述

  • 惰性队列数据变化 (全部一进来就会存储到磁盘,内存中只有需要消费的)
    在这里插入图片描述

  • 正常队列数据变化:
    而正常队列都在内存中(这里是没有开启持久化的情况)

    在这里插入图片描述

4. 总结

消息堆积问题的解决方案?

  • 队列上绑定多个消费者,提高消费速度
  • 给消费者开启线程池,提高消费速度
  • 使用惰性队列,可以在 mq 中保存更多消息

惰性队列的优点有哪些?

  • 基于磁盘存储,消息上限高
  • 没有间隙性的 page-out, 性能比较稳定

惰性队列的缺点有哪些?

  • 基于磁盘存储,消息时效性会降低
  • 性能受限于磁盘的 IO

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

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

相关文章

【Linux】shell脚本—正则表达式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、正则表达式概述二、基本的正则表达式三、操作演示 一、正则表达式概述 正则表达式是对字符串操作的一种逻辑公式&#xff0c;就是用事先定义好的一些特定字符、…

WIN11+CLion+CMake+MINGW+OPENCV编译需注意问题

安装编译教程可参考以下链接&#xff1a; CLion OpenCV cmake&#xff0c;源码编译及使用_clion编译opencv_拜阳的博客-CSDN博客 使用CLion开发openCV——环境搭建全记录_-Willing-的博客-CSDN博客 此文主要是记录自己在编译过程中遇到的问题和解决方法 1、版本问题 C…

Windows 10 主机上的 VMware Workstation 和设备/凭据防护不兼容“错误

Windows 10 主机上的 VMware Workstation 和设备/凭据防护不兼容“错误 VMware Workstation 和 Device/Credential Guard 不兼容。VMware 工作站可以在禁用设备/凭据防护后运行。 排查错误的过程&#xff1a; 要解决错误&#xff0c;请按照以下步骤操作&#xff1a; 如果您…

LDR6020 【USB_C显示器方案】台式显示器方案介绍

首先介绍一下什么是Type-c接口&#xff1f; 现在显示器上常见的有这几种接口&#xff1a;HDMI、DP、USB-A、USB-C&#xff08;USB Type-c接口&#xff09;、3.5mm和电源接口&#xff0c;像之前流行的VGA接口和DVI接口&#xff0c;基本上在新显示器上&#xff0c;尤其是中高端显…

什么是频谱型温振变送器(附常见振动故障特征)

在机械振动方面&#xff0c;振动分析是一项十分重要的技术。这项技术是预测维修程序中的基础&#xff0c;是机器状态的指示器&#xff0c;为了避免机械设备异常振动所带来的损失&#xff0c;对工业机械设备做振动分析是非常有必要的&#xff01; 频谱型温振变送器是一款选用了M…

阿里高级工程师对C语言预处理指令的理解

目录 预处理器指令列表 预处理器指令的流程 四种主要类型的预处理器指令 结论 我们可以将预处理器视为一个编译过程&#xff0c;该过程在开发人员运行程序时运行。它是使用 c/c 语言执行程序的预处理。若要初始化预处理器命令的进程&#xff0c;必须使用哈希符号 &#xf…

【Devops运维】Docker搭建jenkins自动化编译hadoop/spark/flink/hive/kyuubi/trino大数据组件

Docker搭建jenkins DevOps概念Docker部署Jenkins制作Jenkins镜像Dockerfile及所依赖的脚本build镜像 利用docker-compose部署jenkins 配置Jenkins管理员密码插件安装系统配置全局工具配置MAVEN 配置JDK 配置GIT 配置MAVEN 配置 Jenkins Maven Git 自动化编译找到token生成界面…

ChatGPT:使用OpenAI创建自己的AI网站,使用 flask web框架快速搭建网站主体

使用OpenAI创建自己的AI网站 如果你还是一个OpenAI的小白&#xff0c;有OpenAI的账号&#xff0c;但想调用OpenAI的API搞一些有意思的事&#xff0c;那么这一系列的教程将仔细的为你讲解如何使用OpenAI的API制作属于自己的AI网站。 使用 flask web框架快速搭建网站主体 之前…

C++:布隆过滤器和哈希切分

目录 一. 什么是布隆过滤器 二. 布隆过滤器的实现 2.1 数据插入函数set 2.2 判断数据是否存在函数test 2.3 布隆过滤器数据的删除 三. 哈希切分 一. 什么是布隆过滤器 在我之前的博客C&#xff1a;使用位图处理海量数据_【Shine】光芒的博客-CSDN博客中&#xff0c;介绍了…

【LinuxShell】linux防火墙之firewalld防火墙

文章目录 前言一、firewalld概述1. 概念2. firewalld和iptables的关系 二、firewalld网络区域1. firewalld区域的概念2. firewalld预定义区域3. firewalld数据包的处理3.1 firewalld数据处理流程3.2 firewalld检查数据包的源地址的规则3.3 总结 三、firewalld防火墙的配置方法1…

“GPT+医疗健康”:给予医疗领域新机遇

现如今&#xff0c;GPT十分火热。随着人们对健康医疗的关注越来越热切&#xff0c;GPT已逐渐成为健康医疗领域的重要角色之一。GPT可以用于许多医疗语境中&#xff0c;如医学咨询、病症诊断、健康建议、在线问诊、患者教育、健康数据跟踪等。 GPT是一种基于深度学习的自然语言处…

结构体-C语言

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C知识系统分享》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c…

【Python办公自动化】python实现将图片插入到word中指定位置并将word转换为图片

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、…

垃圾站养殖场除臭杀菌解决方案

养殖场和垃圾站都会产生大量的有机废气和垃圾&#xff0c;这些废气和垃圾会产生难闻的臭味&#xff0c;影响周围环境和居民健康。这些地方又是病菌和细菌的滋生地&#xff0c;这些细菌和病菌会对人类和动物的健康造成威胁。除臭杀菌系统可以杀灭这些细菌和病菌&#xff0c;也可…

换个思维方式,你离网工天花板会更近一点

大家好&#xff0c;我是许公子。 收到老杨的邀请&#xff0c;我正式加入网络工程师俱乐部了&#xff0c;未来会给你分享更多网工硬核内容。 和老杨聊天的过程中&#xff0c;我想起了在刚入社会一两年&#xff0c;我去参加了一个高中同学聚餐。 里面有自主创业的&#xff0c;…

软件测试被00后整顿职场了?

00后带来的压力 公司一位工作3年的老油条工资还没有刚来的00后高&#xff0c;她心中不平&#xff0c;对这件事情有不小的怨气&#xff0c;她觉得自己来公司三年了&#xff0c;三年内迟到次数都不超过5次&#xff0c;每天勤勤恳恳&#xff0c;要加班的时候也愿意加班&#xff0…

Python竖版大屏 | 用pyecharts开发可视化的奇妙探索

你好&#xff01;我是马哥python说&#xff0c;一枚10年程序猿&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;正在试错用pyecharts开发可视化大屏的非常规排版。 以下&#xff0c;我用8种ThemeType展示的同一个可视化数据大屏。 1、SHINE主题 2、LIGHT主题 3、MACARO…

手撕代码——任意奇数分频

手撕代码——任意奇数分频 一、奇数分频器原理与设计 在上文《手撕代码——任意偶数分频》中&#xff0c;我们编写任意偶数分频的Verilog代码&#xff0c;对时钟进行偶数分频&#xff0c;只需要用到时钟的上升沿或者下降沿即可&#xff0c;而要进行N倍奇数分频&#xff0c;需要…

修改Allure报告窗口标题,Overview的标题文案,环境配置,左上角LOGO

前言 如下图所示&#xff1a; 一、修改Allure报告窗口标题 Allure-html测试报告的窗口标题保存在&#xff1a;allure-html目录下的index.html文件 写个 set_windows_title 方法&#xff0c;并在 run.py 的执行文件去调用即可修改&#xff08; 在html报告生成后&#xff09…

研报精选230522

目录 【行业230522东亚前海证券】新能源行业深度报告&#xff1a;政策东风与海外需求共振&#xff0c;充电桩迎新一轮增长周期 【行业230522西南证券】人工智能专题研究&#xff1a;AIGC投资框架 【行业230522国信证券】传媒互联网行业周报&#xff1a;OpenAI推出移动版及网页端…