8

Arthas 定位CPU跑满问题,源头竟是Apache Beanutils

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzU2MTY2MjE4OQ%3D%3D&%3Bmid=2247484049&%3Bidx=1&%3Bsn=4b92959bbef42e00c4688220eaf15327
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一、背景

大早上 线上k8s 机子 某个机子 cpu 飙高,导致k8s 健康检查失败,线上环境会自动执行jstack,上传到oss 通知到 钉钉告警群,直接分析锁、cpu 高的线程。

二、过程分析

2.1 排查cpu 占用最高的线程

使用 jstack 分析:

发现占用CPU最高的线程栈是: org.apache.commons.beanutils.MethodUtils#getMatchingAccessibleMethod

当然也可以使用arthas 的 thread -n 10 命令 ,由于自动监控抓取的,省去了这一步了。

一般的常规操作 jstack+top ,参考:

https://blog.csdn.net/guixunlong/article/details/8450897

jstack 、top 文件也可以使用这个网站来分析

https://fastthread.io/ft-index.jsp

I3INFvB.png!mobile

2.2 定位问题线程MethodUtils工具类

在线程栈里发现 org.apache.commons.beanutils.MethodUtils#getMatchingAccessibleMethod 异常代码行数和本地 比较对应不上!

IZR3myE.png!mobile

2.3 sc -d 查看当前类来自哪个jar包

使用Arthas sc 命令搜索发现有两个不同版本jar包,真香 。k8s服务器重启了也可以用 sc 命令非常方便地定位jar冲突问题。 Ff6fi2n.png!mobile

2.4 多线程并发问题

org.apache.commons.beanutils.MethodUtils 实际来自 apache-beanutils 依赖:

<dependency> 
<groupId>apache-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>

那么应用里两个不同版本的 apache-beanutils 到底哪里冲突了呢?

1.7 版本

static WeakHashMap cache =  new  WeakHashMap();

1.9 版本

static Map<MethodDescriptor, Reference<Method>> cache = Collections
._synchronizedMap_( new WeakHashMap<MethodDescriptor, Reference<Method>>());

那么为什么 1.7 版本里的代码有问题呢?

线程在WeakHashMap的get方法里面出不来了,一直在while循环里面。 多线程并发get和put,然后get方法内的while循环一直找不到eq的对象,循环出不来。

参考:

https://blog.csdn.net/weixin_33693070/article/details/85952993 https://www.cnblogs.com/love-jishu/p/4244302.html

解决办法:排除掉低版本的 apache-beanutils 依赖。

招聘

我们正在寻找小伙伴,欢迎加入。

实习生: 阿里云-云原生团队-2022 届春季实习⽣招聘 社招:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK