RabbitMQ的高级特性介绍(一)

news2025/4/21 21:16:44

消息确认机制

⽣产者发送消息之后, 到达消费端之后, 可能会有以下情况:

a. 消息处理成功
b. 消息处理异常

RabbitMQ向消费者发送消息之后, 就会把这条消息删掉, 那么第二种情况, 就会造成消息丢失
那么如何确保消费端已经成功接收了, 并正确处理了呢?

为了保证消息从队列可靠地到达消费者, RabbitMQ提供了消息确认机制

消息确认机制分为两种:

自动确认:RabbitMQ 会自动把发送出去的消息置为确认, 然后从内存(或者磁盘)中删除, 而不管消费者是否真正地消费到了这些消息。⾃动确认模式适合对于消息可靠性要求不⾼的场景。

手动确认:RabbitMQ会等待消费者显式地调⽤Basic.Ack命令, 回复确认信号后才从内存(或者磁盘) 中移去消息. 这种模式适合对消息可靠性要求⽐较⾼的场景。

如果RabbitMQ⼀直没有收到消费者的确认信号, 并且消费此消息的消费者已经断开连接, 则RabbitMQ会安排该消息重新进⼊队列,等待投递给下⼀个消费者,当然也有可能还是原来的那个消费者。

手动确认的方法

消费者在收到消息之后, 可以选择确认, 也可以选择直接拒绝或者跳过, RabbitMQ也提供了不同的确认应答的⽅式,消费者客⼾端可以调⽤与其对应的channel的相关⽅法,共有三种。

肯定确认:Channel.basicAck(long deliveryTag, boolean multiple)

RabbitMQ 已知道该消息并且成功的处理消息。可以将其丢弃了。

参数说明:

1) deliveryTag: 消息的唯⼀标识,它是⼀个单调递增的64 位的⻓整型值。

2)multiple: 是否批量确认。 在某些情况下, 为了减少⽹络流量, 可以对⼀系列连续的 deliveryTag 进行批量确认。

否定确认: Channel.basicReject(long deliveryTag, boolean requeue)

消费者客⼾端可以调用channel.basicReject方法来告诉RabbitMQ拒绝这个消息。

参数说明:

1)deliveryTag: 参考channel.basicAck

2)requeue: 表⽰拒绝后, 这条消息如何处理. 如果requeue 参数设置为true, 则RabbitMQ会重新将这条消息存⼊队列,以便可以发送给下⼀个订阅的消费者. 如果requeue参数设置为false, 则RabbitMQ会把消息从队列中移除, 而不会把它发送给新的消费者。

否定确认: Channel.basicNack(long deliveryTag, boolean multiple,boolean requeue)

Basic.Reject命令⼀次只能拒绝⼀条消息,如果想要批量拒绝消息,则可以使⽤Basic.Nack这个命令. 消费者客⼾端可以调⽤ channel.basicNack⽅法来实现。

代码实现

我们基于SpringBoot来演示消息的确认机制。Spring-AMQP 对消息确认机制提供了三种策略。

1. AcknowledgeMode.NONE
这种模式下, 消息⼀旦投递给消费者, 不管消费者是否成功处理了消息, RabbitMQ 就会⾃动确认
消息, 从RabbitMQ队列中移除消息. 如果消费者处理消息失败, 消息可能会丢失.
2. AcknowledgeMode.AUTO(默认)

这种模式下, 消费者在消息处理成功时会⾃动确认消息, 但如果处理过程中抛出了异常, 则不会确
认消息。
3. AcknowledgeMode.MANUAL
手动确认模式下, 消费者必须在成功处理消息后显式调⽤ basicAck ⽅法来确认消息. 如果消
息未被确认, RabbitMQ 会认为消息尚未被成功处理, 并且会在消费者可⽤时重新投递该消息, 这
种模式提⾼了消息处理的可靠性, 因为即使消费者处理消息后失败, 消息也不会丢失, ⽽是可以被
重新处理。

