Arthas,7000字入门篇
Arthas(阿尔萨斯)能为你做什么?
Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。
当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:这个类从哪个jar包加载的?为什么会报各种类相关的Exception?我改的代码为什么没有执行到?难道是我没commit?分支搞错了?遇到问题无法在线上debug,难道只能通过加日志再重新发布吗?线上遇到某个用户的数据处理有问题,但线上同样无法debug,线下无法重现!是否有一个全局视角来查看系统的运行状况?有什么办法可以监控到JVM的实时运行状态?怎么快速定位应用的热点,生成火焰图?怎样直接从JVM内查找某个类的实例?运行环境要求
Arthas支持JDK6,支持LinuxMacWindows,采用命令行交互模式,同时提供丰富的Tab自动补全功能,进一步方便进行问题的定位和诊断。快速安装
推荐使用arthasboot,下载arthasboot。jar,然后用javajar的方式启动:curlOhttps:alibaba。github。ioarthasarthasboot。jarjavajararthasboot。jar
注:在运行第2条命令之前,先运行一个java进程在内存中,不然会出现找不到java进程的错误。
打印帮助信息javajararthasboot。jarh
如果下载速度比较慢,可以使用aliyun的镜像:javajararthasboot。jarrepomirroraliyunusehttpWindows下安装
1、在D:下创建Arthas目录,在windows命令窗口下,使用curl命令下载阿里服务器上的jar包,大小138k。
2、使用java启动arthasboot。jar,来安装arthas,大小约10M。运行此命令会发现java进程,输入1按回车。则自动从远程主机上下载Arthas到本地目录。
注意:启动Arthas的时候一定要先启动一个Java进程。
3、查看按照好的目录C:UsersHUAWEI。arthaslib3。5。4arthas
小结下载arthasboot。jar包执行arthasboo。jar包,前提是必须要有java进程在运行。第一次执行这个jar包,会自动从服务器上下载arthas,大小是11M从Maven仓库下载全量包
如果下载速度比较慢,可以尝试用阿里云的镜像仓库步骤
1。比如要下载3。5。4版本,下载的url是:https:archivamavenstorageprod。osscnbeijing。aliyuncs。comrepositoryjcentercomtaobaoarthasarthaspackaging3。5。4arthaspackaging3。5。4bin。zip3B?Expires1637823771OSSAccessKeyIdLTAIfU51SusnnfCCSignatureCAlIjIvMl4kh09oMtff2FBgxyG2U3D
2。解压后,在文件夹里有arthasboot。jar,直接用javajar的方式启动:javajararthasboot。jar
注:如果是Linux,可以使用以下命令解压到指定的arthas目录unzipdrootapparthasarthaspackaging3。5。4bin。zip
小结在Linux下在线安装的方式与在Windows下的安装相同如果要使用离线的安装方式,先下载完成的zip到本地,再解压到任意的目录即可卸载在Linux平台
删除下面文件:rmrf。arthasrmrflogsarthasWindows平台
直接删除userhome下面的。arthas和logsarthas目录快速入门:attach一个进程目标:通过案例快速入门执行一个jar包通过arthas来attach粘附步骤1。下载以及Demo
命令下载已经打包好的arthasdemo。jarcurlOhttps:alibaba。github。ioarthasarthasdemo。jar在命令行下执行javajararthasdemo。jar
2。启动arthas
注意:在Windows中启动arthas捕获进程的时候可能会出现如下的报错〔ERROR〕Thetelnetport3658isusedbyprocess10472insteadoftargetprocess284,youwillconnecttoanunexpectedprocess。〔ERROR〕1。Trytorestartarthasboot,selectprocess10472,shutdownitfirstwithrunningthestopcommand。〔ERROR〕2。Ortrytostoptheexistingarthasinstance:javajararthasclient。jar127。0。0。13658cstop〔ERROR〕3。Ortrytousedifferenttelnetport,forexample:javajararthasboot。jartelnetport9998httpport1
直接将启动命令换成javajararthasboot。jartelnetport9998httpport1
3。通过浏览器连接arthas
Arthas目前支持WebConsole,用户在attach成功之后,可以直接访问:http:127。0。0。1:3658。
可以填入IP,远程连接其它机器上的arthas。
默认情况下,arthas只listen127。0。0。1,所以如果想从远程连接,则可以使用targetip参数指定listen的IP4。查看arthasdemo。jar的代码
以下是一个简单的Java程序,每隔一秒生成一个随机数,再执行质因数分解,并打印出分解结果。代码的内容不用理会这不是现在关注的点。packagedemo;importjava。util。ArrayList;importjava。util。List;importjava。util。Random;importjava。util。concurrent。TimeUnit;publicclassMathGame{privatestaticRandomrandomnewRandom();用于统计生成的不合法变量的个数publicintillegalArgumentCount0;publicstaticvoidmain(String〔〕args)throwsInterruptedException{MathGamegamenewMathGame();死循环,每过1秒调用1次下面的方法(不是开启一个线程)while(true){game。run();TimeUnit。SECONDS。sleep(1);}}分解质因数publicvoidrun()throwsInterruptedException{try{随机生成一个整数,有可能正,有可能负intnumberrandom。nextInt()10000;调用方法进行质因数分解ListIntegerprimeFactorsprimeFactors(number);打印结果print(number,primeFactors);}catch(Exceptione){System。out。println(String。format(illegalArgumentCount:3d,,illegalArgumentCount)e。getMessage());}}打印质因数分解的结果publicstaticvoidprint(intnumber,ListIntegerprimeFactors){StringBuffersbnewStringBuffer(number);for(intfactor:primeFactors){sb。append(factor)。append();}if(sb。charAt(sb。length()1)){sb。deleteCharAt(sb。length()1);}System。out。println(sb);}计算number的质因数分解publicListIntegerprimeFactors(intnumber){如果小于2,则抛出异常,并且计数加1if(number2){illegalArgumentCount;thrownewIllegalArgumentException(numberis:number,need2);}用于保存每个质数ListIntegerresultnewArrayListInteger();分解过程,从2开始看能不能整除inti2;while(inumber){如果i大于number就退出循环能整除,则i为一个因数,number为整除的结果再继续从2开始除if(numberi0){result。add(i);numbernumberi;i2;}else{i;否则i}}returnresult;}}小结启动被诊断进程启动arthasboot。jar,粘贴上面的进程不但可以通过命令行的方式来操作arthas也可以通过浏览器来访问arthas快速入门:常用命令接触目标dashboard仪表板通过thread命令来获取到arthasdemo进程的MainClass通过jad来反编译MainClasswatch命令介绍1。dashboard仪表板
输入dashboard(仪表板),按回车enter,会展示当前进程的信息,按ctrlc可以中断执行。
注:输入前面部分字母,按tab可以自动补全命令第一部分是显示JVM中运行的所有线程:所在线程组,优先级,线程的状态,CPU的占用率,是否是后台进程等第二部分显示的JVM内存的使用情况第三部分是操作系统的一些信息和Java版本号
2。通过thread命令来获取到arthasdemo进程的MainClass
获取到arthasdemo进程的MainClass
thread14会打印线程ID14的栈。如果是thread1会打印线程ID1的栈,通常是main函数的线程。
thread1示例图
3。通过jad来反编译MainClassjaddemo。MathGame
4。watch监视
通过watch命令来查看demo。MathGameprimeFactors函数的返回值:watchdemo。MathGameprimeFactorsreturnObj
按Q或者CtrlC退出5。退出arthas
如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上。
如果想完全退出arthas,可以执行stop命令。小结如何启动arthas?javajararthasboot。jar说说以下命令的作用
命令
功能
dashboard
显示JVM中内存的情况,JVM中环境信息
thread
显示当前进程所有线程信息
quit,exit,stop
退出或停止arthas
watch
监视某个方法的执行情况,监视了返回值
jad
反编译指定的类或方法基础命令之一目标helpcatgreppwdclshelp作用
查看命令帮助信息,help命令会打印出所有可以用的命令效果
cat
作用
打印文件内容,和linux里的cat命令类似;如果没有写路径,则显示当前目录下的文件。效果
grep作用
匹配查找,和linux里的grep命令类似,但它只能用于管道命令语法
参数列表
作用
n
显示行号
i
忽略大小写查找
e正则表达式
使用正则表达式查找
m行数
最大显示行数,要与查询字符串一起使用
举例只显示包含java字符串的行系统属性syspropgrepjava
显示包含java字符串的行和行号的系统属性syspropgrepjavan
显示包含system字符串的10行信息threadgrepsystemm10
使用正则表达式,显示包含2个o字符的线程信息,threadgrepeo
pwd作用
返回当前的工作目录,和linux命令类似
pwd:PrintWorkDirectory打印当前工作目录效果
cls作用
清空当前屏幕区域基础命令之二目标sessionresetversionquitstopkeymapsession作用
查看当前会话的信息效果
reset作用
重置增强类,将被Arthas增强过的类全部还原,Arthas服务端关闭时会重置所有增强过的类语法还原指定类resetTest还原所有以List结尾的类resetList还原所有的类reset效果
version作用
输出当前目标Java进程所加载的Arthas版本号效果
history作用
打印命令历史效果
quit作用
退出当前Arthas客户端,其他Arthas客户端不受影响stop作用
关闭Arthas服务端,所有Arthas客户端全部退出效果
keymap作用
Arthas快捷键列表及自定义快捷键效果
Arthas命令行快捷键
快捷键说明
命令说明
ctrla
跳到行首
ctrle
跳到行尾
ctrlm
结束当前行,相当于敲回车
ctrlj
结束当前行,相当于敲回车
ctrli
自动补全,相当于敲TAB
ctrlk
删除当前光标到行尾的所有字符
ctrld
删除当前光标所在字符
ctrlu
撤销上一个命令,相当于清空当前行
ctrlshift
向后删除一个字符
ctrlh
向后删除一个字符
键盘上方向键
上翻显示上一个命令
键盘下方向键
下翻显示下一个命令
键盘右方向键
光标向后移动一个字符
键盘左方向键
光标向前移动一个字符
ctrlb
向后移动一个单词
ctrlf
向前移动一个单词任何时候tab键,会根据当前的输入给出提示命令后敲或,然后按tab键,可以展示出此命令具体的选项后台异步命令相关快捷键ctrlc:终止当前命令ctrlz:挂起当前命令,后续可以bgfg重新支持此命令,或kill掉ctrla:回到行首ctrle:回到行尾小结
命令
说明
session
显示当前会话的信息:进程的ID,会话ID
reset
重置类的增强,服务器关闭的时候会自动重置所有的类
keymap
获取快捷键
stop
退出arthas服务器,所有的会话都停止
quit
退出当前会话,不会影响其它的会话
version
显示arthas版本号jvm相关命令之一目标dashboard仪表板thread线程相关jvm虚拟机相关sysprop系统属性相关dashboard作用
显示当前系统的实时数据面板,按q或ctrlc退出效果
数据说明ID:Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应NAME:线程名GROUP:线程组名PRIORITY:线程优先级,110之间的数字,越大表示优先级越高STATE:线程的状态CPU:线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。TIME:线程运行总时间,数据格式为分:秒INTERRUPTED:线程当前的中断位状态DAEMON:是否是daemon线程thread线程相关作用
查看当前JVM的线程堆栈信息参数说明
参数名称
参数说明
数字
线程id
〔n:〕
指定最忙的前N个线程并打印堆栈
〔i〕
指定cpu占比统计的采样间隔,单位为毫秒
〔b〕
找出当前阻塞其他线程的线程
举例
展示当前最忙的前3个线程并打印堆栈,threadn3
当没有参数时,显示所有线程的信息,thread;当显示1号线程的运行堆栈,thread1
找出当前阻塞其他线程的线程,有时候我们发现应用卡住了,通常是由于某个线程拿住了某个锁,并且其他线程都在等待这把锁造成的。为了排查这类问题,arthas提供了threadb,一键找出那个罪魁祸首。threadb
指定采样时间间隔,每过1000毫秒采样,显示最占时间的3个线程threadi1000n3
查看处于等待状态的线程,threadstateWAITING
jvm作用
查看当前JVM的信息效果
THREAD相关COUNT:JVM当前活跃的线程数DAEMONCOUNT:JVM当前活跃的守护线程数PEAKCOUNT:从JVM启动开始曾经活着的最大线程数STARTEDCOUNT:从JVM启动开始总共启动过的线程次数DEADLOCKCOUNT:JVM当前死锁的线程数文件描述符相关MAXFILEDESCRIPTORCOUNT:JVM进程最大可以打开的文件描述符数OPENFILEDESCRIPTORCOUNT:JVM当前打开的文件描述符数sysprop作用
查看和修改JVM的系统属性举例查看所有属性sysprop查看单个属性,支持通过tab补全syspropjava。version
修改单个属性syspropuser。countryuser。countryUSsyspropuser。countryCNSuccessfullychangedthesystemproperty。user。countryCN
小结
jvm相关命令
说明
dashboard
显示线程,内存,GC,系统环境等信息
thread
显示线程信息
sysprop
显示系统属性信息,也可以修改某个属性
jvm
与JVM相关的信息jvm相关命令之二目标sysenvvmoptiongetstaticognlsysenv作用
查看当前JVM的环境属性(SystemEnvironmentVariables)举例查看所有环境变量sysenv查看单个环境变量sysenvUSER效果
vmoption作用
查看,更新VM诊断相关的参数举例查看所有的选项vmoption查看指定的选项vmoptionHeapDumpAfterFullGC
更新指定的选项vmoptionHeapDumpAfterFullGCtrue
getstatic作用
通过getstatic命令可以方便的查看类的静态属性语法getstatic类名属性名举例显示demo。MathGame类中静态属性randomgetstaticdemo。MathGamerandom
ognl作用
执行ognl表达式,这是从3。0。5版本新增的功能OGNL语法
官网:http:commons。apache。orgpropercommonsognllanguageguide。html
参数说明
参数说明
参数名称
express
执行的表达式
〔c:〕
执行表达式的ClassLoader的hashcode,默认值是SystemClassLoader
〔x〕
结果对象的展开层次,默认值1
举例调用静态函数ognljava。lang。Systemout。println(hello)获取静态类的静态字段ognldemo。MathGamerandom执行多行表达式,赋值给临时变量,返回一个Listognlvalue1SystemgetProperty(java。home),value2SystemgetProperty(java。runtime。name),{value1,value2}
小结
jvm相关命令
说明
sysenv
查看JVM环境变量的值
vmoption
查看JVM中选项,可以修改
ognl
执行一个ognl表达式
getstatic
获取静态成员变量classclassloader相关命令之一目标sc:SearchClasssm:SearchMethodsc作用
查看JVM已加载的类信息,SearchClass的简写,这个命令能搜索出所有已经加载到JVM中的Class信息
sc默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,请打开optionsdisablesubclasstrue开关参数说明
参数名称
参数说明
classpattern
类名表达式匹配,支持全限定名,如com。taobao。test。AAA,也支持comtaobaotestAAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把替换为。啦。
methodpattern
方法名表达式匹配
〔f〕
输出当前类的成员变量信息(需要配合参数d一起使用)
〔E〕
开启正则表达式匹配,默认为通配符匹配
〔d〕
输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次举例模糊搜索,demo包下所有的类scdemo。打印类的详细信息scddemo。MathGame
打印出类的Field信息scdfdemo。MathGame
sm作用
查看已加载类的方法信息
SearchMethod的简写,这个命令能搜索出所有已经加载了Class信息的方法信息。
sm命令只能看到由当前类所声明(declaring)的方法,父类则无法看到。参数说明
参数名称
参数说明
classpattern
类名表达式匹配
methodpattern
方法名表达式匹配
〔E〕
开启正则表达式匹配,默认为通配符匹配
〔d〕
展示每个方法的详细信息举例
显示String类加载的方法,smjava。lang。String
显示String中的toString方法详细信息,smdjava。lang。StringtoString
小结
与类相关的命令
说明
sc
SearchClass显示类相关的信息
sm
SearchMethod显示方法相关的信息classclassloader相关命令之二目标jad把字节码文件反编译成源代码mc在内存中把源代码编译成字节码文件redefine把新生成的字节码文件在内存中执行jad作用
反编译指定已加载类源码jad命令将JVM中实际运行的class的bytecode反编译成java代码,便于你理解业务逻辑;
在ArthasConsole上,反编译出来的源码是带语法高亮的,阅读更方便;
当然,反编译出来的java代码可能会存在语法错误,但不影响你进行阅读理解;参数说明
参数名称
参数说明
classpattern
类名表达式匹配
〔E〕
开启正则表达式匹配,默认为通配符匹配举例
编译java。lang。String,jadjava。lang。String
反编绎时只显示源代码,默认情况下,反编译结果里会带有ClassLoader信息,通过sourceonly选项,可以只打印源代码。方便和mcredefine命令结合使用。jadsourceonlyjava。lang。Object
反编译指定的函数,jaddemo。MathGamemain
mc作用
MemoryCompiler内存编译器,编译。java文件生成。class举例在内存中编译Hello。java为helloworld。classmcdatahelloworld。java可以通过d命令指定输出目录mcddataoutputdatahelloworld。java效果
redefine作用
加载外部的。class文件,redefine到JVM里
注意,redefine后的原来的类不能恢复,redefine有可能失败(比如增加了新的field)。
reset命令对redefine的类无效。如果想重置,需要redefine原始的字节码。
redefine命令和jadwatchtracemonitortt等命令会冲突。执行完redefine之后,如果再执行上面提到的命令,则会把redefine的字节码重置。redefine的限制不允许新增加fieldmethod正在跑的函数,没有退出不能生效,比如下面main()、run()方法中新增加的System。out。println,只有run()函数里的会生效publicclassMathGame{publicstaticvoidmain(String〔〕args)throwsInterruptedException{MathGamegamenewMathGame();while(true){game。run();TimeUnit。SECONDS。sleep(1);这个不生效,因为代码一直跑在while里System。out。println(在main函数中添加);}}publicvoidrun()throwsInterruptedException{这个生效,因为run()函数每次都可以完整结束System。out。println(在run函数中添加);try{intnumberrandom。nextInt();ListIntegerprimeFactorsprimeFactors(number);print(number,primeFactors);}catch(Exceptione){System。out。println(String。format(illegalArgumentCount:3d,,illegalArgumentCount)e。getMessage());}}}案例:结合jadmc命令使用步骤1。使用jad反编译demo。MathGame输出到dataMathGame。javajadsourceonlydemo。MathGamedataMathGame。java2。按上面的代码编辑完毕以后,使用mc内存中对新的代码编译mcdataMathGame。javaddata3。使用redefine命令加载新的字节码redefinedatademoMathGame。class结果
从上面可以得出,我们在main()方法新增的内容并没有生效,在run()方法新增的内容生效了。小结
类相关的命令
说明
jad
反编译字节码文件得到java的源代码
mc
在内存中将源代码编译成字节码
redefine
将字节码文件重新加载到内存中执行学习总结安装arthas的方法既可以安装在windows下也可以安装在LinuxcurlO
javajararthasboot。jar离线安装将从maven仓库中下载的zip包直接解压就可以使用卸载方式直接删除2个文件夹:。arthas和logs在线安装基础命令
help
显示所有arthas命令,每个命令都可以使用h的参数,显示它的参数信息
cat
显示文本文件内容
grep
对内容进行过滤,只显示关心的行
keymap
显示所有的快捷键
stop
结束arthas服务器,退出所有的会话
quit
退出当前的会话
version
显示当前arthas的版本号
reset
重置arthas增强的类
session
显示当前连接的会话ID
cls
清除屏幕
pwd
显示当前的工作路径
3。jvm相关命令
jvm相关命令
说明
dashboard
仪表板,可以显示:线程,内存,堆栈,GC,Runtime等信息
thread
显示线程的堆栈
ognl
执行一条ognl表达式,对象图导航语言
getstatic
获取类中静态成员变量
vmoption
显示jvm中选项信息
sysenv
显示jvm中系统环境变量配置信息
sysprop
显示jvm中系统属性,也可以修改某个属性
jvm
显示java虚拟机信息
4。class和classloader相关命令
类,类加载相关的命令
说明
sc
SearchClass查看运行中的类信息
sm
SearchMethod查看类中方法的信息
redefine
将编译好的字节码文件加载到jvm中运行
mc
MemoryCompile将源代码编译成字节码
jad
反编译字节码为源代码参考
https:arthas。aliyun。comdocindex。html