记一次多线程导致 CPU 飚高以及排查过程

一.cpu突然飚高

收到系统频发的cpu超过90%的告警.虽然是在非线上环境出现.接到告警后第一反应还是去重启了机器,重启后cpu如期的下降了下来.以为能高枕无忧,不过一会儿还是收到了告警.

二.排查

2.1 top 指令查看物理机进程id

申请了堡垒机权限登上机器 top指令后.如下确实发现进程为623的机器cpu一直在高位,但内存不是很高. 从Command 列发现,确实是该java进程 623.顺带需要注意下User列用户为admin用户启动的该进程,那么在后续对该进程的一些操作尽量是切到admin用户上来操作,防止出现权限不足.su命令.

2.2 查看进程下各线程情况 top-H -p 623

通过这个命令可以查看到该进程下所有线程的具体执行情况,执行后发现并没有非常突出的占用cpu高的线程存在.这就很诡异了,我们并没有很高cpu占用的线程在执行.反而出现了cpu飚高.很纳闷,继续往下再看看这些线程到底在做什么事情.

2.3 指定其中一个线程查看具体的执行情况

2.3.1 先将指定的线程转换为16进制,而后使用jstack查看具体的线程执行情况,如下为例

perl 复制代码
printf "%x\n" tid 
jstack pId | grep -A 行数

通过具体的jstack命令,可以看到具体的代码行执行的堆栈调用情况.发现很多线程都是如上的情况,其中为binlog同步消费的查询数据库的操作.回想到最近的需求.我们做了一个多商品多门店下发到店品的操作.这个操作在1000*1000的场景下就回出现100w的数据写入.写入后触发binlog,binlog再从mq进行消费同步写入到es.所以才会出现在重启之后短暂的cpu下降,后续启动过后mq再次消费重新触发导致上述线程不断的进行数据库IO以及彼此之间竞争cpu导致cpu飚高.

三.解决

由于上述的问题本质上还是由于产品需求导致,而在开发过程中.我们又使用了多线程.多线程在队列等待时也会去竞争cpu资源,这一层已经出现了很多cpu压力,后续的binlogmq消费进一步的数据库io和线程切换导致了cpu雪崩.所以优先的方案还是限制了多线程等待队列的数量,从源头优先控制竞争队列大小.

java 复制代码
private AtomicLong THREAD_NUM = new AtomicLong(0);

通过AutomicLong 来手动控制多线程队列流速,源头控制竞争队列大小.最后顺利解决

赠人玫瑰 手有余香 我是柏修 一名持续更新的晚熟程序员 期待您的点赞,关注加收藏,加个关注不迷路,感谢 您的鼓励是我更新的最大动力 ↓↓↓↓↓↓

相关推荐
一只大袋鼠27 分钟前
Git 进阶(二):分支管理、暂存栈、远程仓库与多人协作
java·开发语言·git
德思特1 小时前
从 Dify 配置页理解 RAG 的重要参数
java·人工智能·llm·dify·rag
YOU OU2 小时前
Spring IoC&DI
java·数据库·spring
один but you2 小时前
从可变参数到 emplace:现代 C++ 性能优化的核心组合
java·开发语言
IT_陈寒2 小时前
Redis缓存击穿把我整不会了,原来还有这手操作
前端·人工智能·后端
是码龙不是码农2 小时前
ThreadPoolExecutor 7 个核心参数详解
java·线程池·threadpool
kyriewen3 小时前
面试官让我查各部门工资最高的员工,我用AI三秒写出窗口函数,他愣了
后端·mysql·面试
这是程序猿3 小时前
Spring Boot自动配置详解
java·大数据·前端
文心快码BaiduComate3 小时前
干货|Comate Harness Engineering工程实践指南
前端·后端·程序员
光辉GuangHui3 小时前
Agent Skill 也需要测试:如何搭建 Skill 评估框架
前端·后端·llm