RabbitMQ的优先级队列、惰性队列

2023-11-03

视频地址

优先级队列

在我们系统中有一个订单催付的场景,我们的客户在天猫下的订单,淘宝会及时将订单推送给我们,如
果在用户设定的时间内未付款那么就会给用户推送一条短信提醒,很简单的一个功能对吧,但是,tmall商家对我们来说,肯定是要分大客户和小客户的对吧,比如像苹果,小米这样大商家一年起码能给我们创造很大的利润,所以理应当然,他们的订单必须得到优先处理,而曾经我们的后端系统是使用 redis 来存放的定时轮询,大家都知道 redis 只能用 List 做一个简简单单的消息队列,并不能实现一个优先级的场景,所以订单量大了后采用 RabbitMQ 进行改造和优化,如果发现是大客户的订单给一个相对比较高的优先级,否则就是默认优先级。

消息生产者代码

package com.dongmu.rabbitmq;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.impl.AMQBasicProperties;

import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeoutException;

public class Produce {
    //队列名称
    private static final String QUEUE_NAME = "hello";

    //发送消息
    public static void main(String[] args) throws IOException, TimeoutException {
        //创建一个工厂
        ConnectionFactory factory = new ConnectionFactory();
        //工厂ip,连接Rabitmq的队列
        factory.setHost("*******);
        //设置用户名和密码
        factory.setUsername("***");
        factory.setPassword("***");

        //获取连接
        Connection connection = factory.newConnection();

        //获取信道
        Channel channel = connection.createChannel();

        HashMap<String,Object> hashMap = new HashMap<>();
        //范围是0-255,根据自己的业务来进行设置,合适就好,太大了回占用CPU和内存。
        hashMap.put("x-max-priority",10);
        //创建一个队列
        /*参数:
        队列名称
        是否保存消息(是否持久化消息,默认不持久化)
        这个队列是否只供一个消费者进行消费(是否进行消息的共享)
        是否自动删除
        其他参数
        */
        channel.queueDeclare(QUEUE_NAME,true,false,false,hashMap);

        String message = "Hello World2";

        /*
        * * 发送一个消息
         * 1.发送到那个交换机
         * 2.路由的 key 是哪个
         * 3.其他的参数信息
         * 4.发送消息的消息体
        * */
        for (int i = 0; i < 10; i++) {
            String str  = message+i;
            if (i==5){
                AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().priority(5).build();
                channel.basicPublish("",QUEUE_NAME,properties,str.getBytes());
            }else {
                channel.basicPublish("",QUEUE_NAME,null,str.getBytes());
            }
        }


        System.out.println("消息发送完毕");

    }


}

启动执行后发现队列中有了十条消息
在这里插入图片描述
消费者端代码

package com.dongmu.rabbitmq;

import com.rabbitmq.client.*;

public class Consumer {
    private final static String QUEUE_NAME = "hello";
    public static void main(String[] args) throws Exception {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("****");
        factory.setUsername("***");
        factory.setPassword("***");

        Connection connection = factory.newConnection();

        Channel channel = connection.createChannel();

        System.out.println("等待接收消息....");

        //推送的消息如何进行消费的接口回调
        DeliverCallback deliverCallback=(consumerTag, delivery)->{
            String message= new String(delivery.getBody());
            System.out.println(message);
        };

        //取消消费的一个回调接口 如在消费的时候队列被删除掉了
        CancelCallback cancelCallback=(consumerTag)->{
            System.out.println("消息消费被中断");
        };

        /*
         * 消费者消费消息
         * 1.消费哪个队列
         * 2.消费成功之后是否要自动应答 true 代表自动应答 false 手动应答
         * 3.消费者成功消费的回调
         * 4.消费者未成功消费的回调
         */

        channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);

    }
}

启动消费者端的代码
运行结果
在这里插入图片描述
可以发现优先级高的消息被优先消费了。

惰性队列

RabbitMQ 从 3.6.0 版本开始引入了惰性队列的概念。惰性队列会尽可能的将消息存入磁盘中,而在消
费者消费到相应的消息时才会被加载到内存中,它的一个重要的设计目标是能够支持更长的队列,即支持更多的消息存储。当消费者由于各种各样的原因(比如消费者下线、宕机亦或者是由于维护而关闭等)而致使长时间内不能消费消息造成堆积时,惰性队列就很有必要了。

