当前位置: 首页 > news >正文

RabbitMQ高级特性详解

前言

RabbitMQ是一款广泛使用的开源消息队列软件,它基于AMQP(Advanced Message Queuing Protocol)标准实现。本文将带你深入了解RabbitMQ的一些高级特性,包括消息确认、死信队列、延迟队列、事务处理以及消息分发策略等,并通过示例代码展示如何在实际项目中应用这些特性。


目录

1. 消息确认机制

1.1 什么是消息确认?

自动确认 vs 手动确认

1.2 使用场景

2. 死信队列

2.1 死信的概念与来源

2.2 应用场景

3. 延迟队列

3.1 延迟队列简介

3.2 实现方法

示例代码

3.3 场景应用

4. 事务处理

4.1 事务的基本概念

4.2 配置与使用

4.3 生产者示例

5. 消息分发

5.1 分发机制

5.2 限流与负载均衡

5.3 示例代码

总结


1. 消息确认机制

1.1 什么是消息确认?

消息确认是确保消息从队列可靠地到达消费者的关键机制。生产者发送消息后,消息可能会被成功处理,也可能因为异常而未被正确处理。为了保证消息的可靠性,RabbitMQ引入了消息确认机制。

自动确认 vs 手动确认
  • 自动确认:当autoAck设置为true时,RabbitMQ会自动认为消息一旦发送出去就被消费端接收到了,并立刻从队列中删除这条消息。这种方式适合对消息可靠性要求不高的场景。
  • 手动确认:当autoAck设置为false时,RabbitMQ会在接收到消费者的显式确认信号后才会移除消息。这种模式适用于需要高可靠性的场景。
// 自动确认示例
channel.basicConsume("queueName", true, new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println("接收到消息: " + new String(body));}
});// 手动确认示例
channel.basicConsume("queueName", false, new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {try {// 处理消息System.out.println("接收到消息: " + new String(body));// 确认消息channel.basicAck(envelope.getDeliveryTag(), false);} catch (Exception e) {// 异常处理,拒绝签收channel.basicNack(envelope.getDeliveryTag(), false, true); // requeue设为true表示重新入队}}
});

1.2 使用场景

使用自动确认可以简化开发流程,但可能会导致消息丢失。手动确认虽然增加了额外的确认步骤,但是能显著提高消息传递的可靠性,特别适用于金融交易、订单处理等关键业务场景。


2. 死信队列

2.1 死信的概念与来源

死信是指那些无法被正常消费的消息。它们可能由于以下几种情况产生:

  • 消息过期:消息在队列中的存活时间超过了设定的时间阈值(TTL)。
  • 消息被拒绝:消费者在处理过程中遇到错误并拒绝了该消息。
  • 队列满载:当队列达到最大长度限制时,新来的消息会被视为死信。

2.2 应用场景

  • 消息重试:将未能处理的消息重新发送到原始队列或另一个队列进行尝试。
  • 消息丢弃:直接丢弃那些不可处理的消息以避免占用资源。
  • 日志收集:将死信作为日志记录下来,以便后续分析问题所在。
@Bean
public Queue normalQueue() {Map<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange", "dlxExchange");arguments.put("x-dead-letter-routing-key", "dlxRoutingKey");return QueueBuilder.durable("normalQueue").withArguments(arguments).build();
}@RabbitListener(queues = "dlxQueue")
public void listenerDLXQueue(Message message, Channel channel) throws Exception {long deliveryTag = message.getMessageProperties().getDeliveryTag();System.out.printf("死信队列接收到消息: %s, deliveryTag: %d%n", new String(message.getBody()), deliveryTag);
}

3. 延迟队列

3.1 延迟队列简介

延迟队列是一种特殊的队列,其中的消息不是立即被消费,而是等待指定的时间后才可被获取。RabbitMQ本身并不支持延迟队列功能,但可以通过结合TTL(Time to Live)和死信队列来模拟实现。

3.2 实现方法

  • TTL+死信队列:给消息设置生存时间,超时后转至死信队列。
  • 官方插件:使用RabbitMQ提供的延迟消息插件。
示例代码
@Bean
public Queue delayedQueue() {Map<String, Object> args = new HashMap<>();args.put("x-dead-letter-exchange", "dlxExchange");args.put("x-message-ttl", 5000); // 设置消息TTL为5秒return QueueBuilder.durable("delayedQueue").withArguments(args).build();
}@RabbitListener(queues = "dlxQueue")
public void listenDlxQueue(Message message, Channel channel) throws Exception {System.out.printf("%tc 死信队列接收到消息: %s%n", new Date(), new String(message.getBody()));
}

3.3 场景应用

  • 用户注册后发送激活邮件。
  • 订单系统中未支付订单的自动取消。
  • 退款请求处理后的自动退款。

4. 事务处理

4.1 事务的基本概念

RabbitMQ支持事务处理,允许开发者确保消息的发送和接收是原子操作。这意味着要么全部完成,要么全部失败,从而保持数据的一致性。

4.2 配置与使用

配置事务管理器并开启事务支持:

@Configuration
public class TransactionConfig {@Beanpublic RabbitTransactionManager transactionManager(CachingConnectionFactory connectionFactory) {return new RabbitTransactionManager(connectionFactory);}@Beanpublic RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {RabbitTemplate template = new RabbitTemplate(connectionFactory);template.setChannelTransacted(true);return template;}
}

4.3 生产者示例

@Transactional
@RequestMapping("/send")
public String send() {rabbitTemplate.convertAndSend("", "transQueue", "trans test 1...");int a = 5 / 0; // 故意引发异常rabbitTemplate.convertAndSend("", "transQueue", "trans test 2...");return "发送成功";
}

如果启用了事务,上面的代码将会回滚整个操作,确保没有消息被发送出去。


5. 消息分发

5.1 分发机制

当一个队列有多个消费者时,RabbitMQ会根据一定的规则将消息分配给不同的消费者。默认情况下,采用轮询方式分发,即每个消费者轮流获得一条消息。这种方法可能导致某些快速消费者空闲,而慢速消费者积压大量消息的问题。

5.2 限流与负载均衡

  • 限流:通过设置basicQos参数来控制单个消费者同时处理的消息数量,防止过载。
  • 负载均衡:设置prefetchCount=1,使得RabbitMQ每次只向一个消费者发送一条消息,在收到确认之前不会发送新的消息,从而实现更公平的负载分配。
# application.yml
spring:rabbitmq:listener:simple:acknowledge-mode: manualprefetch: 1

5.3 示例代码

@Component
public class QosQueueListener {@RabbitListener(queues = "qosQueue")public void listenQosQueue(Message message, Channel channel) throws Exception {long deliveryTag = message.getMessageProperties().getDeliveryTag();System.out.printf("接收到消息: %s, deliveryTag: %d%n", new String(message.getBody()), deliveryTag);Thread.sleep(100); // 模拟耗时操作channel.basicAck(deliveryTag, false);}
}

总结

  1. 消息确认机制

    • 通过autoAck参数控制消息的确认方式。
    • 自动确认模式适合对消息可靠性要求不高的场景;手动确认模式适用于需要高可靠性的场景。
    • 手动确认允许消费者显式地向RabbitMQ发送确认信号,确保消息被成功处理后才从队列中移除。
  2. 死信队列(Dead Letter Exchange, DLX)

    • 死信是指那些无法被正常消费的消息,可能由于消息过期、被拒绝或队列满载等原因产生。
    • 死信队列可以用来存储这些无法处理的消息,提供重试、丢弃或日志记录等功能。
    • 使用示例展示了如何配置普通队列与DLX绑定,并设置消息TTL和路由键来实现消息转移至DLX。
  3. 延迟队列

    • 延迟队列用于在指定时间之后才将消息传递给消费者。
    • 通过结合TTL与DLX,或者使用官方提供的延迟插件,可以模拟实现延迟队列功能。
    • 这种机制常应用于定时任务、订单超时处理等场景。
  4. 事务处理

    • RabbitMQ支持事务操作,确保消息的发送和接收是原子性的。
    • 通过配置事务管理器并开启事务支持,可以在发生异常时回滚整个事务,保持数据一致性。
    • 示例代码演示了如何在Spring应用中配置并使用事务管理。
  5. 消息分发策略

    • 当多个消费者订阅同一个队列时,RabbitMQ会根据一定的规则分配消息。
    • 默认采用轮询分发,但可以通过设置basicQos参数进行限流,以及调整prefetchCount实现更公平的负载均衡。
    • 适当配置有助于避免某些消费者过载而其他消费者空闲的问题,提高系统的整体吞吐量和稳定性。

以上就是 RabbitMQ 的部分高级特性,有问题可在评论区讨论,感谢阅览!!

相关文章:

RabbitMQ高级特性详解

前言 RabbitMQ是一款广泛使用的开源消息队列软件&#xff0c;它基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;标准实现。本文将带你深入了解RabbitMQ的一些高级特性&#xff0c;包括消息确认、死信队列、延迟队列、事务处理以及消息分发策略等&#xff…...

提升泛化能力的前沿方法:多任务学习在机器学习中的应用与实践

提升泛化能力的前沿方法&#xff1a;多任务学习在机器学习中的应用与实践 &#x1f4cb; 目录 &#x1f9e9; 多任务学习的概念与动机&#x1f310; 多任务学习在自然语言处理中的应用案例&#x1f5bc;️ 多任务学习在计算机视觉中的应用案例⚙️ 项目实践&#xff1a;实现多…...

【小白学机器学习16】 概率论的世界观2

目录 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 1.2 万物不齐 1.3 中庸 1.4 动态平衡 正态分布&#xff0c;概率论都是一种世界观 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 世界是客观的&#xff0c;是不以人们的意志想法为转…...

洛谷 P9868 [NOIP2023] 词典

好久不写博客了&#xff0c;今天来水一篇 原题链接 初看此题在洛谷上的定位是黄题&#xff0c;实际上也并不是很简单。 其实主要就用到了贪心的思想&#xff0c;先说一下我在做题的时候是怎么想的吧。 先看了部分分&#xff0c;10分是很好拿的&#xff0c;再就分析题意&…...

跨浏览器免费书签管理系统

随着互联网信息的爆炸式增长&#xff0c;如何有效管理我们日常浏览中发现的重要网页&#xff0c;成为了每个重度互联网用户的需求。一个跨平台的书签管理网站能够帮助用户在不同设备之间无缝同步和管理书签。本文将分享如何使用 Python 和 SQLite 构建一个简单、易于维护的跨平…...

导出Excel的常用方法:从前端到后端的全面指南

导出Excel的常用方法&#xff1a;从前端到后端的全面指南 在现代Web应用中&#xff0c;导出数据为Excel文件是一个常见需求。无论是为了数据分析、记录保存还是简单的数据共享&#xff0c;Excel文件都因其广泛的兼容性和易用性而成为首选格式之一。本文将介绍几种常用的Excel导…...

uni-app中添加自定义相机(微信小程序+app)

一、微信小程序中 微信小程序中可以直接使用camera标签&#xff0c;这个标签不兼容app&#xff0c;官方文档 <cameradevice-position"back"flash"off":style"{ height: lheight px, width: lwidth px }"class"w-full"></c…...

Android中的SSL/TLS加密及其作用

Android中的SSL/TLS加密及其作用 SSL/TLS&#xff08;Secure Sockets Layer/Transport Layer Security&#xff09;加密技术是保护网络通信安全的关键技术之一&#xff0c;广泛应用于各种网络通信场景&#xff0c;包括Android应用开发。在Android中&#xff0c;SSL/TLS加密技术…...

东芝TLP176AM光耦合器:提升设计性能的关键元件

在当今快速发展的电子领域&#xff0c;精确性、可靠性和效率比以往任何时候都更加重要。作为工程师&#xff0c;我们不断寻找不仅能满足严格技术要求&#xff0c;还能提升整体设计性能的元件。其中&#xff0c;东芝的TLP176AM光耦合器正因其卓越的性能在业界备受关注。 什么是…...

MySQL数据库:基础介绍下载与安装

数据库基础知识先谈发音MySQL如何发音&#xff1f;在国内MySQL发音有很多种&#xff0c;Oracle官方文档说他们念作My sequal[si:kwəl]。 数据库基本概念 1。数据数据&#xff08;Data&#xff09;是指对客观事物进行描述并可以鉴别的符号&#xff0c;这些符号是可识别的、抽…...

原理代码解读:基于DiT结构视频生成模型的ControlNet

Diffusion Models视频生成-博客汇总 前言:相比于基于UNet结构的视频生成模型,DiT结构的模型最大的劣势在于生态不够完善,配套的ControlNet、IP-Adapter等开源权重不多,导致难以落地。最近DiT-based 5B的ControlNet开源了,相比于传统的ControlNet有不少改进点,这篇博客将从…...

【Pip】初识 Pip:Python 包管理的基本命令详解

目录 引言1. 什么是 pip&#xff1f;1.1 pip 的安装 2. pip 的基本命令2.1 pip install2.2 pip uninstall2.3 pip list2.4 pip show2.5 pip freeze2.6 pip search2.7 pip install -U2.8 pip install -r2.9 pip check2.10 pip cache 3. 使用示例3.1 安装多个包3.2 创建虚拟环境3…...

JMeter 中两大高级线程组的区别与应用

一、JMeter 中的高级线程组概述 最近群里的测试小伙伴在问在 JMeter 中&#xff0c;“jpgc - Ultimate Thread Group”和“jpgc - Stepping Thread Group 阶梯加压”有哪些区别和实际应用场景有哪些&#xff1f;所以这里也跟大家分享一下 JMeter 作为一款强大的性能测试工具&a…...

深入理解伪元素与伪类元素

在“探秘盒子浮动&#xff0c;破解高度塌陷与文字环绕难题&#xff0c;清除浮动成关键&#xff01;”中&#xff0c;我们讲到如果父盒由于各种原因未设置高度&#xff0c; 子盒的浮动会导致父盒的高度塌陷。为了解决高度塌陷的问题&#xff0c;我们可以添加伪元素。 一、伪元素…...

HDU Romantic

题目大意&#xff1a;现在告诉你两个非负整数 a 和 b。找到满足 X*a Y*b 1 的非负整数 X 和整数 Y。如果没有这样的答案&#xff0c;请写 “sorry”。 思路&#xff1a;这是一道扩展欧几里得模板题&#xff0c;唯一容易错的就是 x 有可能是负数&#xff0c;要把它改成非负数…...

[每日一练]通过shift移动函数实现连续数据的需求

该题目来源于力扣&#xff1a; 603. 连续空余座位 - 力扣&#xff08;LeetCode&#xff09; 题目要求&#xff1a; 表: Cinema------------------- | Column Name | Type | ------------------- | seat_id | int | | free | bool | ------------------- Seat_id…...

go 中的斐波那契数实现以及效率比较

package mainimport ("fmt""math/big""time" )// FibonacciRecursive 使用递归方法计算斐波那契数列的第n个数 func FibonacciRecursive(n int) *big.Int {if n < 1 {return big.NewInt(int64(n))}return new(big.Int).Add(FibonacciRecursiv…...

基于ASP.NET的小型超市商品管理系统

文章目录 前言项目介绍技术介绍功能介绍核心代码数据库参考 系统效果图 前言 示 文章底部名片&#xff0c;获取项目的完整演示视频&#xff0c;免费解答技术疑问 项目介绍 小型超市商品管理系统是一款针对小型超市日常运营需求设计的软件解决方案。该系统主要内容有商品类别…...

spdlog学习记录

spdlog Loggers&#xff1a;是 Spdlog 最基本的组件&#xff0c;负责记录日志消息。在 Spdlog 中&#xff0c;一个 Logger 对象代表着一个日志记录器&#xff0c;应用程序可以使用 Logger 对象记录不同级别的日志消息Sinks&#xff1a;决定了日志消息的输出位置。在 Spdlog 中&…...

linux替换某个文件的某段内容命令

假设文件是a.sql 里面的库是abc&#xff0c;我想把这个abc给替换掉&#xff0c;改成hahaha cat a.sql |grep abc|sed -i s/abc/hahaha/g a.sql 如果想写个脚本指定整个文件夹中的内容替换 #!/bin/bash # 检查是否提供了文件夹路径 if [ -z "\$1" ]; then echo &…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...