Redisson 延时队列 监听线程中调用 return 造成线程终止 消息积压 无法被消费

本文主要是介绍Redisson 延时队列 监听线程中调用 return 造成线程终止 消息积压 无法被消费,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

博文目录

文章目录

  • 结论
  • 过程
  • 流程


结论

单线程 while(true) 监听 Redisson 延时队列有几个注意点

  • 死循环内必须加 try-catch 捕获 Throwable, 防止报错终止线程
  • 明确线程方法体死循环内的 return 语句是否会导致方法体执行结束, 进而导致线程终止, 考虑是否需要以 continue 替代

生产上线不要夹带私货, 私货往往没有经过完整的测试流程验证, 容易出问题

过程

开发使用 Redisson 延时队列, 完成编码后, 自测没有问题, 在发版时以夹带私货的方式上线了, 在生产运行中出现消息消息无法消费的情况

原因是在线程方法体中有一些条件判断, 当消息不符合条件的时候, 会通过 return 阻断流程执行. 开发自测时模拟的数据有限, 且都没有走到阻断分支, 所以没有发现问题. 而生产上有一些数据会走到阻断流程, 执行 return 导致线程方法体退出死循环并执行结束, 最终导致线程终止, 无法再继续监听消息

流程

Redisson (3.17.7) 延时队列 利用 Redis List 和 ZSet 以及 发布/订阅 功能实现, 整个过程会涉及到 3 个 Key

  • 阻塞队列: redisson_delay_queue:{test}, 是一个 List, 通过阻塞操作 take 读取数据
  • 延时队列: redisson_delay_queue_timeout:{test}, 是一个 ZSet, 通过 offer 写入数据
  • 普通队列, test, 是一个 List, 当消息积压时, 可能会把积压消息转存进来

监听线程死循环 take 阻塞队列, 当延时队列中的消息到期, 会被转存到阻塞队列共监听线程消费, 如果一定时间内未消费, 则会创建普通队列, 并把消息转存进去, 待监听线程重新上线, 先读取普通队列内的消息, 读取完后会删除普通队列, 再阻塞读取阻塞队列内的消息

这篇关于Redisson 延时队列 监听线程中调用 return 造成线程终止 消息积压 无法被消费的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/640262

相关文章

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

Oracle修改端口号之后无法启动的解决方案

《Oracle修改端口号之后无法启动的解决方案》Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见,但并非必然发生,这一问题通常源于​​配置错误或环境冲突​​,而非端口修改本身,以下是系... 目录一、问题根源分析​​​二、保姆级解决方案​​​​步骤1:修正监听器配置文件 (listener.

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

SpringBoot3中使用虚拟线程的完整步骤

《SpringBoot3中使用虚拟线程的完整步骤》在SpringBoot3中使用Java21+的虚拟线程(VirtualThreads)可以显著提升I/O密集型应用的并发能力,这篇文章为大家介绍了详细... 目录1. 环境准备2. 配置虚拟线程方式一:全局启用虚拟线程(Tomcat/Jetty)方式二:异步

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socket read timed out的问题

《如何解决Druid线程池Cause:java.sql.SQLRecoverableException:IO错误:Socketreadtimedout的问题》:本文主要介绍解决Druid线程... 目录异常信息触发场景找到版本发布更新的说明从版本更新信息可以看到该默认逻辑已经去除总结异常信息触发场景复

VS配置好Qt环境之后但无法打开ui界面的问题解决

《VS配置好Qt环境之后但无法打开ui界面的问题解决》本文主要介绍了VS配置好Qt环境之后但无法打开ui界面的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目UKeLvb录找到Qt安装目录中designer.UKeLvBexe的路径找到vs中的解决方案资源

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性