rabbitMQ手动应答与自动应答
手动应答模式(manual)
解释:
手动应答:既是当消费者消费了队列中消息时需要给队列一个应答,告诉队列这条消息我已经消费了,可以删除了;
若是不应答,即使消费了 队列没收到消费成功的提示 所有消息会一直在队列中;
注意 注意 注意:重要的事情说三遍,下面说的很重要
场景:当我们使用了手动应答模式,消费者若是成功消费了信息,我们给队列一个成功应答(channel.basicAck(deliveryTag,false);),然后队列收到应答后就会把此消息删除,这点时毋庸置疑的,因为我们已成功消费了这个消息,也不想让此消息继续留在队列中;
但是,若是消费者消费消息失败了,该怎么办? 这时不能再给队列一个成功的应答(给了那这条消息不就丢失了吗),不给应答呢 消息又一直在队列中,而倘若我们给一个拒绝应答(channel.basicReject(deliveryTag,true) true会重回队列,若是false 消息就丢了,一般都会设置为true;),那么你就成功掉进坑里了,这样队列会一直循环投递消息,而消费者这边又不能成功消费,消费者又拒绝应答,队列又投递消息......
对,此时就会进入死循环,搞不好光错误日志就会沾满内存;这时该有人会说了,不对,我们在配置文件中不是开启了重试,并且配置了最大重试次数了吗?
如下配置:
* #是否开启自动重试 默认为false 不开启
* spring.rabbitmq.listener.simple.retry.enabled=true
* #最大重试次数
* spring.rabbitmq.listener.simple.retry.max-attempts=5
* #最大重试时间间隔
* spring.rabbitmq.listener.simple.retry.max-interval=20000ms
* #重试时间间隔
* spring.rabbitmq.listener.simple.retry.initial-interval=2000ms
* # 最大重试间隔*乘数
* #应用于上一重试间隔的乘数 第一次(重试时间间隔)2s 4s 8s 16s 32s 此处32s>20s 以后都以20s为间隔 总的次数为最大重试次数
* spring.rabbitmq.listener.simple.retry.multiplier=2
那么,应该会在最大重试次数试完还不成功就应该不尝试投递了啊,这样不应该走死循环了啊!
其实这就是要特别注意的点,当我们开启了手动应答时 当消息没被成功消费并给队列拒绝时上面那些配置其实都已经失效了!!! 所以就会进入死循环!
但是在开发中我们不想让消息丢失,那么开启自动应答显然不合理,而开启手动应答时当出现错误时(没成功消费)又会进入死循环,那该怎么解决呢?
解决:引入死信队列; 当消息没被成功消费时 我们把这条消息投递到私信队列中,然后我们再人为的干预处理此消息即可!
自动应答:顾名思义 当消费者成功消费了队列中消息,队列就会自动的把此消息从队列中删除,若是没有消费者或者消费者消费失败,队列在尝试最大重试次数后就会把此消息删除;
注意:
手动模式 若消息没成功消费时,若给队列拒绝(重试机制不生效),则会进入死循环,若不给拒绝 抛出异常(重试机制生效) 则消息会堆积在队列中,后续投递的消息也会堆积并不会被消费
/*** 消费者*/@Component
@Slf4j
public class DirectConsumer {/*** 手动应答模式(manual)* 解释:* 手动应答:既是当消费者消费了队列中消息时需要给队列一个应答,告诉队列这条消息我已经消费了,可以删除了;* 若是不应答,即使消费了 队列没收到消费成功的提示 所有消息会一直在队列中;* 注意 注意 注意:重要的事情说三遍,下面说的很重要* 场景:当我们使用了手动应答模式,消费者若是成功消费了信息,我们给队列一个成功应答(channel.basicAck(deliveryTag,false);),* 然后队列收到应答后就会把此消息删除,这点时毋庸置疑的,因为我们已成功消费了这个消息,也不想让此消息继续留在队列中;* 但是,若是消费者消费消息失败了,该怎么办? 这时不能再给队列一个成功的应答(给了那这条消息不就丢失了吗),不给应答呢 消息又一直在队列中* 而倘若我们给一个拒绝应答(channel.basicReject(deliveryTag,true) true会重回队列,若是false 消息就丢了,一般都会设置为true;)* 那么你就成功掉进坑里了,这样队列会一直循环投递消息,而消费者这边又不能成功消费,消费者又拒绝应答,队列又投递消息......* 对,此时就会进入死循环,搞不好光错误日志就会沾满内存;这时该有人会说了,不对,我们在配置文件中不是开启了重试,并且配置了最大重试次数了吗?* 如下配置:* #是否开启自动重试 默认为false 不开启* spring.rabbitmq.listener.simple.retry.enabled=true* #最大重试次数* spring.rabbitmq.listener.simple.retry.max-attempts=5* #最大重试时间间隔* spring.rabbitmq.listener.simple.retry.max-interval=20000ms* #重试时间间隔* spring.rabbitmq.listener.simple.retry.initial-interval=2000ms* # 最大重试间隔*乘数* #应用于上一重试间隔的乘数 第一次(重试时间间隔)2s 4s 8s 16s 32s 此处32s>20s 以后都以20s为间隔 总的次数为最大重试次数* spring.rabbitmq.listener.simple.retry.multiplier=2* 那么,应该会在最大重试次数试完还不成功就应该不尝试投递了啊,这样不应该走死循环了啊!* 其实这就是要特别注意的点,当我们开启了手动应答时 当消息没被成功消费并给队列拒绝时上面那些配置其实都已经失效了!!! 所以就会进入死循环!* 但是在开发中我们不想让消息丢失,那么开启自动应答显然不合理,而开启手动应答时当出现错误时(没成功消费)又会进入死循环,那该怎么解决呢?** 解决: 引入死信队列; 当消息没被成功消费时 我们把这条消息投递到私信队列中,然后我们再人为的干预处理此消息即可!*** 自动应答:顾名思义 当消费者成功消费了队列中消息,队列就会自动的把此消息从队列中删除,若是没有消费者或者消费者* 消费失败,队列在尝试最大重试次数后就会把此消息删除;** 注解含义:* 1、@RabbitHandler handler真正的执行者* 2、@RabbitListener 监听DirectQueue-01这个队列** @param user 接受的消息类型为user(生产者发送的为user类型)* @param message* @param channel* @throws IOException*/@RabbitHandler@RabbitListener(queues = RabbitConfig.QUEUE_KEY_03)public void process2(User user, Message message, Channel channel) throws IOException {
// long deliveryTag = message.getMessageProperties().getDeliveryTag();try {//业务开始if (user.getId().equals(5)) {int a=1/0;}System.out.println("接受到消息,并正常处理结束"+ JSONUtil.toJsonStr(user));//业务结束/*** 确认应答* basicAck(long deliveryTag, boolean multiple)* deliveryTag:当前消息在队列中的的索引;* multiple:为true的话就是批量确认 是消费一个就应答还是一批处理完再应答;通常都是false 一个一个应答*/// channel.basicAck(deliveryTag,false);}catch (Exception ex){System.out.println(ex.getMessage());System.out.println("接受到消息,发生异常"+ JSONUtil.toJsonStr(user));System.out.println(user);throw ex;//拒绝 true的时候拒绝,false时消息就丢了
// channel.basicReject(deliveryTag,true);}}
}
相关文章:
rabbitMQ手动应答与自动应答
手动应答模式(manual) 解释: 手动应答:既是当消费者消费了队列中消息时需要给队列一个应答,告诉队列这条消息我已经消费了,可以删除了; 若是不应答,即使消费了 队列没收到消费成功的提示 所有消息会一直在队列中; 注意 注意 注意:重要的事情说三遍,下面说的…...

java对象创建的过程
1、检查指令的参数是否能在常量池中定位到一个类的符号引用 2、检查此符号引用代表的类是否已被加载、解析和初始化过。如果没有,就先执行相应的类加载过程 3、类加载检查通过后,接下来虚拟机将为新生对象分配内存。 4、内存分配完成之后,…...

WireShark流量抓包详解
目录 Wireshark软件安装Wireshark 开始抓包示例Wireshakr抓包界面介绍WireShark 主要界面 wireshark过滤器表达式的规则 Wireshark软件安装 软件下载路径:wireshark官网。按照系统版本选择下载,下载完成后,按照软件提示一路Next安装。 Wire…...
【密码学代码分享】突破ECDSA算法封装--JS无三方包纯手写ECDSA
ECDSA(Elliptic Curve Digital Signature Algorithm)是一种基于椭圆曲线密码学的数字签名算法。它用于确保数字数据的完整性和身份验证,通常在信息安全和加密通信中使用。在日常使用中,通常会使用一些函数库来实现完成这个算法的功…...

stable diffusion实践操作-文生图
本文专门开一节写文生图相关的内容,在看之前,可以同步关注: stable diffusion实践操作 正文 1 liblib SD1.5底模 lora(baihuaniang_1.0) 详细信息: 底模:SD 1.5 Lora:baihuaniang_1.0 正向提示词: Best …...

Spring容器及实例化
一、前言 Spring 容器是 Spring 框架的核心部分,它负责管理和组织应用程序中的对象(Bean)。Spring 容器负责创建、配置和组装这些对象,并且可以在需要时将它们提供给应用程序的其他部分。 Spring 容器提供了两种主要类型的容器&…...
# Go学习-Day9
文章目录 Channel声明存入取出一个简单的死锁分析 个人博客:CSDN博客 Channel Channel本质是一个队列多goroutine访问时不需要加锁,Channel天然线程安全channel有类型,只能写入相同类型channel是引用类型channel必须初始化才能写入数据&…...
chatGPT如何在Java中使用
ChatGPT是一个基于GPT模型的聊天机器人平台,它提供了API接口,可以通过HTTP请求与之交互。您可以使用Java编写程序,通过HTTP请求与ChatGPT进行交互,实现聊天机器人的功能。 具体步骤如下: 1、注册ChatGPT账号并创建应…...
vue+axios——创建多个实例共用请求拦截器和响应拦截器(403错误信息不提示bug解决)——基础积累
创建多个实例共用请求拦截器和响应拦截器:使用的是函数的继承,也就是call()方法,这个方法第一个参数就是this,后面的参数可以是一个也可以是多个。最后一定要记得要return出去,否则接口是拿不到数据的。 import axios from axios…...

全球免费编程教育网站:Code.org
全球免费编程教育网站:Code.org 官网地址注册使用 你还在为小朋友的编程教育而发愁吗? 你还在为小朋友放假无聊而头疼吗? 他来了他来了,全球免费编程教育网站来了。 2013年成立的Code.org是一个非营利组织。 它致力于为年轻女子、…...

构造函数与成员变量初始化
C自学精简教程 目录(必读) 1 为什么需要定义构造函数? 构造函数主要用来给成员变量初始化。 让类对象有一个良好的开始状态。 2 构造函数初始化成员变量 下面我们来完善上一篇文章中的几个构造函数。 让这些构造函数完成给成员变量初始化的职责。 为此&#…...
使用Go env命令设置Go的环境
文章目录 前言Linux的设置Windlows设置Go version > 1.13 当你的GO的版本大于1.13的时候 Set environment variable allow bypassing the proxy for selected modules 前言 在进行Go开发的时候,设置Go的环境变量信息是必须的。下面介绍windows和Linux࿰…...
目标检测YOLO实战应用案例100讲-道路场景下目标检测与分割模型的压缩研究与实现(续)
目录 道路场景下目标检测与语义分割模型的改进研究 3.1 道路场景数据集分析 3.1.1 Cityscapes数据集...

b站手机缓存文件转MP4
b站缓存的文件 音频、视频、弹幕是分开的 这里我只用到了音频和视频所以只介绍这一部分 b站的缓存视频文件和路径结构如下 默认缓存路径 内部存储\Android\data\tv.danmaku.bilil\download\89720189 文件夹结构 文件夹 c_738583 这是单个视频的缓存文件夹 进入c_738583文件夹…...

一个集成的BurpSuite漏洞探测插件1.2
4、DNSLog查询漏报 注:扫描结束后才会在BurpSuite的Target、Dashboard模块显示高危漏洞,进程扫描中无法进行同步,但可以在插件中查看(涉及到DoPassive方法问题)。...
[FMMPEG] parse与 demuxer
FFmpeg源码分析:av_parser_parse2()解析数据包 ffmpeg 4.3添加自定义demuxer ffmpeg API基础...

【Bug】Ubuntu 有线设置打不开无反应
前言: 突然有线设置就没法启用了,但是能联网,能查看ip 解决: 最后安装了一个新的依赖包: sudo apt install gnome-control-center 然后就可以了 还有一个方法,没试过,但感觉有点道理的&#…...

迈向无限可能, ATEN宏正领跑设备切换行业革命!
随着互联网在各个领域的广泛应用,线上办公这一不受时间和地点制约、不受发展空间限制的办公模式开始广受追捧,预示着经济的发展正朝着新潮与活跃的方向不断跃进。当然,在互联网时代的背景下,多线程、多设备的线上办公模式也催生了许多问题:多设备间无法进行高速传输、切换;为保…...
Ubuntu18.04:ORB-SLAM3使用数据集构建地图和保存点云地图
文章目录 保存地图方法一:使用ORB-SLAM3自带的保存方法(oea后缀文件)保存地图方法二:使用PCL库保存为PCD类型地图文件安装PCL库:取巧方法:CMakeLists.txt 文件修改内容:(向该文件内添…...

找到自制电子杂志的方法了,快来看看?
终于找到自制电子杂志的方法了,这真是令人兴奋啊!现在,我们可以利用这个方法来创造属于自己的电子杂志,将我们的想法和创意以独特的方式展现给世界。 1.需要一个电子杂志制作工具 市面上有许多专门用于制作电子杂志的工具&#x…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...