作者 | 李昊(能够养肥)
【Arthas 官网社区正在举办征文活动,加入即有奖品拿~ 点击投稿】
生产环境 CPU 告警:
13:40 收到咱们的生产环境服务器绿版 CUP 超负载告警告诉。
此时心里只有一个想法,重启大法好,马上登录服务器,执行 top 发现过程 30247 和 28337 占用 CPU 为 200 多和 100 多根本占用了 4 核的 3 核,整个过程大略用时 30 秒,保护群仍然很平静,经营的电话也没打过去,这时候我判定,这次问题应该影响面很小,用户可能也临时没有发现,好吧,还有工夫做排查。
Arthas 排查过程:
- 开启 Arthas 工具找到对应的 30247 运单模块和 28337 领取模块,抉择运单模块进入:
java -jar arthas-boot.jar
- 执行 dashboard 命令,线程 35 和 12042 不失常 CUP 占用 49%:
dashboard
- 执行 thread 35 thread 12042 定位代码行:
thread 35
thread 12042
- 查看代码,业务需要为生成一个至多蕴含 2 个数字的随机字符串,咱们应用的对立的工具类办法,该办法中先通过
UUID.randomUUID()
随机出一个 10 位的字符池,而后再从这个字符池中随机须要位数的字符串,如果随机进去的 10 位字符池中都是字母,则二次随机时候就会呈现死循环,问题代码如下:
public static String getRandomStr(boolean numberFlag, int length) {
String retStr = "";
String strTable =
numberFlag
? UUID.randomUUID().toString().replaceAll("-", "").substring(0, 10)
: "1234567890abcdefghijkmnpqrstuvwxyz";
int len = strTable.length();
boolean bDone = true;
do {
retStr = "";
int count = 0;
for (int i = 0; i < length; i++) {double dblR = Math.random() * len;
int intR = (int) Math.floor(dblR);
char c = strTable.charAt(intR);
if (('0' <= c) && (c <= '9')) {count++;}
retStr += strTable.charAt(intR);
}
if (count >= 2) {bDone = false;}
} while (bDone);
return retStr;
}
- 线下模仿不到二万次
UUID.randomUUID()
前十位会呈现一次全字母的状况。
- 最终起因是死循环导致的 CPU 飚高,修复代码,减少是否都是字母的判断,第一次随机进去的 10 位字符池都是字母,则从新随机。
Arthas 常用命令:
装置
curl -O arthas.aliyun.com/arthas-boot…
java -jar arthas-boot.jar
根底命令
help——查看命令帮忙信息
cat——打印文件内容,和 linux 里的 cat 命令相似
echo–打印参数,和 linux 里的 echo 命令相似
grep——匹配查找,和 linux 里的 grep 命令相似
tee——复制规范输出到规范输入和指定的文件,和 linux 里的 tee 命令相似
pwd——返回以后的工作目录,和 linux 命令相似
cls——清空以后屏幕区域
session——查看以后会话的信息
reset——重置加强类,将被 Arthas 加强过的类全副还原,Arthas 服务端敞开时会重置所有加强过的类
version——输入以后指标 Java 过程所加载的 Arthas 版本号
history——打印命令历史
quit——退出以后 Arthas 客户端,其余 Arthas 客户端不受影响
stop——敞开 Arthas 服务端,所有 Arthas 客户端全副退出
keymap——Arthas 快捷键列表及自定义快捷键
jvm 相干
dashboard——以后零碎的实时数据面板
thread——查看以后 JVM 的线程堆栈信息
jvm——查看以后 JVM 的信息
sysprop——查看和批改 JVM 的零碎属性
sysenv——查看 JVM 的环境变量
vmoption——查看和批改 JVM 里诊断相干的 option
perfcounter——查看以后 JVM 的 Perf Counter 信息
logger——查看和批改 logger
getstatic——查看类的动态属性
ognl——执行 ognl 表达式
mbean——查看 Mbean 的信息
heapdump——dump java heap, 相似 jmap 命令的 heap dump 性能
class/classloader 相干
sc——查看 JVM 已加载的类信息
sm——查看已加载类的办法信息
jad——反编译指定已加载类的源码
mc——内存编译器,内存编译 .java 文件为 .class 文件
redefine——加载内部的 .class 文件,redefine 到 JVM 里
dump——dump 已加载类的 byte code 到特定目录
classloader——查看 classloader 的继承树,urls,类加载信息,应用 classloader 去 getResource
monitor/watch/trace 相干
- monitor 办法执行监控
monitor -c 5 demo.MathGame primeFactors
-c 5 未统计周期默认 120s
- watch 能察看到的范畴为:返回值、抛出异样、入参
watch demo.MathGame primeFactors“{params,target,returnObj}”-x 2 -b -s -n 2
-x 2 输入后果的属性遍历深度
-b 办法调用前
-s 办法返回后
-n 2 执行 2 次
watch demo.MathGame primeFactors“{params[0],throwExp}”-e -x 2
- e 示意抛出异样时才触发
- trace 办法外部调用门路,并输入办法门路上的每个节点上耗时
trace demo.MathGame run