高级特性实战:死信队列、延迟队列与优先级队列(三)

四、优先级队列:优先处理重要任务

4.1 优先级队列概念解析

优先级队列(Priority Queue)是一种特殊的队列数据结构,它与普通队列的主要区别在于,普通队列遵循先进先出(FIFO)的原则,即先进入队列的元素先被取出;而优先级队列则根据元素的优先级来决定取出顺序,优先级高的元素会优先被取出并处理,而不是按照进入队列的先后顺序 。

在优先级队列中,每个元素都被赋予了一个优先级值,这个值可以是一个数字、一个权重,或者根据具体业务定义的某种优先级标识。当从队列中获取元素时,系统会首先返回具有最高优先级的元素。如果多个元素具有相同的优先级,那么这些元素之间通常按照它们进入队列的顺序进行处理,即遵循 FIFO 原则 。

4.2 优先级队列应用场景

优先级队列在实际应用中有着广泛的场景,以下是一些常见的例子:

  • 电商订单处理:在电商系统中,不同类型的订单可能具有不同的优先级。例如,VIP 客户的订单、加急订单或者金额较大的订单,可以被赋予较高的优先级。这些高优先级订单会优先进入处理流程,优先进行库存分配、发货等操作,以提升重要客户的购物体验,同时确保高价值订单能够得到及时处理,提高业务收益。
  • 任务调度系统:在操作系统或分布式系统的任务调度模块中,任务可以根据其重要性、紧急程度或者资源需求等因素被分配不同的优先级。比如,系统关键任务(如系统监控、数据备份等)具有较高优先级,而一些后台辅助任务(如日志分析、数据统计等)优先级较低。优先级队列可以确保关键任务优先被调度执行,保证系统的稳定运行和关键业务的正常进行 。
  • 消息推送系统:在消息推送场景中,不同类型的消息也有不同的优先级。例如,短信验证码、重要通知等消息,对于及时性要求较高,需要优先推送。而一些普通的营销消息、活动通知等,优先级相对较低。通过优先级队列,消息推送系统可以优先处理和发送高优先级消息,确保用户能够及时收到关键信息 。

4.3 优先级队列实战案例(以 RabbitMQ 为例)

在 RabbitMQ 中实现优先级队列,需要进行以下几个步骤:

  1. 声明优先级队列:在创建队列时,通过设置队列的x-max-priority参数来指定队列的最大优先级。该参数的值表示队列支持的最大优先级级别,例如设置为 10,表示队列中的消息优先级可以从 0 到 10,其中 10 为最高优先级。
  1. 发送带有优先级的消息:生产者在发送消息时,通过设置消息的priority属性来指定消息的优先级。消息的优先级值必须在队列声明的最大优先级范围内,否则会被自动调整为队列的最大优先级 。
  1. 消费者消费消息:消费者从优先级队列中获取消息时,RabbitMQ 会按照消息的优先级顺序将消息发送给消费者,高优先级的消息会优先被消费。

下面是一个使用 Java 和 RabbitMQ 实现优先级队列的示例代码:

首先,引入 RabbitMQ 的 Java 客户端依赖:

 

<dependency>

<groupId>com.rabbitmq</groupId>

<artifactId>amqp-client</artifactId>

<version>5.14.2</version>

</dependency>

然后,编写生产者代码,向优先级队列发送不同优先级的消息:

 

import com.rabbitmq.client.AMQP;

import com.rabbitmq.client.Channel;

import com.rabbitmq.client.Connection;

import com.rabbitmq.client.ConnectionFactory;

public class Producer {

private static final String EXCHANGE_NAME = "priority_exchange";

private static final String QUEUE_NAME = "priority_queue";

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

channel.exchangeDeclare(EXCHANGE_NAME, "direct");

// 声明优先级队列,设置最大优先级为10

java.util.Map<String, Object> argsMap = new java.util.HashMap<>();

argsMap.put("x-max-priority", 10);

channel.queueDeclare(QUEUE_NAME, false, false, false, argsMap);

channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, QUEUE_NAME);