在application.yml文件中,设置消息确认的机制:

spring:
  application:
    name: rabbit-extensions-demo
  rabbitmq:
    address: amqp://study:study@47.108.157.13:5672/extension
    listener:
      simple:
#        acknowledge-mode: none  
#        acknowledge-mode: auto  #默认
        acknowledge-mode: manual  

生产端逻辑:

@RestController
@RequestMapping("/producer")
public class ProductController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @RequestMapping("/ack")
    public String ack(){
        rabbitTemplate.convertAndSend(Constant.ACK_EXCHANGE_NAME, "ack",
        "consumer ack test...");
    return "发送成功!";
    }
}

消费端逻辑:

@Component
public class AckQueueListener {
//指定监听队列的名称
  @RabbitListener(queues = Constant.ACK_QUEUE)
  public void ListenerQueue(Message message, Channel channel) throws  Exception {
    System.out.printf("接收到消息: %s, deliveryTag: %d%n", new
    String(message.getBody(),"UTF-8"),
    message.getMessageProperties().getDeliveryTag());
//模拟处理失败
    int num = 3/0;
    System.out.println("处理完成");
}

持久化

如何保证生产者发送消息到Broker,Broker在保存消息时,Broker发送到消费者之间,消息不会丢失。我们需要实现RabbitMQ的持久化

RabbitMQ的持久性分为三个部分:

交换机持久化

交换器的持久化是通过在声明交换机时是将durable参数置为true实现的。相当于将交换机的属性在服务器内部保存,当MQ的服务器发⽣意外或关闭之后,重启 RabbitMQ 时不需要重新去建⽴交换机。⼀个⻓期使⽤的交换器来说,建议将其置为持久化的。

在交换机的配置类中设置:

@Bean("directExchange")
        public DirectExchange  directExchange(){   //默认是true
           return ExchangeBuilder.directExchange(Constants.ACK_EXCHANGE).durable(true).build();
        }

队列持久化

队列的持久化是通过在声明队列时将 durable 参数置为 true实现的。
如果队列不设置持久化, 那么在RabbitMQ服务重启之后,该队列就会被删掉, 此时数据也会丢失。

队列的持久化能保证该队列本⾝的元数据不会因异常情况⽽丢失, 但是并不能保证内部所存储的消息不会丢失。 要确保消息不会丢失, 需要将消息设置为持久化。

 @Bean("ackQueue")
 public Queue ackQueue()
      return QueueBuilder.durable(Constants.ACK_QUEUE).build();
     }

消息持久化

消息实现持久化, 需要把消息的投递模式( MessageProperties 中的 deliveryMode )设置为2,
也就是 MessageDeliveryMode.PERSISTENT

设置了队列和消息的持久化, 当 RabbitMQ 服务重启之后, 消息依旧存在.

如果只设置队列持久化, 重启之后消息会丢失.

如果只设置消息的持久化, 重启之后队列消失, 继⽽消息也丢失.

所以单单设置消息持久化⽽不设置队列的持久化显得毫⽆意义.

在RabbitMQ配置类中设置:

//持久化
    @Bean("presQueue")
    public Queue presQueue(){
             return QueueBuilder.nonDurable(Constants.PRES_QUEUE).build();
    }

    @Bean("presExchange")
    public DirectExchange presExchange(){
             return ExchangeBuilder.directExchange(Constants.PRES_EXCHANGE).durable(false).build();
    }

    @Bean("presBinding")
    public Binding presBinding(@Qualifier("presQueue") Queue queue,@Qualifier("presExchange") Exchange exchange){
            return BindingBuilder.bind(queue).to(exchange).with("pres").noargs();
    }

以上,关于RabbitMQ,希望对你有所帮助。

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

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

相关文章

QML开发入门1--安装QT6.8和新建第一个QtQuickApplication

1.下载在线安装工具 qt-online-installer-windows-x64-4.8.1.exe 2.安装 注:可能官网qt安装很慢。需要使用国内镜像源。推荐阿里镜像 qt-online-installer-windows-x64-4.8.1.exe --mirror https://mirrors.aliyun.com/qt3.配置QT关键配置 3.1 无法编译 注&#…

