arthas中文直译过来叫阿尔萨斯,是阿里巴巴开源的java应用诊断工具,在线排查问题,无需重启服务,实时监控jvm状态。支持JDK6以上版本,支持Linux/Mac/Window操作系统。

采用命令行交换方式,tab键命令自动补全,而且兼容linux系统部分命令,如:grep,ctrl+i清屏,ctrl+a跳到行首,ctrl+c终止命令等

如果你还在使用jdk原生jstat、jmap等命令排查问题,那么,强烈建议你使用arthas。本文介绍arthas的下载安装、启动、常用命令、退出、卸载以及常见问题的调试步骤

下载安装

arthas安装分为快速安装和全量安装,快速安装只下载arthas-boot.jar。全量安装是下载一个压缩包,压缩包中包含arthas-boot.jar、测试demo和封装好的启动脚本等文件,一般我们使用快速安装就可以了

快速安装

linux系统中安装可以用curl命令从阿里云官方网站下载

curl -O https://arthas.aliyun.com/arthas-boot.jar

windows系统中安装用浏览器打开如下地址会提示下载

https://arthas.aliyun.com/arthas-boot.jar

全量安装

linux全量安装需要先下载执行脚本

curl -L https://arthas.aliyun.com/install.sh | sh

下载完成后会在当前目录生成as.sh脚本,执行脚本 ./as.sh 后会自动下载全量安装包,默认保存在~/.arthas/lib目录下。修改as.sh脚本可以更改默认保存路径

windows全量安装只需要用浏览器打开下载地址就会提示下载

https://arthas.aliyun.com/download/latest_version?mirror=aliyun

全量安装包的文件夹名称为arthas,目录结构如下

启动

启动之前需要明确要监听哪个java程序,并找到这个java程序的进程id。当前登录用户必须对要监听的进程有可操作权限,否则会报错

linux中使用ps或jps命令可以找到java程序的进程id

ps -ef | grep java
jps -mlv

windows中打开任务管理器可以找到对应程序的进程id

执行命令启动arthas

java -jar arthas-boot.jar

启动后会提示选择监听哪个进程id,输入对应的序号即可。我要监听的进程id是19646,也就是序号2

输入2之后敲回车,启动成功如下图

启动时可以直接指定pid,就不用在启动过程中再输入序号了

java -jar arthas-boot.jar 19646

如果安装时选择了全量安装,那么也可以通过脚本启动,linux系统使用as.sh脚本,windows系统使用as.bat脚本

查看dashboard

dashboard命令可以查看cpu、线程状态,内存信息、GC情况和jdk版本等信息

图中字段解读

ID: Java中的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
NAME: 线程名称
GROUP: 线程组名称
PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
STATE: 线程的状态
CPU%: 线程消耗的cpu占比,采样间隔100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
TIME: 线程运行总时间,格式为 分:秒
INTERRUPTED: 线程当前的中断状态
DAEMON: 是否是守护线程

监控页面会实时刷新,默认每5000毫秒(5秒)刷新一次。可以通过 - i 参数指定刷新频率,-n 参数指定刷新次数。这个统计会有一定的开销,从截图中也可以看到arthas的cpu占比较大,所以刷新频率不要太高,建议5秒以上,刷新次数建议10次以内

// 每10秒刷新一次,3次后停止
dashboard -i 10000 -n 3

查看线程

使用thread命令可以查看线程的状态,显示的结果实际就是dashboard结果的第一栏

thread命令可以追加参数

id:可以查看指定线程id的堆栈信息
-n value:找出最忙的value个线程,并打印堆栈信息
-b:找出当前正在阻塞其他线程的线程
-i value:指定采样cpu占比的时间间隔,默认为100ms。

打印线程id=24的堆栈信息

打印当前最忙的3个线程的堆栈信息

打印正在阻塞其他线程的线程

指定统计线程cpu占比的时间间隔,单位:毫秒。因为统计cpu占比会有一定的资源消耗,所以时间间隔不要太小,建议100毫秒以上

thead -i 200

反编译

