目录

1. 重试机制

1.1 简介

1.2 配置文件 

1.3 消费者确认机制为 auto 时

1.4 消费者确认机制为 manual 时

2. TTL

2.1 设置消息的过期时间

2.2 设置队列的过期时间

2.3 给过期队列中消息设置过期时间


1. 重试机制

1.1 简介

在消息传递过程中, 可能会遇到各种问题, 如网络故障, 服务不可用, 资源不足... 这些问题可能导致消息处理失败. 为了解决这些问题, RabbitMQ 提供了重试机制, 允许消息在处理失败后重新发送. 但如果是程序逻辑引起的错误, 那么多次重试也是没有用的, 可以设置重试次数.

1.2 配置文件 

spring:application:name: rabbitmq-extensions-demorabbitmq:addresses: amqp://study:study@192.168.100.10:5672/extensionlistener:simple:
#        acknowledge-mode: noneacknowledge-mode: auto
#        acknowledge-mode: manualretry:enabled: true # 开启消费者失败重试initial-interval: 5000ms # 初始失败等待时长为5秒max-attempts: 5 # 最大重试次数
    //重试机制@Bean("retryQueue")public Queue retryQueue(){return QueueBuilder.durable(Constants.RETRY_QUEUE).build();}@Bean("retryExchange")public DirectExchange retryExchange(){return ExchangeBuilder.directExchange(Constants.RETRY_EXCHANGE).build();}@Bean("retryBinding")public Binding retryBinding(@Qualifier("retryQueue") Queue queue, @Qualifier("retryExchange") Exchange exchange){return BindingBuilder.bind(queue).to(exchange).with("retry").noargs();}

1.3 消费者确认机制为 auto 时

如果程序逻辑错误, 那么就会不断重试, 造成消息积压. 因此我们就需要设置重试次数, 当多次重试还是失败, 消息就会被自动确认, 自然消息就会丢失 (这里可以弄个死信队列, 来存储这些丢失的消息)

生产者 : 

    @RequestMapping("/retry")public String retry() {System.out.println("retry...");rabbitTemplate.convertAndSend(Constants.RETRY_EXCHANGE, "retry", "retry test...");return "消息发送成功";}

消费者 : 

@Component
public class RetryListener {@RabbitListener(queues = Constants.RETRY_QUEUE)public void handlerMessage(Message message) throws UnsupportedEncodingException {long deliveryTag = message.getMessageProperties().getDeliveryTag();System.out.printf("[" + Constants.RETRY_QUEUE + "]接收到消息: %s, deliveryTag: %s \n",new String(message.getBody(), StandardCharsets.UTF_8), deliveryTag);int num = 3/0;System.out.println("业务处理完成");}
}

由于消费者代码逻辑错误, 消息重发机制触发了 4 次, 一共发了 5 次, 日志中, 每次的 deliverTag 都一样, 表示发送的是同一个消息.  

查看队列中消息也已经被删除.

1.4 消费者确认机制为 manual 时