默认情况下,当生产者将消息发送到 RabbitMQ 的时候,队列中的消息会尽可能的存储在内存之中,这样可以更加快速的将消息发送给消费者。即使是持久化的消息,在被写入磁盘的同时也会在内存中驻留一份备份。当 RabbitMQ 需要释放内存的时候,会将内存中的消息换页至磁盘中,这个操作会耗费较长的时间,也会阻塞队列的操作,进而无法接收新的消息。虽然 RabbitMQ 的开发者们一直在升级相关的算法,但是效果始终不太理想,尤其是在消息量特别大的时候。

队列具备两种模式:default 和 lazy。默认的为 default 模式,在 3.6.0 之前的版本无需做任何变更。lazy模式即为惰性队列的模式,可以通过调用 channel.queueDeclare 方法的时候在参数中设置,也可以通过Policy 的方式设置,如果一个队列同时使用这两种方式设置的话,那么 Policy 的方式具备更高的优先级。如果要通过声明的方式改变已有队列的模式的话,那么只能先删除队列,然后再重新声明一个新的。

在队列声明的时候可以通过“x-queue-mode”参数来设置队列的模式,取值为“default”和“lazy”。下面示
例中演示了一个惰性队列的声明细节:
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-queue-mode", "lazy");
channel.queueDeclare("myqueue", false, false, false, args);

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RabbitMQ的优先级队列、惰性队列 的相关文章

  • 从 PDF 中提取不可选择的内容

    我正在使用 Apache PDFBox 从 PDF 文件中提取页面 但找不到提取不可选择的内容 文本或图像 的方法 从 PDF 文件中选择内容是没有问题的 请注意 相关 PDF 在复制内容方面没有任何限制 至少从我在文件的 文档限制摘要 中
  • Java Arraylist of object 按日期从数组列表中删除元素

    这是我的数组列表 ArrayList
  • JPA 实体中的方法是否允许抛出异常?

    我尝试创建的 Entity 有问题 当尝试使用 OpenJPA 实现在 Eclipse 中测试类时出现问题 我有not尝试过其他人 所以不确定它是否适用于他们 我的测试用例非常简单 因为它创建一个 EntityManagerFactory
  • Android 上的 setTimeOut() 相当于什么?

    我需要等效的代码setTimeOut call function milliseconds 对于安卓 setTimeOut call function milliseconds 您可能想查看定时任务 http developer andro
  • 如何检测线程是否被IO阻塞?

    在Java中 线程可以有不同的状态 新的 可运行的 阻塞的 等待的 TIMED WAITING 的 终止的 然而 当线程被IO阻塞时 其状态为 RUNNABLE 如何判断是否被IO阻塞 NEW 线程已创建但尚未处理 可运行 线程正在占用CP
  • 为移动设备扩展 libgdx UI?

    眼下desktop应用程序的版本很好 按钮缩放得很好 但是当我部署到android它们很小 几乎无法使用 DesktopLauncher public class DesktopLauncher public static void mai
  • Hamcrest 泛型地狱 #2:iterable With Size 给出错误“不适用于参数”

    在 hamcrest 中 1 3 RC2 没有 JUnit 依赖项 我使用失败iterableWithSize 我有一个 扩展 Iterator参数化为Content像这样EndResult
  • 如何使用 log4j 自动记录类中调用的每个方法

    我有一个包含数据库调用的类 我通常希望使用 log4j 记录该类中调用的每个方法 带参数 logger debug foo id id initiated 可以自动执行此操作吗 也许通过在每个方法的开头使用某种注释而不是编写每个 logge
  • java中如何围绕另一个移动对象旋转一个对象?

    我对 Java 很陌生 想要编写一个简单的太阳系统 其中月球绕地球旋转 地球绕太阳旋转 一切正常 除了月亮不想正确移动 由于地球偏离月球的初始位置 月球的自转半径会根据该距离而增大 同样 当地球接近月球惯性位置时 自转半径会减小 如果初始位
  • C# 中的 Culture 相当于 Java 中的 Locale 吗?

    C 使用文化的概念 这在操作上与 Java 中的 Locale 类似吗 或者底层概念是否存在显着差异 从文化而不是语言环境的角度进行工作是一种寻找正确抽象层次的尝试 从以类似方式做事的人群的角度来考虑事物 而不是谈论地理区域和语言 并有点疯
  • 如何在Spring Security SAML示例中配置IDP元数据和SP元数据?

    我想处理 Spring Security SAML 为此 我开始探索Spring安全SAML http docs spring io spring security saml docs 1 0 x reference html chapte
  • Android - Java - 发送 facebook 聊天消息的意图(facebook 禁用 xmpp)

    Facebook 已弃用 xmpp API 有没有办法打开意图 或将数据传递到fb 以在Android设备上发送聊天消息 设备上安装的 Facebook 和 Messenger 应用 谢谢 您需要将 uri 传递给意图 这里10000572
  • 从 Java 调用 Python 代码时出现问题(不使用 jython)

    我发现这是从 java 运行 使用 exec 方法 python 脚本的方法之一 我在 python 文件中有一个简单的打印语句 但是 我的程序在运行时什么也没做 它既不打印Python文件中编写的语句 也不抛出异常 程序什么都不做就终止了
  • Java反序列化中避免重复对象

    我有两个列表 list1 和 list2 其中包含对某些对象的引用 其中某些列表条目可能指向同一对象 然后 由于各种原因 我将这些列表序列化为两个单独的文件 最后 当我反序列化列表时 我想确保我不会重新创建超出需要的对象 换句话说 List
  • 如何在 Eclipse 中使用 Hibernate Tools 生成 DAO?

    我在用着 Eclipse Java EE IDE Web 开发人员 版本 Indigo 发布 使用 hibernate 工具 我对 Eclipse 中的 hibernate 很陌生 所以我学习如何配置 hibernate 并使用注释生成 P
  • ObservableList 不更新 ArrayList

    对于学校作业 我们正在使用 JavaFX 中的 ObservableList 对象 对吗 我已经为此工作了一天多了 但无法弄清楚 老师只告诉我们 谷歌一下 所以这也没有帮助 基本上 我们正在开发一个基本的管理应用程序来跟踪人们及其家人 人们
  • Android:如何以编程方式仅圆化位图的顶角?

    我目前正在使用这段代码 Override public Bitmap transform Bitmap source Bitmap result Bitmap createBitmap source getWidth source getH
  • 何时以及为何使用缓冲输入和输出流? [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我读到这些是为了减少磁盘 网络调用开销而使用的 这在写操作的情况下似乎很好 但是进行缓冲读取有什么好处呢 如果您按字节读取文件 则每次都会进
  • 仅在java中使用数组计算50的阶乘

    我是java的初学者 我有一个作业要编写一个完整的程序 使用数组计算 50 的阶乘 我无法使用像 biginteger 这样的任何方法 我只能使用数组 因为我的教授希望我们理解背后的逻辑 我猜 然而 他并没有真正教我们数组的细节 所以我在这
  • java.lang.NoClassDefFoundError:com.google.ads.AdView

    我正在尝试将 admob 广告合并到我的应用程序中 到目前为止我已经添加了以下代码 在我的应用程序主要活动的 onCreate 方法中 adView new AdView this AdSize BANNER my code number

随机推荐

  • 前端代码深浅拷贝四种方式

    今天公司的实习生有问我代码怎么深拷贝 下面我就给大家整理四种前端代码深拷贝的四种方式 前端数据分为基本数据类型和引用数据类型 当我们拷贝引用数据类型的时候 我们希望改变新数组 对象 不改变原本的数组 对象 我们往往会深拷贝数据 下面是四种深
  • Python paramiko文件传输显示上传下载进度条源码 - stdout

    本文Python Code基于chatGPT的推荐 并修改调试实际运行通过 供学习参考 通过使用python paramiko库 实现文件传输 包括上传和下载 并且同步显示上传和下载进度条信息 实时获取传输进度 避免print方式频繁刷屏困
  • Spring Boot 配置多数据源

    Spring Boot 配置多数据源 作者 Grey 原文地址 博客园 Spring Boot 配置多数据源 CSDN Spring Boot 配置多数据源 说明 本文主要介绍了 Spring Boot 下如何配置多数据源 环境和版本 Ja
  • 静态路由综合实验

    目录 实验要求 实验步骤 1 子网划分 2 配置IP和环回 3 配置静态路由 实现全网可达 4 配置缺省路由 使R1 R4可以访问5 5 5 5 24 5 配置空接口防环 6 ping测试 实验要求 1 除R5的环回地址固定以外 整个其他所
  • 10个最好的 jQuery 视频插件

    在这篇文章中已经收集了10个最佳的jQuery视频插件 帮助开发人员容易地实现网站播放影片功能 可以显示视频和视频播放列表 1 Bigvideo js BigVideo js 是一个jQuery插件能够 让你很方便将视频作为网站的背景 它可
  • FCM算法的matlab实现(Fuzzy C-means 算法)

    FCM算法 F C M FCM FCM算法简介 F C M FCM FCM算法原理 F C M FCM FCM算法实现 m a t l a b matlab matlab F C M FCM FCM算法简介 F C M FCM FCM算法属
  • `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver‘的解决办法

    com mysql jdbc Driver This is deprecated The new driver class is com mysql cj jdbc Driver 的解决办法 说多了都是泪 搭建这个项目遇到的问题太多了 cs
  • Tensorflow中问题总结

    1 ValueError Variable bar v does not exist or was not created with tf get variab le Did you mean to set reuse None in Va
  • 基于Tensorflow卷积神经网络(CNN)的人脸年龄和性别检测系统

    文件大小 150M 开发环境 Python3 7 OpenCV4 0 1 24 Tensorflow1 13 1 PyCharm2020 点击下载 点击下载 简要概述 基于Tensorflow卷积神经网络 CNN 的人脸年龄和性别检测系统
  • Unity BRDF公式解析

    根据BRDF公式 高光项部分 只能物体的表面的粗糙度有关 Roughness有关 大部分公式都是 根据Cook Torrance 的微表面高光BRDF公式 我们把高光分成三项 D项 Normal Distribution Function
  • 正则表达式如何同时添加左右括号 sub_python小课堂24 - 正则表达式(二)

    python小课堂24 正则表达式 二 前言 今天继续来介绍一下python的正则表达式 回顾一下上次介绍的re模块整篇文章围绕着re findall 来进行实例的讲解 也就是所谓的查询操作 为了便于回顾 这里给出链接 python小课堂2
  • 加密文件

    记得不要抄 问题描述 有一种加密方法为 其使用一个字母串 可以含重复字母 字母个数不超过50 作为密钥 假定密钥单词串为feather 则先去掉密钥单词中的重复字母得到单词串feathr 然后再将字母表中的其它字母以反序追加到feathr的
  • Intellij IDEA Diagrams找不到

    问题 利用spring integration配置了并行调用 想利用Intellij IDEA的Diagrams功能生成可视化效果图 但是怎么也找不到Diagrams这个功能 查询了很多解决方法 如添加插件 Settings中设置 利用快捷
  • Jmeter-plugins-manager下载安装和使用

    一 Jmeter plugins manager下载 官网下载地址 Install JMeter Plugins org 点击plugins manager jar就可以下载安装包了 然后把下载的包放入jmeter下面的 lib ext目录
  • matlab中complex的详细用法,Matlab基本函数-complex函数

    1 complex函数 创建复数 2 用法说明 1 z complex x y 函数创建复数z 输入的x y必须同为变量或维数相同 相同数据类型的向量 矩阵或者多维数组 输出的结果跟输入的维数相同 返回值为a b i 2 y complex
  • dubbo提供者源码解析

    一 dubbo配置解析 DubboBeanDefinitionParser类 会解析xml或者注解配置的类 public DubboBeanDefinitionParser Class
  • k8s指南-工作负载(4)

    目录 1 k8s指南 概述 2 k8s指南 架构 3 k8s指南 工作负载 1 4 k8s指南 工作负载 2 5 k8s指南 工作负载 3 6 k8s指南 工作负载 4 7 k8s指南 Service 8 k8s指南 Ingress 9 k
  • RocketMQ-Broker异常恢复后部分队列重新加载已消费消息问题解决

    问题描述 线上Broker所有在主机IO异常 导致Broker异常退出 主机问题解决后 重启Broker 发现group A的几个consumeQueue diff值有几十万 而通过查看日志信息发现该Group的consumeQueue只有
  • 如何从PHP 获取绝对路径、文档根目录、基本 URL

    根据您的服务器配置 获取正确的路径信息可能具有挑战性 例如 PHP 并没有直接提供一个变量来返回站点基本 URL 以下是一些代码片段 可以帮助您获取绝对路径 文档根目录和基本 URL 获取绝对路径 如果您的脚本位于 path directo
  • RabbitMQ的优先级队列、惰性队列

    视频地址 优先级队列 在我们系统中有一个订单催付的场景 我们的客户在天猫下的订单 淘宝会及时将订单推送给我们 如 果在用户设定的时间内未付款那么就会给用户推送一条短信提醒 很简单的一个功能对吧 但是 tmall商家对我们来说 肯定是要分大客