使用jad可以对代码进行反编译,反编译过来的代码可能会有语法错误,但不影响阅读。比较贴心的是,反编译过来的代码语法高亮,方便阅读

类名支持全路径,同时也支持模糊匹配,下面两个命令可以达到相同的效果

jad com.helianxiaowu.demo.ThreadBlock
jad *ThreadBlock

也可以对类中的某一个方法进行反编译,只需要在类名后面加上方法名即可

反编译过来的代码默认携带ClassLoader信息,使用 --source-only 选项可以去除ClassLoader信息

退出

使用quit或exit会退出arthas操作界面,但arthas进程还在,这时当你想监听别的java进程时会报错。因为arthas默认使用的是3658端口,所以这时会报错3658端口被别的进程占用。

使用shutdown或stop可以结束arthas,结束后可以监听别的进程id

出现端口被占用报错时,可以再次启动进入刚才监听的进程或者使用telnet进入刚才监听的arthas进程界面,执行shutdown或stop结束监听

telnet localhost 3658

卸载

linu系统中执行如下命令进行卸载

rm -rf ~/.arthas/
rm -rf ~/logs/arthas

window下需要进入C盘当前用户的目录,找到 .arthas目录和logs/arthas目录进行删除

CPU飙升的问题调试

java程序中,频繁GC、链接没有释放、线程数量过多导致频繁的进行切换、线程被阻塞、死循环等原因是造成cpu飙升的主要原因。

通过arthas的dashboard命令可以看到GC的回收次数和时间,现在大部分程序都是使用spring进行对象管理,不会出现创建大量实例对象的情况。数据库链接、IO、HTTP链接都使用的链接池,也很少出现链接没有释放的问题。所以,JVM频繁进行GC操作,很有可能是内存设置不合理,可以使用如下参数指定内存

JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m"

线程数量过多导致频繁进行线程切换,基本可以断定当前服务支撑不了现有的并发了,需要增加服务器资源或者增加负载

现在来模拟一个cpu飙升的问题排查过程

首先启动测试程序,模拟cpu升高的情况

然后启动arthas,选择测试程序对应的进程进行监控。输入dashboard命令,可以看到id=10的这个线程占用cpu过高

打印id=10的线程堆栈信息,可以看到这个线程正在执行high()方法

反编译high方法,查看源码,可以看到进行了死循环,所以cpu会飙升

方法响应速度慢的问题调试

一个接口调用,好长时间才能收到响应,接口逻辑复杂,排查起来特别困难,不知从何下手?下面带你一步步找到问题

找到调用耗时较长的接口,这里测试使用的是MethodDemo类中的slow()方法。

启动测试程序,调用slow方法,可以看到该方法耗时足足10秒,确实很慢

在arthas监控页面输入如下命令对这个方法进行耗时统计

trace *MethodDemo slow

在统计结果中,能看到每个方法的调用时长

反编译slow方法,发现代码进行了sleep操作,所以耗时较长

trace命令是统计方法的内部调用路径,并为每个调用路径统计耗时。trace命令需要指定类名和方法名,支持模糊匹配

线程阻塞的调试

线程阻塞会导致并发量上不去、cpu占用过高,降低系统整体性能,严重时会导致系统崩溃

启动测试程序,调用演示线程阻塞的方法

进入arthas监控页面,找到目前正在阻塞其他线程的线程,可以看到loop方法中正在锁定一个字符串,阻塞了其他线程

反编译loop方法,可以看到使用了synchronized进行了同步操作,阻塞了其他线程

由于篇幅有限,本文只讲一些arthas常用操作,后期会再出一篇高级操作,包括webconsole远程监控服务器、ognl表达式、封装docker镜像等

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:

长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

用它调试线上bug,真得劲!相关推荐

  1. 用它调试线上 bug,真得劲 | webconsole

    本文主要介绍用本地浏览器连接远程服务器进行bug调试的两种方法 webconsole webconsole 是 arthas 提供的 web 页面,它可以让用户在自己的电脑上,连接远程服务器的 art ...

  2. 线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!

    前言 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈. 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不? 今天陈某 ...

  3. springboot设置默认值_线上Bug无法复现?老司机教你一招,SpringBoot远程调试不用愁!...

    前言 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈. 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不? 今天陈某 ...

  4. 如何使用Fiddler调试线上JS代码(转自:http://www.cnblogs.com/RockLi/p/3511132.html)

    大家平时肯定都用过火狐的Firebug或者谷歌的调试工具来调试JS,但遗憾的是我们不能像编辑html,css那样来直接新增或者删除JS代码. 虽然可以通过调试工具的控制台来动态执行JS代码,但有时候却 ...

  5. 走完线上 BUG 定位最后一公里

    简介:因为线上线下环境隔离的问题,线上的输入很多时候难以在日常环境中构造,定位 bug 效率低下.是否有简单快捷的办法呢? 一个小故事 周末12点的闹钟在回龙观均价3000的出租屋急促的响起,程序员小 ...

  6. 使用MITM调试线上前端错误

    使用MITM调试线上前端错误 前言 目前所在的公司每次部署上线至少半小时,如果在上线刚完成,检查线上发现有bug时,这意味着你又要等一次部署,尤其是接近下班的时候出这事的话,整个人都不好了. 首先线上 ...

  7. 听说”双11”是这么解决线上bug的

    听说"双11"是这么解决线上bug的 --Android线上热修复的使用与原理 预备知识和开发环境 Android NDK编程 AndFix浅析 Android线上热修复的原理大同 ...

  8. 线上BUG 处理并分析原因

    昨天下午大神把组内几十号人召集在一起开Online bug分析大会,主要是针对近期线上事故从事故原因和解决方案两个维度来分析 对金融软件来说,每一次的线上事故都有可能给公司带来重大的损失,少扣了用户的 ...

  9. 测试金融软件出现线上bug的原因及解决方法

    小编热衷于收集整理资源,记录踩坑到爬坑的过程.希望能把自己所学,实际工作中使用的技术.学习方法.心得及踩过的一些坑,记录下来.也希望想做软件测试的你一样,通过我的分享可以少走一些弯路,可以形成一套自己 ...

最新文章

  1. void函数调用时显示不允许使用不完整的_C语言的角落——这些C语言不常用的特性你知道吗?...
  2. Matlab-基于短时神经网络的声音分类
  3. 【Centos 7】【Docker】 安装 redis
  4. 第十一章:配置和安全---IntelliMorph
  5. OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()
  6. oracle深度巡检指标,oracle DBA 巡检项目
  7. window打开IIS
  8. Mysql的key_len计算方法
  9. Scikit-learn:聚类clustering
  10. 小米路由插件二维码2020_打造5G时代的AIoT智能互联 小米路由AX3600评测
  11. 基于cnn的人脸识别_人脸识别技术:从传统方法到深度学习
  12. 硬件基础之继电器互锁工作原理
  13. 【新书速递】深入浅出Electron
  14. 004 数字调制ASK,OOK,FSK,PSK,QAM,CPFSK
  15. 故宫博物馆爬虫(简略版)
  16. 百度编辑器ueditor-在线图片管理,想修改下默认的排序管理
  17. Qt开发串口通信以及坐标显示程序并移植
  18. 关于u盘插入电脑在我的电脑中不显示盘符无法正常使用,但是在右下角图标有显示的问题。
  19. react-native打包release版本闪退
  20. 机器学习_深度学习毕设题目汇总——皮肤_癌症_糖尿病

热门文章

  1. 详解:操作符的优先级
  2. 关于NameError: name ‘train_test_split‘ is not defined错误提示
  3. 深度学习机器臂控制_深度学习新进展:可自建任务解决模型的机器人问世
  4. 许昌科技学校工业机器人_【调研】省人大常委会副主任徐济超到许昌科技学校进行专题调研...
  5. mysql 工程师必备命令_mysql入门命令语句
  6. 怎样用ug画铝型材_用UG画钻头,适合初学UG的小伙伴,快来学习吧!
  7. 革命性移动端开发框架-Flutter时间简史
  8. [Go]结构体及其方法
  9. 谈谈 Docker 网络
  10. Js获取宽高度的归纳总结