如何让节卡机器人精准对点?

如何让节卡机器人精准对点? JAKA Zu 软件主界面主要由功能栏、开关栏、菜单栏构成。 菜单栏:控制柜管理,机器人管理与软件管理组成。主要功能为对控制柜关机、APP 设置、机器人本体设 置、控制柜设置、连接机器人和机器人显示等功能。 开关…

在 Spring Boot 中调用 AnythingLLM 的发消息接口

整体逻辑: 自建系统的web UI界面调用接口: 1.SpringBoot接口:/anything/chatMessageAnything 2.调用anythingLLM - 调用知识库deepseek r1 . Windows Installation ~ AnythingLLMhttps://docs.anythingllm.com/installation-desktop/windows http://localhost:3…

[GHCTF 2025]Popppppp[pop链构造] [php原生类的利用] [双md5加密绕过]

题目 <?php error_reporting(0);class CherryBlossom {public $fruit1;public $fruit2;public function __construct($a) {$this->fruit1 $a;}function __destruct() {echo $this->fruit1;}public function __toString() {$newFunc $this->fruit2;return $new…

Tr0ll2靶机详解

一、主机发现 arp-scan -l靶机ip&#xff1a;192.168.55.164 二、端口扫描、漏洞扫描、目录枚举、指纹识别 2.1端口扫描 nmap --min-rate 10000 -p- 192.168.55.164发现21端口的ftp服务开启 以UDP协议进行扫描 使用参数-sU进行UDP扫描 nmap -sU --min-rate 10000 -p- 19…

制造业数字化转型,汽车装备制造企业数字化转型案例,智能制造数字化传统制造业数字化制造业数字化转型案例

《某制造业企业信息化整体解决方案》PPT展示了一个汽车装备企业的整体信息化解决方案&#xff0c;阐述了该企业的业务特点和现状&#xff0c;主要包括按订单生产、多级计划和产品跟踪等&#xff0c;分析了信息化建设的主要困难&#xff0c;如信息管理手工化、过程数据追溯困难、…

科技云报到:AI Agent打了个响指,商业齿轮加速转动

科技云报到原创。 3月16日&#xff0c;百度旗下文心大模型4.5和文心大模型X1正式发布。目前&#xff0c;两款模型已在文心一言官网上线&#xff0c;免费向用户开放。 同时&#xff0c;文心大模型4.5已上线百度智能云千帆大模型平台&#xff0c;企业用户和开发者登录即可调用AP…

【蓝桥杯python研究生组备赛】005 数学与简单DP

题目1 01背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi&#xff0c;价值是 wi。 求解将哪些物品装入背包&#xff0c;可使这些物品的总体积不超过背包容量&#xff0c;且总价值最大。 输出最大价值。 输入格式 第一行两个整数&a…

大白话读懂java对象创建的过程

1. java对象创建流程&#xff08;大白话版&#xff09; 咱们java对象被创建的过程大致如下&#xff0c;即&#xff1a; 在 JVM 中对象的创建&#xff0c;从⼀个 new 指令开始&#xff1a; 首先检查这个指令的参数是否能在常量池中定位到⼀个类的符号引用检查这个符号引用代表…

AI图像理解技术的演进

在CLIP等现代多模态模型出现之前&#xff0c;早期的图生文技术主要依赖人工标注的ImageNet等数据集&#xff0c;但其技术路线与当前方法存在本质差异。 一、传统图生文技术的标注依赖 ImageNet的核心地位 在2012-2020年间&#xff0c;ImageNet的1,400万张人工标注图像&#xff…

电脑节电模式怎么退出 分享5种解决方法

在使用电脑的过程中&#xff0c;许多用户为了节省电力&#xff0c;通常会选择开启电脑的节能模式。然而&#xff0c;在需要更高性能或进行图形密集型任务时&#xff0c;节能模式可能会限制系统的性能表现。这时&#xff0c;了解如何正确地关闭或调整节能设置就显得尤为重要了。…

【Java】——程序逻辑控制(构建稳健代码的基石)

&#x1f381;个人主页&#xff1a;User_芊芊君子 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 &#x1f50d;系列专栏&#xff1a;【Java】内容概括 文章目录&#xff1a; 一.顺序结构二.分支结构1.if 语句1.1 语法格式11.2 语法格式21.3 语法格式3 …

卫星互联网智慧杆:开启智能城市新时代​

哇哦&#xff01;在当下这个数字化浪潮正以雷霆万钧之势席卷全球的超酷时代&#xff0c;智慧城市建设已然成为世界各国你追我赶、竞相发力的核心重点领域啦&#xff01;而咱们的卫星互联网智慧杆&#xff0c;作为一项完美融合了卫星通信与物联网顶尖技术的创新结晶&#xff0c;…

Qt-QChart实现折线图

一、介绍场景 动态查看数据变化&#xff0c;或者了解数据发展趋势&#xff0c;让数据可以形象直观展现出来&#xff0c;这里推荐使用折线图的方式展现&#xff0c;本文抛砖引玉&#xff0c;简单实现一个实例&#xff0c;效果图如下&#xff1a; 二、实现步骤 1、charts组件 …

取消Win10锁屏界面上显示的天气、市场和广告的操作

要取消Win10锁屏界面上显示的天气、市场和广告&#xff0c;您可以按照以下步骤操作&#xff1a; 方法一&#xff1a;更改锁屏界面设置 打开“设置”&#xff1a; 点击“开始”菜单&#xff0c;然后点击齿轮状的“设置”图标。 进入“个性化”&#xff1a; 在“设置”窗口中&a…

从TouchDriver Pro到Touchdriver G1,Weart触觉手套全系解析:XR交互的“真实触感”如何实现?

Weart旗下的Touchdriver Pro触觉手套和Touchdriver G1触觉手套&#xff0c;凭借其技术创新&#xff0c;为用户带来了全新的触觉体验。Touchdriver Pro触觉手套通过多模态触觉反馈技术&#xff0c;提供力反馈、纹理渲染和温度提示&#xff0c;让用户在虚拟环境中感受到真实的触觉…

排序算法实现:插入排序与希尔排序

目录 一、引言 二、代码整体结构 三、宏定义与头文件 四、插入排序函数&#xff08;Insertsort&#xff09; 函数作用 代码要点分析 五、希尔排序函数&#xff08;ShellSort&#xff09; 函数作用 代码要点分析 六、打印数组函数&#xff08;PrintSort&#x…

UDP协议原理

UDP协议原理 本篇介绍 在前面使用UDP编程时已经基本了解了UDP的工作模式&#xff0c;也知道了UDP有三个特点&#xff1a; 无连接不可靠面向数据报 但是当时并没有具体谈论为什么UDP有以上三个特点&#xff0c;基于这个原因&#xff0c;本篇就会针对这三个原因进行介绍 UDP…

EtherCAT转Modbus网关如何在倍福plc组态快速配置

EtherCAT转Modbus网关如何在倍福plc组态快速配置 在工业控制领域&#xff0c;EtherCAT和Modbus是两种常见的总线通信协议。EtherCAT以其高速的数据传输和灵活的网络配置被广泛应用于高性能自动化控制系统中&#xff0c;而Modbus则因其简单、稳定且兼容性强而被许多设备所支持。…

DooTask在Linux的离线部署教程

DooTask在Linux的离线部署教程 下载安装包 从网盘中将安装包下载到本地&#xff0c;下载地址 通过网盘分享的文件&#xff1a;DooTask项目管理工具 链接: https://pan.baidu.com/s/1hGmLXonT4c8hLiDP1QBr8w?pwdgdp6 提取码: gdp6 通过网盘分享的文件&#xff1a;DooTask项目…