记一次线程堵塞(挂起)导致消息队列积压
1 背景
A服务作为生产者,每天发送上千万的mq消息,每一个消息包含500个用户ids数据。B服务作为消费者,接受MQ消息并通过http调用第三方请求进行业务处理,消费组启用了rabbitmq的多线程消费组,一个实例并发40个mq消费者线程,每个线程一次获取10个消息进行消费。
Mq消费者配置如下:
# mq配置rabbitmq:connection-timeout: 15000cache:channel:size: 200# 消息发送到rabbitmq broker cluster需要回调publisher-confirms: true# 交换机将消息投递至队列失败时需要回调publisher-returns: truelistener:# 手动确认消息已被消费simple:acknowledge-mode: manual# consumer的并发数concurrency: 40max-concurrency: 50# 每个消息者每次取10条prefetch: 10
Mq挤压消息如下

2 排查
2.1 复制rabbitmq挤压消息数据进行模拟复现
找出rabbitmq挤压的消息,在本地模拟消费,找出没有进行消息确认的原因,通过rabbitmq控制台的Get messages功能

复制payload的消息进行base64转码,转出来的消息是乱码不完整的,怀疑
是rabbitmq还结合了其他加密处理,放弃这种排查思路
2.2 检查报错日志
rabbitmq的unack消息挤压,那就是消费者没有进行ack确认,怀疑消费者代码有异常导致没能执行到ack的代码。
查询服务器日志,没发现有报错的日志,梳理业务代码,消费者使用了spring aop around机制进行消息确认,所以不管代码有没有报错,按理说都会手动进行mq消息ack确认
2.3 检查服务是否宕机
消费组实例数量符合服务器大小配置,因此服务器应用没有宕机

2.4 检查java线程
使用IBM的TMDA工具进行分析线程堆栈,工具下载地址
TMDA工具下载地址
TMDA工具简介
TMDA分析线程堆栈结果如下

通过分析图,看到大量park线程,确实是符合现状,应用的线程挂起了
3 分析和解决
通过stack深度高到底排序,业务代码存在线程等待情况,具体代码CountDownLatch.await

