带着8个问题5分钟教你学会Arthas诊断工具
Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:这个类从哪个jar包加载的?为什么会报各种类相关的Exception?我改的代码为什么没有执行到?难道是我没commit?分支搞错了?遇到问题无法在线上debug,难道只能通过加日志再重新发布吗?线上遇到某个用户的数据处理有问题,但线上同样无法debug,线下无法重现!是否有一个全局视角来查看系统的运行状况?有什么办法可以监控到JVM的实时运行状态?怎么快速定位应用的热点,生成火焰图?怎样直接从JVM内查找某个类的实例?
这8个问题,Arthas官方文档(https:arthas。aliyun。comdoc)中并没有给出答案或标准的解决方案。
坑爹啊
这不是管杀不管埋吗!!准备先给出我的测试代码packagecom。admin。study;importcom。alibaba。fastjson。JSON;importlombok。AccessLevel;importlombok。Getter;importlombok。Setter;importlombok。ToString;importlombok。experimental。FieldDefaults;importjava。util。List;importjava。util。concurrent。TimeUnit;publicclassArthasDemo{publicstaticvoidmain(String〔〕args){Strings〔{name:zhangsan,age:10,telephone:123456,interests:〔sing,dance,rap〕},{name:lisi,age:20,telephone:123457,interests:〔sing,swim〕},{name:wangwu,age:30,telephone:123458,interests:〔sing,program〕}〕;模拟一遍遍的调用方法的过程for(;;){System。out。println(newArthasDemo()。convert(s));try{TimeUnit。SECONDS。sleep(10);}catch(InterruptedExceptione){e。printStackTrace();}}}privateListPeopleconvert(Strings){returnJSON。parseArray(s,People。class);}GetterSetterToStringFieldDefaults(levelAccessLevel。PRIVATE)privatestaticclassPeople{姓名Stringname;年龄Stringage;电话Stringtelephone;兴趣列表ListStringinterests;}}以下是控制台正常打印的结果LibraryJavaJavaVirtualMachinesjdk1。8。0192。jdkContentsHomebinjava。。。〔ArthasDemo。People(namezhangsan,age10,telephone123456,interests〔sing,dance,rap〕),ArthasDemo。People(namelisi,age20,telephone123457,interests〔sing,swim〕),ArthasDemo。People(namewangwu,age30,telephone123458,interests〔sing,program〕)〕〔ArthasDemo。People(namezhangsan,age10,telephone123456,interests〔sing,dance,rap〕),ArthasDemo。People(namelisi,age20,telephone123457,interests〔sing,swim〕),ArthasDemo。People(namewangwu,age30,telephone123458,interests〔sing,program〕)〕下载并运行Arthas
按照下图中的步骤,选择一个Java进程进行attach。
下载并运行Arthas访问WebConsole
attach成功后可以打开谷歌浏览器输入http:127。0。0。1:3658打开WebConsole
(吐槽一句MacOS的Safari浏览器不支持)使用WebConsole最方便的是你可以打开多个标签页同时操作
问题1:这个类从哪个jar包加载的?为什么会报各种类相关的Exception?
这个问题我经常在处理各种依赖冲突的时候遇到,有一些类的完全名称是一模一样,通过常规的办法无法解决类具体从哪个jar包加载。
别急,看我下面的解决办法。sc
通过sc命令模糊查看当前JVM中是否加载了包含关键字的类,以及获取其完全名称。注意使用scd命令,获取classLoaderHash,这个值在后面需要用到。
scdArthasDemo
scd命令classloader
通过classloader查看class文件来自哪个jar包使用cls命令可以清空命令行,这个简单的命令官方文档居然找不到
注意classloaderc后面的值填上面第一步中获取到的Hash值,class文件路径使用分割,且必须以。class结尾。
〔arthas3633〕classloaderc18b4aac2rcomadminstudyArthasDemo。classfile:UsersadmincodeconcurrentbooktargetclassescomshockangstudyArthasDemo。classAffect(rowcnt:1)costin0ms。
上面是显示class文件路径的,如果class文件来自jar包,可以显示jar包路径,例如官方文档给的例子:classloaderc1b6d3586rjavalangString。classjar:file:LibraryJavaJavaVirtualMachinesjdk1。8。060。jdkContentsHomejrelibrt。jar!javalangString。class问题2:我改的代码为什么没有执行到?难道是我没commit?分支搞错了?
推荐使用watch和tt命令,非常好用。
这两个命令都是用来查看方法调用过程的,不同的是watch命令是调用一次打印一次方法的调用情况,而tt命令可以先生成一个不断增加的调用列表,然后指定其中某一项进行观测。使用watch命令查看方法调用情况。我们要查看ArthasDemo这个类里面的convert方法调用情况。
watch命令watchcom。shockang。study。ArthasDemoconvert{params,target,returnObj}fx4
watch后面跟上完全类名和方法名,以及一个OGNL的表达式,f表示不论正常返回还是异常返回都进行观察,x表示输出结果的属性遍历深度,默认为1,建议无脑写4就行,这是笔者经验来看最大的遍历深度,再大就不支持了
使用tt命令来观测方法调用情况,tt命令可以查看多次调用并选择其中一个进行观测,但是如果输出结果是多层嵌套就没办法看了,而watch可以查看多层嵌套的结果。使用ttt记录下当前方法的每次调用环境现场
ttt命令tttcom。shockang。study。ArthasDemoconvert
TIMESTAMP表示方法调用发生的时间,COST表示调用耗时(ms),ISRET表示是否正常返回,ISEXP表示是否异常返回,OBJECT表示对象的HASH值对于具体一个时间片的信息而言,你可以通过i参数后边跟着对应的INDEX编号查看到他的详细信息
tti命令图中之所以可以打印兴趣列表,是调用了其toString方法,如果没有重写java。lang。Object类的toString方法,只会看到hash值。
如何判断代码是否已经提交?
通过jadsourceonly可以查看源代码。〔arthas3633〕jadsourceonlycom。admin。study。ArthasDemoDecompiledwithCFR。packagecom。admin。study;importcom。alibaba。fastjson。JSON;importjava。util。List;importjava。util。concurrent。TimeUnit;publicclassArthasDemo{publicstaticvoidmain(String〔〕args){15Strings〔{name:zhangsan,age:10,telephone:123456,interests:〔sing,dance,rap〕},{name:lisi,age:20,telephone:123457,interests:〔sing,swim〕},{name:wangwu,age:30,telephone:123458,interests:〔sing,program〕}〕;while(true){20System。out。println(newArthasDemo()。convert(s));try{22TimeUnit。SECONDS。sleep(10L);25continue;}catch(InterruptedExceptione){24e。printStackTrace();continue;}break;}}privateListPeopleconvert(Strings){30returnJSON。parseArray(s,People。class);}privatestaticclassPeople{privateStringname;privateStringage;privateStringtelephone;privateListStringinterests;privatePeople(){}publicStringtoString(){returnArthasDemo。People(namethis。getName(),agethis。getAge(),telephonethis。getTelephone(),intereststhis。getInterests());}publicStringgetName(){returnthis。name;}publicvoidsetName(Stringname){this。namename;}publicStringgetAge(){returnthis。age;}publicStringgetTelephone(){returnthis。telephone;}publicListStringgetInterests(){returnthis。interests;}publicvoidsetAge(Stringage){this。ageage;}publicvoidsetTelephone(Stringtelephone){this。telephonetelephone;}publicvoidsetInterests(ListStringinterests){this。interestsinterests;}}}〔arthas3633〕问题3:遇到问题无法在线上debug,难道只能通过加日志再重新发布吗?
通过上面问题2的watch和tt命令可以查看方法调用情况。
此外,可以通过redefine命令热替换线上的代码,注意应用重启之后会失效,这在某些紧急情况下会有奇效。
比如说我们修改一下方法体里面的代码,加了一行日志打印:privateListPeopleconvert(Strings){System。out。println(s);returnJSON。parseArray(s,People。class);}
这时我们就可以将新代码编译后的class文件热替换正在运行的ArthasDemo的代码。
redefine命令
热替换JVM内存中(方法区)加载的类
从这张图可以明显的看出,明明源码中没有打印字符串s的逻辑,但是控制台还是打印了字符串,因为我们已经热替换了JVM内存中(方法区)加载的类。问题4:线上遇到某个用户的数据处理有问题,但线上同样无法debug,线下无法重现!
这个问题没有完美的解决办法
参考一下问题2和问题3的解决方案
推荐使用tt命令并将命令行返回结果输出到一个文件中,后续可以选择异常的一行记录使用tti命令进行深入的分析。
tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
tee命令tttcom。admin。study。ArthasDemoconvertteeUsersadminDownloadslog
此外还可以使用monitor命令统计方法调用成功失败情况。
monitor命令monitorc30com。admin。study。ArthasDemoconvertteeUsersadminDownloadslog1c后面接统计周期,默认值为120秒
问题5:是否有一个全局视角来查看系统的运行状况?
使用dashboard命令可以查看当前系统的实时数据面板,当运行在Alitomcat时,会显示当前tomcat的实时信息,如HTTP请求的qps,rt,错误数,线程池信息等等。
dashboard实时数据面板
从图中可以看到线程情况,内存使用情况,系统参数等。问题6:有什么办法可以监控到JVM的实时运行状态?
使用jvm命令可以查看JVM的实时运行状态。
JVM的实时运行状态问题7:怎么快速定位应用的热点,生成火焰图?
profiler命令支持生成应用热点的火焰图。本质上是通过不断的采样,然后把收集到的采样结果生成火焰图。默认情况下,生成的是cpu的火焰图,即event是cpu,可以用event参数来指定。注意不同系统支持的event不同
默认情况下,arthas使用3658端口,则可以打开:http:localhost:3658arthasoutput查看到arthasoutput目录下面的profiler结果:
profiler目录
选择一项点击
profiler结果图问题8:怎样直接从JVM内查找某个类的实例?
使用vmtool可以达成目的这个功能是Arthas3。5。1新增的。可以参考官方文档https:arthas。aliyun。comdocvmtool。htmlid1
vmtoolactiongetInstancesclassNamejava。lang。Stringlimit10String〔〕〔String〔comtaobaoarthascoreshellsessionSession〕,String〔com。taobao。arthas。core。shell。session。Session〕,String〔comtaobaoarthascoreshellsessionSession〕,String〔comtaobaoarthascoreshellsessionSession〕,String〔comtaobaoarthascoreshellsessionSession。class〕,String〔comtaobaoarthascoreshellsessionSession。class〕,String〔comtaobaoarthascoreshellsessionSession。class〕,String〔com〕,String〔javautilconcurrentConcurrentHashMapValueIterator〕,String〔javautilconcurrentlocksLockSupport〕,〕
通过limit参数,可以限制返回值数量,避免获取超大数据时对JVM造成压力。默认值是10。
如果想精确的定位到具体的类实例,可以通过指定classloadername或者classloaderhash,如下所示:vmtoolactiongetInstancesclassLoaderClassorg。springframework。boot。loader。LaunchedURLClassLoaderclassNameorg。springframework。context。ApplicationContextvmtoolactiongetInstancesc19469ea2classNameorg。springframework。context。ApplicationContext获取classloaderhash的方法请参考上面的问题1
vmtool还有个不错的功能,可以强制进行GC,这在某些生产环境内存紧张的情况下有奇效。vmtoolactionforceGc
深圳警方通报闲鱼上发死亡威胁事件涉事男子被拘10日IT之家7月10日消息据红星新闻9日报道,山东一位网友发文称其在闲鱼上卖混血童模衣物遭死亡威胁。报道称,山东济南市民张倩在闲鱼上卖女儿的旧衣服,她的闲鱼账号长期收到一些非……
委托办理入驻电商未果,商户起诉获2万退款据海淀法院网消息,尚京公司称,其花4万元委托思亿公司办理电商入驻服务,因未与电商签订销售合同,帐号为空号致入驻未果,遂将思亿公司诉至法院,要求解除委托合同并要求退还服务费4万元……
海尔回应代工小米冰箱虚假报道,从未给该品牌代工IT之家10月10日消息针对有媒体报道海尔冰箱为小米代工一事,今日下午,海尔冰箱官方发表声明称,海尔冰箱从未给小米代工,此为虚假报道,海尔保留依法追究相关媒体和企业法律责任的权……
程序员锁死服务器导致公司倒闭,真锁库跑路案今日开庭审理凤凰网科技讯11月1日消息,据微博网友爆料,此前程序员锁死服务器致创业游戏公司倒闭一案今日开庭审理,公司创始人螃了个蟹提交了对方莫名失联,跑路的证据。据悉,2017年,深……
碳的几种单质说课稿范文作为一无名无私奉献的教育工作者,时常会需要准备好说课稿,是说课取得成功的前提。快来参考说课稿是怎么写的吧!以下是小编收集整理的碳的几种单质说课稿范文,仅供参考,欢迎大家阅读。……
金山云双11大促1核2G基础款冰点抢购一年只需81元进入第四季度,云服务器促销活动不断。日前,金山云11月份上线了双11特惠,金山云推出特价基础型云服务器,配置为1核2G,价格是81元年,折合约6。75月。活动地址:htt……
最后2天!百度云虚拟主机BCH双11特价11元6个月双11期间,百度云开始了一轮大促,适合于个人兴趣建站的云虚拟主机BCH,最低仅11元6个月。目前大促还剩两天时间,想要入手云服务器的用户可以关注下。抢购地址:https:……
11元6个月,百度云虚拟主机BCH双11特价双11临近,各家云服务厂商纷纷推出了相应的优惠。百度云也开始了一轮双11大促,双11大促期间,适合于个人兴趣建站的云虚拟主机BCH,最低仅11元6个月。抢购地址:http……
11元6个月,百度云云虚拟主机BCH双11特价双11临近,各家云服务厂商纷纷推出了相应的优惠。百度云也开始了一轮双11大促,双11大促期间,适合于个人兴趣建站的云虚拟主机BCH,最低仅11元6个月。抢购地址:http……
圆的公切线教案范文教学目标:(1)理解两圆相切长等有关概念,掌握两圆外公切线长的求法;(2)培养学生的归纳、总结能力;(3)通过两圆外公切线长的求法向学生渗透转化思想。教……
腾讯云双11活动1核2G云服务器88元1年随着双十一活动的临近,云服务器厂商也开始了一年一度最大力度的促销。日前,腾讯云便放出了本年度双11的预热活动1核2G、50G硬盘的标准型S2爆款云服务器,双11活动价88元1年……
腾讯云双11提前购1核2G配置云服务器,88元1年马上双11即将开启。云服务器厂商也开始了一年一度的最大力度促销。今天,腾讯云就放出了本年度双11活动的预热爆款云服务器1核2G、50G硬盘的标准型S2服务器,双11活动价……