// 发送不同优先级的消息

for (int i = 1; i <= 10; i++) {

String message = "Message " + i;

int priority = i % 5; // 模拟不同优先级,范围0 - 4

AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()

.priority(priority)

.build();

channel.basicPublish(EXCHANGE_NAME, QUEUE_NAME, properties, message.getBytes("UTF-8"));

System.out.println("Sent: " + message + " with priority " + priority);

}

}

}

}

接着,编写消费者代码,从优先级队列中接收并处理消息:

 

import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer {

private static final String EXCHANGE_NAME = "priority_exchange";

private static final String QUEUE_NAME = "priority_queue";

public static void main(String[] args) throws Exception {

ConnectionFactory factory = new ConnectionFactory();

factory.setHost("localhost");

try (Connection connection = factory.newConnection();

Channel channel = connection.createChannel()) {

channel.exchangeDeclare(EXCHANGE_NAME, "direct");

// 声明优先级队列,设置最大优先级为10

java.util.Map<String, Object> argsMap = new java.util.HashMap<>();

argsMap.put("x-max-priority", 10);

channel.queueDeclare(QUEUE_NAME, false, false, false, argsMap);

channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, QUEUE_NAME);

System.out.println("Waiting for messages...");

DeliverCallback deliverCallback = (consumerTag, delivery) -> {

String message = new String(delivery.getBody(), "UTF-8");

int priority = delivery.getProperties().getPriority();

System.out.println("Received: " + message + " with priority " + priority);

channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);

};

channel.basicConsume(QUEUE_NAME, false, deliverCallback, consumerTag -> {});

}

}

}

在上述代码中,生产者创建了一个优先级队列,并向其中发送了 10 条带有不同优先级的消息。消费者从该队列中接收消息,并按照消息的优先级顺序进行处理。通过这个案例,我们可以清晰地看到优先级队列在 RabbitMQ 中的实现和应用 。

五、总结与展望

死信队列、延迟队列和优先级队列作为消息队列的高级特性,在分布式系统中各自发挥着独特且关键的作用。死信队列就像是系统的 “守护卫士”,当消息遭遇异常无法正常消费时,它能够及时将这些消息收纳到死信队列中,避免消息的丢失,为系统的稳定运行提供了坚实的保障。延迟队列则如同一个精准的 “时间管家”,通过巧妙地设置消息的延迟时间,实现了任务的定时执行,让系统的业务流程能够按照既定的时间规则有序推进。优先级队列则好比是资源分配的 “决策者”,根据消息的优先级来决定消费顺序,确保重要的任务能够优先得到处理,提升了系统的整体性能和业务处理效率。

在实际应用中,我们需要根据具体的业务场景和需求,谨慎且合理地选择和配置这些队列。在使用死信队列时,要精心设置死信的条件和处理逻辑,确保能够及时、有效地处理异常消息,同时也要注意避免死信队列中的消息堆积过多,影响系统性能。对于延迟队列,要精确地计算和设置延迟时间,以满足业务对时间的精准要求。在实现方式上,不同的技术方案各有优劣,我们需要综合考虑系统的性能、可靠性、复杂度等因素,选择最适合的实现方式。在运用优先级队列时,要科学地定义消息的优先级规则,确保优先级的划分能够准确反映业务的重要程度和紧急程度。

随着分布式系统和云计算技术的持续迅猛发展,消息队列的应用场景也在不断地拓展和深化。未来,消息队列有望在性能、可靠性、可扩展性等方面取得更为显著的突破和提升。例如,在性能方面,可能会出现更高效的消息存储和传输算法,以满足大规模数据的快速处理需求;在可靠性方面,会进一步完善消息的持久化和容错机制,确保消息在任何情况下都不会丢失;在可扩展性方面,将更好地支持分布式集群部署,实现动态的资源分配和负载均衡。同时,消息队列与人工智能、大数据等新兴技术的融合也将成为未来的发展趋势,为解决各种复杂的业务问题提供更为强大的支持和解决方案。

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

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