3.1 结合业务代码分析
通过上图stack提示,找到关联的业务代码
伪代码如下:
// new一个CompletableFuture
public CompletableFuture<Integer> httpCall(String tokenData){CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {long time = 3000L;try {Thread.sleep(time);} catch (InterruptedException e) {e.printStackTrace();}return Integer.parseInt(tokenData);});return completableFuture;}httpCall(tokenData).whenCompleteAsync((returnValue, ex)->{// do business// ex.getMessage()// 其中ex对象为空,使用ex.getMessage()报了空指针,导致没能执行如下的countDowncountDownLatch.countDown();})
消费者服务通过http调用第三方服务,为了提高并发,使用了多线程,每一组(数十个为一组)http请求批量调用完成后再把请求响应结果异步存入数据库,
主线程使用了countDownLatch.await进行等待,
其中whenCompleteAsync方法存在空指针问题,导致没能执行如下的countDown方法。
这里有人会问, 上面错误日志检查步骤,不是说日志没有空指针异常吗?
对,子线程报了空指针,因为CompletableFuture执行每次都是new 一个新的CompletableFuture对象,并把结果作为下一个CompletableFuture执行的入参,
通过伪代码可以发现,执行whenCompleteAsync后,没有新的CompletableFuture方法执行,所以异常没有抛出来,使得排查变得困难
3.2 解决
因为存在whenCompleteAsync报错的情况,添加多一个新的异常捕获处理方法,捕获异常也进行countDown的操作。
代码如下:
httpCall(tokenData).whenCompleteAsync((returnValue, ex)->{// do business// ex.getMessage()// 其中ex对象为空,使用ex.getMessage()报了空指针,导致没能执行如下的countDowncountDownLatch.countDown();}).exceptionally(e ->{log.info("exceptionally捕获到异常,tokenData={}, e={}", tokenData, e.getMessage());countDownLatch.countDown();return null;});
4 结论
-
熟练CompletableFuture的使用,要看源码的实现(实现原理cas + 多个future采用入stack,每次把前一个future的结果作为参数传入下一个future去执行)
-
使用多线程需要考虑异常、超时等情况
-
熟练使用jvm stack分析工具
5 文章参考
CompletableFuture流程图

CompletableFuture参考文章如下
CompletableFuture 原理浅析
相关文章:
记一次线程堵塞(挂起)导致消息队列积压
1 背景 A服务作为生产者,每天发送上千万的mq消息,每一个消息包含500个用户ids数据。B服务作为消费者,接受MQ消息并通过http调用第三方请求进行业务处理,消费组启用了rabbitmq的多线程消费组,一个实例并发40个mq消费者…...
被问实习最大的收获是什么可以怎么回答?
最大的收获? 了解大型项目的运转过程:总工程师给开发和测试串讲需求->开发编写需求的特性说明书,完成需求方案设计和评审->编码完成后对各个场景进行自测,上库后给相关模块人进行代码检视后并修改检视意见->在每个迭代转…...
如何理解图神经网络的傅里叶变换和图卷积
图神经网络(GNN)代表了一类强大的深度神经网络架构。在一个日益互联的世界里,因为信息的联通性,大部分的信息可以被建模为图。例如,化合物中的原子是节点,它们之间的键是边。图神经网络的美妙之处在于它们能…...
国家网络安全周2023时间是什么时候?有什么特点?谁举办的?
国家网络安全周2023时间是什么时候? 2023年国家网络安全宣传周将于9月11日至17日在全国范围内统一开展。其中开幕式等重要活动将在福建省福州市举行。今年网安周期间,除开幕式外,还将举行网络安全博览会、网络安全技术高峰论坛、网络安全微视…...
windows编程之线程同步万字总结(创建线程,互斥对象,互斥事件,信号量,关键段,多线程群聊服务器)
文章目录 创建线程方法一_beginthreadex函数讲解使用示例: 方法二CreateThread函数讲解:使用示例: 互斥对象:创建互斥对象CreateMutex 互斥事件介绍创建或打开一个未命名的互斥事件对象 信号量介绍信号量的相关函数使用示例 关键段相关函数错误使用示例正确使用示例…...
Git在已有的项目中引入Submodule子模块管理:添加、更新、删除(实战示例代码)
前言 在进行Git版本控制的过程中,有时候我们需要在已有的项目中引入子模块,以便复用其他独立的Git存储库的代码或文件。本文将详细介绍如何在已有项目下添加、更新和删除Git的Submodule子模块,并提供相关的示例代码。 实战场景 假设我们已…...
内网穿透实现Windows远程桌面访问Ubuntu,简单高效的远程桌面解决方案
文章目录 前言1. ubuntu安装XRDP2.局域网测试连接3.安装cpolar内网穿透4.cpolar公网地址测试访问5.固定域名公网地址 前言 XRDP是一种开源工具,它允许用户通过Windows RDP访问Linux远程桌面。 除了Windows RDP外,xrdp工具还接受来自其他RDP客户端(如Fre…...
如何学习运营管理
运营管理(Operations Management)是一门管理学科,它关注如何高效地组织和管理企业的生产、服务、供应链和业务过程以达到组织的目标。运营管理是企业管理的一个重要领域,它包含了多个内容和职能: 生产管理:…...
腾讯云centos7.6安装部署备忘
1.Mysql 1.1 安装mysql wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm rpm -ivh mysql-community-release-el7-5.noarch.rpm yum install mysql-community-server 1.1.1 安装后重启 service mysqld restart 1.1.2 初次安装mysql,root账…...
【赠书活动】考研备考书单推荐
👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…...
中缀表达式 - 栈实现综合计算器
代码: package Algotithm.stackobject Calculator {def main(args: Array[String]): Unit {val expression "32*6-2"//创建两个栈:数栈、符号栈val numStack, operStack new ArrayStack2(10)//定义需要的相关变量var index, num1, num2, …...
html语音播报功能问题
语音播报有个问题,就是弹出层有时无法关闭页面的播报,如果弹出层也有语音播报,就会造成语音混者播放 解决办法就是在弹出窗口(我用的弹出层框架是layui的)之前清空语音 window.operEdit function (url, title){window.speechSynthesis.can…...
计算机重点学科评级B-,山东省属重点高校考情分析
山东科技大学(B-) 考研难度(☆☆) 内容:23考情概况(拟录取和复试分析)、院校概况、23专业目录、23复试详情、各专业考情分析、各科目考情分析。 正文1175字预计阅读:3分钟 2023考情概况 山东科技大学计…...
轻松搭建本地知识库的ChatGLM2-6B
近期发现了一个项目,它的前身是ChatGLM,在我之前的博客中有关于ChatGLM的部署过程,本项目在前者基础上进行了优化,可以基于当前主流的LLM模型和庞大的知识库,实现本地部署自己的ChatGPT,并可结合自己的知识…...
flink的物理DataFlow图及Slot处理槽任务分配
背景 在flink中,有几个比较重要的概念,逻辑DataFlow图,物理DataFlow图以及处理槽执行任务,本文就来讲解下这几个概念 概念详解 假设有以下代码:数据源和统计单词算子的并行度是2,数据汇算子的并行度是1&…...
与面试相关的redis
这里写自定义目录标题 📝 redis的知识点数据结构及其特性,用途和操作方法持久化高可用分布式锁发布订阅性能优化安全性数据分片缓存策略键过期删除策略内存淘汰策略 🤗 总结归纳📎 参考文章 😀 这里写文章的前言&#…...
MapStruct从0到0.5
MapStruct从0到0.5 开发的过程,经常会用到实体类属性映射,同时为了方便,开发者也很少自己写专门的属性赋值工具类。索性会直接使用Sprrng提供的BeanUtils工具类,然后在性能上和字段属性赋值上的问题,一直是为开发者所…...
STM32H750 HAL CUBEMX 时钟失败及死机无法下载问题解决
芯片采样电压设置,否则 无法运行 解决死机问题 设置swd 模式 短接 boot0 —vcc 3.3v即可正常下载...
paddlespeech on centos7
概述 paddlespeech是百度飞桨平台的开源工具包,主要用于语音和音频的分析处理,其中包含多个可选模型,提供语音识别、语音合成、说话人验证、关键词识别、音频分类和语音翻译等功能。 paddlespeech整体是比较简单易用的,但是安装…...
ROM是什么? 刷ROM是什么意思?
文章目录 ROM是什么?刷ROM是什么意思 ROM是什么? ROM是只读内存(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除。通常用在不需经常变更资料的…...
OpenClaw多模型切换实战:百川2-13B量化版与Qwen3-32B对比测试
OpenClaw多模型切换实战:百川2-13B量化版与Qwen3-32B对比测试 1. 为什么需要多模型切换? 去年夏天,当我第一次尝试用OpenClaw自动化处理日常工作时,发现一个有趣的现象:80%的简单任务(如文件重命名、邮件…...
Flutter:从零到APK,手把手教你完成Android应用签名与打包
1. 环境准备与基础概念 在开始Flutter应用打包之前,我们需要确保开发环境已经正确配置。首先确认你的电脑上已经安装了以下工具: Flutter SDK(建议最新稳定版)Android Studio(包含Android SDK)Java JDK&…...
OpenClaw日志分析进阶:百川2-13B-4bits量化模型自动错误诊断
OpenClaw日志分析进阶:百川2-13B-4bits量化模型自动错误诊断 1. 为什么需要自动化日志分析 深夜两点,我的手机突然震动起来——服务器又报警了。强撑着睡意打开终端,面对满屏的报错日志,那种无力感相信每个运维人都深有体会。传…...
QT实战:qcustomplot中setData与addData性能对比与最佳实践(附代码示例)
QT实战:qcustomplot中setData与addData性能对比与最佳实践(附代码示例) 在数据可视化领域,QT的qcustomplot库因其轻量级和高度可定制性而广受欢迎。然而,当处理大规模数据集或实时数据流时,开发者常常会遇到…...
OpenClaw日志分析:QwQ-32B任务执行效率监控
OpenClaw日志分析:QwQ-32B任务执行效率监控 1. 为什么需要监控OpenClaw任务执行效率 去年冬天,我部署了一个自动整理会议纪要的OpenClaw工作流。起初运行得很顺利,直到某天早上发现它漏掉了三场重要会议的记录。检查日志才发现,…...
基于2026校招数据分析:拥有这几张AI证书的学生,起薪普遍高30%
2026年校招季已近尾声,随着DeepSeek等大模型技术的持续突破与“人工智能”向千行百业的深度渗透,AI人才市场的竞争呈现白热化态势。前程无忧51job发布的《2026届校招市场AI人才需求报告》显示,AI相关岗位校招薪酬中位数已突破2万元/月&#x…...
SDMatte边缘精修效果展示:发丝级分离、玻璃折射保留、薄纱纹理还原等高清案例图集
SDMatte边缘精修效果展示:发丝级分离、玻璃折射保留、薄纱纹理还原等高清案例图集 1. 惊艳效果预览 SDMatte作为专业级AI抠图工具,在处理复杂边缘和透明物体方面展现出惊人的能力。下面我们通过一组真实案例,展示它在不同场景下的表现。 1…...
3个步骤玩转虚拟手柄模拟:ViGEmBus驱动从入门到精通
3个步骤玩转虚拟手柄模拟:ViGEmBus驱动从入门到精通 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus Windows虚拟手柄驱动技术为游戏玩家和开发者…...
Rock3A开发板实战:OpenBMC移植全记录(附避坑指南)
Rock3A开发板OpenBMC移植实战:从硬件适配到性能调优 当RK3568处理器遇上OpenBMC,会碰撞出怎样的火花?作为瑞芯微旗下性能与功耗平衡的明星芯片,RK3568在边缘计算领域已证明其价值。而将其应用于BMC(基板管理控制器&…...
零基础入门:时空预测的系统化学习笔记
零基础入门:时空预测的系统化学习笔记 很多刚接触时序与时空预测领域的朋友,常常会陷入两个极端:要么一上来就硬啃复杂的 SOTA 模型,连基础算子都没搞懂就想复现顶会成果,最后处处碰壁;要么只停留在基础概…...