更改消费者 : 

    @RabbitListener(queues = Constants.RETRY_QUEUE)public void handlerMessage(Message message, Channel channel) throws Exception {long deliveryTag = message.getMessageProperties().getDeliveryTag();System.out.printf("[" + Constants.RETRY_QUEUE + "]接收到消息: %s, deliveryTag: %s \n",new String(message.getBody(), StandardCharsets.UTF_8), deliveryTag);try {int num = 3/0;System.out.println("业务处理完成");channel.basicAck(deliveryTag, false);}catch (Exception e){// 不成功消息重新入队列channel.basicNack(deliveryTag, false, true);}}

这里我们发现, 虽然我们设置了重试机制, 但是 deliveryTag 还是在不断更新... 队列中的消息也不会消失. 原因是手动模式下, 消费者需要显示的对消息进行确认, 如果消费者在消息处理过程中遇到异常, 可以选择确认, 不确认消息,也可以选择重新入队. 所以重试的控制权不在应用程序本身, 而在于代码逻辑本身.

  • 消费者确认机制为 AUTO 时, 如果程序逻辑异常, 多次重试还是失败. 那么消息就会自动确认, 进而消息就会丢失.
  • 消费者确认机制为 MANAUL 时, 如果程序逻辑异常, 多次重试依然处理失败, 无法被确认, 消息就会积压.
  • 消费者确认机制为 NONE 时, 不管发生什么情况, 当消息从 Broker 内部发出时, 就会自动确认, 因此它不存在任何内容

2. TTL

TTL -> time to live, 指的是过期时间.

  • 给消息设置过期时间 : 当消息到达过期时间, 还没有被消费, 就会被自动清除.
  • 给队列设置过期时间 :  就相当于给队列的所有消息设置了一个过期时间, 这消息的过期时间与队列的过期时间是相同的. 从消息入队列开始算起, 经过这个时间, 就会被删除

2.1 设置消息的过期时间

    @Bean("ttlQueue")public Queue ttlQueue(){return QueueBuilder.durable(Constants.TTL_QUEUE).build();}@Bean("ttlExchange")public DirectExchange ttlExchange(){return ExchangeBuilder.directExchange(Constants.TTL_EXCHANGE).build();}@Bean("ttlBinding")public Binding ttlBinding(@Qualifier("ttlQueue") Queue queue, @Qualifier("ttlExchange") Exchange exchange){return BindingBuilder.bind(queue).to(exchange).with("ttl").noargs();}
    @RequestMapping("/ttl")public String ttl() {System.out.println("ttl...");MessagePostProcessor messageInfo = new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws AmqpException {message.getMessageProperties().setExpiration("30000"); //单位: 毫秒, 过期时间为30sreturn message;}};rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test 30s", messageInfo);rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test 10s...", message -> {message.getMessageProperties().setExpiration("10000");  //单位: 毫秒, 过期时间为10sreturn message;});return "消息发送成功";}

不需要消费者, 不然看不到消息在队列中的自动删除.

2.2 设置队列的过期时间

    //设置ttl@Bean("ttlQueue2")public Queue ttlQueue2(){return QueueBuilder.durable(Constants.TTL_QUEUE2).ttl(20000).build();  //设置队列的ttl为20s}@Bean("ttlBinding2")public Binding ttlBinding2(@Qualifier("ttlQueue2") Queue queue, @Qualifier("ttlExchange") Exchange exchange){return BindingBuilder.bind(queue).to(exchange).with("ttl").noargs();}
    @RequestMapping("/ttl2")public String ttl2() {System.out.println("ttl2...");//发送普通消息rabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE, "ttl", "ttl test...");return "消息发送成功";}

我们发现了消息经过 20 秒后被删除了, 但是队列没有被删除, 说明过期队列是给消息上过期时间的. 这个队列也有 TTL 的标志了.

2.3 给过期队列中消息设置过期时间

如果两种方法同时使用, 那么就以过期时间较小的值为准.

设置队列的过期时间, 一旦消息过期, 就会从队列中删除.

设置消息的过期时间, 即使消息过期, 如果消息不在队首, 还得等到消息到达队首之后才会进行判定是否过期. 如果过期, 那就删除, 反之就投递到相应的消费者中.

为什么这两种方法处理的方式不一样?

因为设置队列的过期时间, 那么队列中过期的消息一定在队首, RabbitMQ 只需要定期从队首扫描消息是否有过期的消息即可, 而设置消息的过期时间, 每条消息的过期时间都不一致, 如果要删除队列的所有过期消息那么就要扫描整个队列, 所以不如等到消息要进行投递时再判断消息是否过期, 这样可以减少一定的资源消耗.

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

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

相关文章

四、FVP启动linux

目录 1 实验目的及环境 1.1 实验目的 1.2 实验环境 1.2.1 拉取代码 1.2.2搭建交叉编译环境 2 相关镜像编译 2.1 TF-A镜像编译 2.2 U-Boot镜像编译 2.3 Linux Kernel镜像编译 2.4 构建跟文件系统 3 启动linux内核 3.1 启动脚本构建 3.2 启动Linux内核 1 实验目的及环境 1.1 实验…

浅聊一下微服务的服务保护

在微服务架构里,服务间调用关系错综复杂,一个服务出问题很可能引发连锁反应,也就是 “雪崩”。今天就带大家从零开始学习 Sentinel,这款阿里开源的微服务保护工具,帮你解决雪崩难题,做好流量控制、隔离降级…

ECharts Gallery:Apache官方数据可视化模板库,助你快速制作交互图表并实现深度定制

你有没有过这种时候?手里攥着一堆 Excel 数据,想做个直观的图表给同事看,用 Excel 自带的图表吧,样式丑不说,稍微复杂点的交互(比如点击柱子显示详情)根本做不了;想自己用代码写吧&a…

[数据结构——lesson3.单链表]

目录 引言 学习目标: 1.什么是链表 2.链表的分类 2.1 单向链表和双向链表 (1)单向链表 (2)双向链表 2.2 带头结点链表和不带头结点链表 (1)带头结点链表 (2)不带头结点链表 2.3 循环链表和不循环链表 (1)循环链表 (2)非循环链表 3.链表的实…

从零深入理解嵌入式OTA升级:Bootloader、IAP与升级流程全解析

引言(Opening)想象一下,你开发的一款智能水杯、一个环境监测设备或者一台共享充电宝,已经部署到了成千上万的用户手中。突然,你发现了一个软件bug,或者需要增加一个酷炫的新功能。你不可能派人跑到每个设备…

【Ansible】实施 Ansible Playbook知识点

1.清单概念与静态清单文件是什么?答:Ansible 清单是被管理主机的列表,用于明确Ansible的管理范围,分为静态清单和动态清单。静态清单是通过手动编辑的文本文件来定义被管主机,文件格式可以是INI格式或YAML格式。在INI格…

【Linux】vim工具篇

目录一、vim的多模式1.1 命令模式1.1.1 光标移动1.1.2 复制及撤销1.1.3 剪切及删除1.1.4 替换1.1.5 批量化注释/去注释1.2 底行模式二、vim的配置个人主页<—请点击 Linux专栏<—请点击 一、vim的多模式 vim是一款功能强大的文本编辑器&#xff0c;它编辑代码主要围绕命…

Spark 核心原理:RDD, DataFrame, DataSet 的深度解析

Apache Spark 是一个强大的分布式计算系统&#xff0c;以其内存计算、速度快、易用性强等特点&#xff0c;在大数据处理领域占据重要地位。理解 Spark 的核心原理&#xff0c;特别是其三种核心抽象——RDD, DataFrame, DataSet——对于高效地使用 Spark 至关重要。本文将深入解…

Docker 命令行的使用

1.Docker 命令列表[roothost1 ~]# docker Usage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersCommon Commands:run Create and run a new container from an imageexec Execute a command in a running containerps List cont…

Redis Stream:轻量级消息队列深度解析

&#x1f4e8; Redis Stream&#xff1a;轻量级消息队列深度解析 文章目录&#x1f4e8; Redis Stream&#xff1a;轻量级消息队列深度解析&#x1f9e0; 一、Stream 数据结构解析&#x1f4a1; Stream 核心概念&#x1f4cb; Stream 底层结构⚡ 二、消息生产与消费&#x1f68…

Android studio的adb和终端的adb互相抢占端口

在Android Studio调试时&#xff0c;有时候也需要借助终端的adb命令&#xff0c;他们互相抢占端 口&#xff0c;导致调试麻烦解决如下&#xff1a;① 终端adb的版本是&#xff1a;1.0.39路径是:/usr/lib/android-sdk/platform-tools/adb② Android Studio使用的adb来源于Androi…

GEO服务商推荐:移山科技以划时代高精尖技术引领AI搜索优化新纪元

引言&#xff1a;AI搜索生态重塑与GEO优化战略地位跃升AI技术对信息检索范式的颠覆GEO优化在企业增长中的核心作用第一章&#xff1a;AI搜索新纪元的企业营销挑战与机遇生成式AI成为用户主要信息入口的行业趋势企业在AI搜索中的“答案主权”争夺战GEO优化服务商的核心能力模型&…

Android SystemServer 系列专题【AttentionManagerService】

AttentionManagerService是framework中用来实现屏幕感知的一个系统级服务&#xff0c;他继承于systemserver。我们可以通过dumpsys attention来获取他的一些信息。如下针对屏幕感知的功能的引入来针对这个服务进行一个介绍。1、屏幕感知Settings UI实现屏幕感知的功能在A14上面…

nginx 反向代理使用变量的坑

nginx采用反向代理的时候使用变量的坑 正常情况&#xff1a; location ~ ^/prod-api(?<rest>/.*)?$ {# 假设 $mes_backend 形如: http://127.0.0.1:16889proxy_pass $mes_backend$rest$is_args$args;proxy_http_version 1.1;proxy_set_header Host $host;…

Origin绘制径向条形图|科研论文图表教程

数据排列格式截图&#xff0c;请查看每张图↘右下角水印 目录 数据排列格式截图&#xff0c;请查看每张图↘右下角水印 本 期 导 读 No.1 理解图形 1 定义 2 特点 3 适用场景 No.2 画图教程 1 导入数据&#xff0c;绘制图形 2 设置绘图细节 本 期 导 读 径…

MySQL InnoDB 的 MVCC 机制

前言 多版本并发控制&#xff08;MVCC&#xff09;是 MySQL InnoDB 存储引擎实现高性能事务的核心机制。它通过创建数据快照&#xff0c;使得读写操作可以无锁并发&#xff0c;极大地提升了数据库的并发性能。本文将深入探讨 MVCC 的工作原理、实现细节以及它与事务隔离级别的紧…

景区负氧离子气象站:引领绿色旅游,畅吸清新每一刻

在绿色旅游成为消费主流的今天&#xff0c;游客对 “清新空气” 的需求不再是模糊的期待&#xff0c;而是可感知、可选择的具体体验。景区负氧离子气象站的出现&#xff0c;正以科技之力重塑绿色旅游格局&#xff0c;让 “畅吸清新每一刻” 从口号变为触手可及的现实&#xff0…

Pytorch笔记一之 cpu模型保存、加载与推理

Pytorch笔记一之 cpu模型保存、加载与推理 1.保存模型 首先&#xff0c;在加载模型之前&#xff0c;我们需要了解如何保存模型。PyTorch 提供了两种保存模型的方法&#xff1a;保存整个模型和仅保存模型的状态字典&#xff08;state dict&#xff09;。推荐使用第二种方式&…

当AI在代码车间组装模块:初级开发者的创意反成「核心算法」

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录当AI在…

技术视界 | 跨域机器人通信与智能系统:打破壁垒的开源探索

8 月 16 日&#xff0c;在 OpenLoong 社区举办的第九期线下分享会上&#xff0c;国家地方共建人形机器人创新中心的软件开发负责人 Amadeus 博士带来了一场主题为“跨域机器人通信与智能系统&#xff1a;打破行业壁垒的创新方案”的演讲。深入探讨了当前机器人领域的一个关键痛…