相关文章

python打卡day34

GPU训练及类的call方法 知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数GPU性能的查看&#xff1a;看显存、看级别、看架构代际GPU训练的方法&#xff1a;数据和模型移动到GPU device上类的call方法&#xff1a;为什么定义前向传播时可以直接写作…

Newtonsoft Json序列化数据不序列化默认数据

问题描述 数据在序列号为json时,一些默认值也序列化了,像旋转rot都是0、缩放scal都是1,这样的默认值完全可以去掉,减少和服务器通信数据量 核心代码 数据结构字段增加[DefaultValue(1.0)]属性,缩放的默认值为1 public class Vec3DataOne{[DefaultValue(1.0)] public flo…

可增添功能的鼠标右键优化工具

软件介绍 本文介绍一款能优化Windows电脑的软件&#xff0c;它可以让鼠标右键菜单添加多种功能。 软件基本信息 这款名为Easy Context Menu的鼠标右键菜单工具非常小巧&#xff0c;软件大小仅1.14MB&#xff0c;打开即可直接使用&#xff0c;无需进行安装。 添加功能列举 它…

Gemini 2.5 Pro 一次测试

您好&#xff0c;您遇到的重定向循环问题&#xff0c;即在 /user/messaging、/user/login?return_to/user/messaging 和 /user/login 之间反复跳转&#xff0c;通常是由于客户端的身份验证状态检查和页面重定向逻辑存在冲突或竞争条件。 在分析了您提供的代码&#xff08;特别…

vue3前端后端地址可配置方案

在开发vue3项目过程中&#xff0c;需要切换不同的服务器部署&#xff0c;代码中配置的服务需要可灵活配置&#xff0c;不随着run npm build把网址打包到代码资源中&#xff0c;不然每次切换都需要重新run npm build。需要一个配置文件可以修改服务地址&#xff0c;而打包的代码…

大模型微调与高效训练

随着预训练大模型(如BERT、GPT、ViT、LLaMA、CLIP等)的崛起,人工智能进入了一个新的范式:预训练-微调(Pre-train, Fine-tune)。这些大模型在海量数据上学习到了通用的、强大的表示能力和世界知识。然而,要将这些通用模型应用于特定的下游任务或领域,通常还需要进行微调…

编程技能:字符串函数10,strchr

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏&#xff0c;故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 &#xff08;一&#xff09;WIn32 专栏导航 上一篇&#xff1a;编程技能&#xff1a;字符串函数09&#xff0c;strncmp 回到目录…

动态规划-53.最大子数组和-力扣(LeetCode)

一、题目解析 在给定顺序的数组中找出一段具有最大和的连续子数组&#xff0c;且大小最小为1. 二、算法原理 1.状态表示 我们可以意一一枚举出所有的子数组&#xff0c;但我们想要的是最大子数组&#xff0c;所以f[i]表示&#xff1a;以i位置为结尾&#xff0c;所有子数组的最…

C++ queue对象创建、queue赋值操作、queue入队、出队、获得队首、获得队尾操作、queue大小操作、代码练习

对象创建&#xff0c;代码见下 #include<iostream> #include<queue>using namespace std;int main() {// 1 默认构造函数queue<int> q1;// 2 拷贝构造函数queue<int> q2(q1);return 0;} queue赋值操作&#xff0c;代码见下 #include<iostream>…

全链路解析:影刀RPA+Coze API自动化工作流实战指南

在数字化转型加速的今天&#xff0c;如何通过RPA与API的深度融合实现业务自动化提效&#xff0c;已成为企业降本增效的核心命题。本文以「影刀RPA」与「Coze API」的深度协作为例&#xff0c;系统性拆解从授权配置、数据交互到批量执行的完整技术链路&#xff0c;助你快速掌握跨…

php本地 curl 请求证书问题解决

错误: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for 解决方案 在php目录下创建证书文件夹, 执行下面生成命令, 然后在php.ini 文件中配置证书路径; 重启环境 curl --eta…

【图数据库】--Neo4j 安装

目录 1.Neo4j --概述 2.JDK安装 3.Neo4j--下载 3.1.下载资源包 3.2.创建环境变量 3.3.运行 Neo4j 是目前最流行的图形数据库(Graph Database)&#xff0c;它以节点(Node)、关系(Relationship)和属性(Property)的形式存储数据&#xff0c;专门为处理高度连接的数据而设计。…

MIT 6.S081 2020Lab5 lazy page allocation 个人全流程

文章目录 零、写在前面一、Eliminate allocation from sbrk()1.1 说明1.2 实现 二、Lazy allocation2.1 说明2.2 实现 三、Lazytests and Usertests3.1 说明3.2 实现3.2.1 lazytests3.2.2 usertests 零、写在前面 可以阅读下4.6页面错误异常 像应用程序申请内存&#xff0c;内…

(Git) 稀疏检出(Sparse Checkout) 拉取指定文件

文章目录 &#x1f3ed;作用&#x1f3ed;指令总览&#x1f477;core.sparseCheckout&#x1f477;sparse-checkout 文件 &#x1f3ed;实例演示⭐END&#x1f31f;交流方式 &#x1f3ed;作用 类似于 .gitignore 进行文件的规则匹配。 一般在需要拉取大型项目指定的某些文件…

docker初学

加载镜像&#xff1a;docker load -i ubuntu.tar 导出镜像&#xff1a;docker save -o ubuntu1.tar ubuntu 运行&#xff1a; docker run -it --name mu ubuntu /bin/bash ocker run -dit --name mmus docker.1ms.run/library/ubuntu /bin/bash 进入容器&#xff1a;docke…

Docker系列(二):开机自启动与基础配置、镜像加速器优化与疑难排查指南

引言 docker 的快速部署与高效运行依赖于两大核心环节&#xff1a;基础环境搭建与镜像生态优化。本期博文从零开始&#xff0c;系统讲解 docker 服务的管理配置与镜像加速实践。第一部分聚焦 docker 服务的安装、权限控制与自启动设置&#xff0c;确保环境稳定可用&#xff1b…

计算机视觉(图像算法工程师)学习路线

计算机视觉学习路线 Python基础 常量与变量 列表、元组、字典、集合 运算符 循环 条件控制语句 函数 面向对象与类 包与模块Numpy Pandas Matplotlib numpy机器学习 回归问题 线性回归 Lasso回归 Ridge回归 多项式回归 决策树回归 AdaBoost GBDT 随机森林回归 分类问题 逻辑…

工业软件国产化:构建自主创新生态,赋能制造强国建设

随着全球产业环境的变化和技术的发展&#xff0c;建立自主可控的工业体系成为我国工业转型升级、走新型工业化道路、推动国家制造业竞争水平提升的重要抓手。 市场倒逼与政策护航&#xff0c;国产化进程双轮驱动 据中商产业研究院预测&#xff0c;2025年中国工业软件市场规模…

OpenCV CUDA 模块图像过滤------创建一个高斯滤波器函数createGaussianFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::createGaussianFilter 是 OpenCV CUDA 模块中的一个工厂函数&#xff0c;用于创建一个高斯滤波器。这个滤波器可以用来平滑图像&#…

【RocketMQ 生产者和消费者】- 生产者发送故障延时策略

文章目录 1. 前言2. FaultItem3. LatencyFaultToleranceImpl 容错集合处理类3.1 updateFaultItem 更新容错集合3.2 isAvailable 判断 broker 是否可用3.3 pickOneAtLeast 至少选出一个故障 broker 4. MQFaultStrategy 故障策略类4.1 属性4.2 updateFaultItem 更新延迟故障容错信…