记一次多线程导致 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 来手动控制多线程队列流速,源头控制竞争队列大小.最后顺利解决

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

相关推荐
潲爺几秒前
《Java 8-21 高频特性实战(上):5 个场景解决 50% 开发问题(附可运行代码)》
java·开发语言·笔记·学习
资生算法程序员_畅想家_剑魔3 分钟前
算法-回溯-14
java·开发语言·算法
w_zero_one15 分钟前
Java的Vert.x框架结合Thymeleaf(TH)模板语言
java·开发语言·idea
咸鱼2.024 分钟前
【java入门到放弃】网络
java·开发语言·网络
Roye_ack27 分钟前
【微服务 Day2】SpringCloud实战开发(微服务拆分步骤 + Nacos注册中心 + OpenFeign + 微服务拆分作业)
java·spring cloud·微服务·nacos·openfeign
程序员爱钓鱼28 分钟前
用Python开发“跳一跳”小游戏——从零到可玩
后端·python·面试
wniuniu_28 分钟前
blob是啥
java·服务器·网络
程序员爱钓鱼28 分钟前
Python 源码打包成.whl文件的完整指南
后端·python·面试
IT_陈寒31 分钟前
Vite 3.0 实战:5个优化技巧让你的开发效率提升50%
前端·人工智能·后端
.生产的驴34 分钟前
DockerCompoe 部署注册中心Nacos 一键部署 单机+Mysql8
java·linux·运维·spring boot·缓存·docker·doc