arthas学习图文记录

🚀 优质资源分享 🚀

学习路线指引(点击解锁)知识定位人群定位
🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

Arthas 是阿里开源的 Java 诊断工具。在线排查问题,无需重启;动态跟踪 Java 代码;实时监控 JVM 状态。Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

Arthas可以通过简单的命令交互模式,接入运行的JVM,快速定位和诊断线上程序运行的问题。在不重启服务的情况下,实时,动态的修改相关代码,并实时生效,具体工作原理如下:

  1. 连接JVM,通过attach机制,通过attach pid连接正在运行的JVM
  2. 查看及修改JVM字节码,通过instrument技术对运行中的JVM附加或修改字节码来实现增强的逻辑

Arthas的执行过程如下:Arthas底层调用rt.jar包的ManagementFactory获取整个JVM内部信息,通过命令集成与后端交互,执行,返回结果,整个工程简单清晰,容易上手。

arthas-demo入门

可以使用阿里云给的基础教程地址练习: https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn&id=arthas-basics

在这里,我使用自己的服务器,跟着基础教程做入门联系。

1.下载math-game.jar,再用java -jar命令启动

[root@localhost arthas]# wget https://arthas.aliyun.com/math-game.jar
[root@localhost arthas]# java -jar arthas-boot.jar

2.新开Terminal ,下载arthas-boot.jar,再用java -jar命令启动

[root@localhost arthas]# wget https://arthas.aliyun.com/arthas-boot.jar
[root@localhost arthas]# java -jar arthas-boot.jar

arthas-bootArthas的启动程序,它启动后,会列出所有的Java进程,用户可以选择需要诊断的目标进程。

选择第一个进程,输入 1 (math-game这个程序对应的就是1),再Enter/回车

Attach成功之后,会打印Arthas LOGO。输入 help 可以获取到更多的帮助信息。

3. dashboard 命令可以查看当前系统的实时数据面板

数据说明:

  • ID:java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
  • NAME:线程名
  • GROUP:线程组名
  • PRIORI:线程的优先级,1~10之间的数字,越大表示优先级越高
  • STATE:线程的状态
  • %CPU:线程的CPU使用率,比如采样间隔1000ms,某个线程的增量cpu时间为100ms,则cpu的使用率为100/1000=10%
  • DELTA_TIME:上次采样之后线程运行增量cpu时间,数据格式为秒
  • TIME:线程运行总CPU时间,数据格式为 分:秒
  • INTERRUPTED:线程当前的中断位状态
  • DAEMON:是否是daemon(后台)线程

4. thread 命令会打印线程ID 1的栈

还可以通过thread 1 | grep 'main(' 命令来查找main class:

参数说明:

参数名称参数说明
id线程id
[ n: ]指定最忙的前N个线程并打印堆栈
[ b ]找出当前阻塞其他线程的线程(目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。)
[ i ]指定cpu占比统计的采样间隔,单位为毫秒
[ --all ]显示所有匹配的线程
[ --state ]查看指定状态的线程,如: thread --state WAITING

5. sc命令来查找JVM里已加载的类

sc为“Search-Class” 的简写,能搜索出所有已经加载到 JVM 中的 Class 信息。

参数说明:

参数名称参数说明
class-pattern类名表达式匹配,支持全限定名。如:demo.MathGame,也支持demo/MathGame
method-pattern方法名表达式匹配
[ d ]输出当前类的详细信息,包括这个类所加载的原始文件来源,类的声明,加载的ClassLoader等详细信息;如果一个类被多个ClassLoader所加载,则会出现多次
[ E ]开启正则表达式匹配,默认为通配符匹配
[ f ]输出当前类的成员变量信息(需要配合参数 -d一起使用)
[ x: ]指定输出静态变量时属性的遍历深度,默认为0,直接使用toString输出
[ c: ]指定class的ClassLoader的hashcode
[ classLoaderClass: ]指定执行表达式的ClassLoader的class name
[ n: ]具有详细信息的匹配类的最大数量,默认为100

sm为“Search-Method” 的简写,查询某个类下所有的方法,与sc的功能类似,这里就不详细介绍了。

6. jad命令来反编译代码

还可以反编译指定的函数

反编译时只显示源代码

默认情况下,反编译结果里会带有ClassLoader信息,通过--source-only选项,可以只打印源代码。这样就会清爽很多。

7. watch方法执行数据观测

watch命令可以查看函数的参数/返回值/异常信息,通过编写 OGNL 表达式进行对应变量的查看。

从上面的结果里,说明函数被执行了两次,第一次结果是 location=AtExceptionExit,说明函数抛出了异常,因此returnObj是null;第二次结果是location=AtExit,说明函数正常返回,因此可以看到returnObj的结果是一个ArrayList。

参数说明:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
express观察表达式,默认值为:{params,target,returnObj},单个值可以不用加 {},多个值需要加
condition-express条件表达式,不能加 {},可以使用逗号分隔子表达式,取表达式最后一个值来判断
[ b ]在方法调用之前观察,默认关闭,由于观察事件点是在方法调用前,此时返回值或异常均不存在,params代表方法入参
[ e ]在方法异常之后观察,默认关闭,params代表方法出参
[ s ]在方法返回之后观察,默认关闭,params代表方法出参
[ f ]在方法结束之后(正常返回和异常返回)观察,默认打开,params代表方法出参
[ E ]开启正则表达式匹配,默认为通配符匹配
[ x: ]指定输出结果的属性遍历深度,默认为1
[ #cost ]监控耗时

条件表达式的例子:

下面这个例子表示只有参数小于0的调用才会响应。

异常信息的例子:

-e 表示抛出异常时才触发

express中,表示异常信息的变量时throwExp

8. vmtool命令,可以搜索内存对象

vmtool 利用JVMTI接口,实现查询内存对象,强制GC等功能。

参数说明:

参数名称参数说明
–action getInstances返回结果绑定到 instances变量上,它是数组。
–className指定类名(完成路径),支持 java.lang.String,也支持java/lang/String
[ --limit ]限制返回值数量,避免获取超大数据时对JVM造成压力。默认值是10。
[ -x ]指定返回结果展开层数,默认为1
[ c: ]指定class的ClassLoader的hashcode(通过sc命令找到加载class的classLoader)
[ classLoaderClass: ]指定执行表达式的ClassLoader的class name

强制GC的命令:vmtool --action forceGc

9. 退出Arthas

exit 或者 quit 命令可以退出Arthas。退出Arthas之后,还可以再次用 java -jar arthas-boot.jar 来连接。

10. 彻底退出Arthas

exit/quit命令只是退出当前session,arthas server还在目标进程中运行。

想完全退出Arthas,可以执行 stop 命令。

Arthas的其他重点使用功能

1. mc 内存编译器(Memory Compiler/内存编译器)

Memory Compiler/内存编译器,编译.java文件生成.class。通过 -c / --classLoaderClass 参数指定classLoader,-d 参数指定输出目录;编译生成.class文件之后,可以结合retransform 命令实现热更新代码。retransform的限制:1.不允许新增加field和method 2.正在跑的函数,没有退出不能生效

这里还是使用arthas的提供的教程:https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn&id=command-mc-retransform

1.由于正在跑的函数没有退出时不生效的,所以上面的math-game的demo就不能使用了,所以得下载另一个demo(一个简单的spring-boot应用)。

[root@localhost arthas]# wget https://raw.githubusercontent.com/hengyunabc/spring-boot-inside/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jar
[root@localhost arthas]# java -jar demo-arthas-spring-boot.jar 

2.新开一个Terminal;访问下面这个路径,可以看到报错(500异常)了。

3.启动arthas-boot应用。

4.反编译代码可以看到,当id小于1是,就会抛出异常。

在这里,我们修改文件,想让id小于1时还是能正常返回,不抛出异常。

5.jad反编译UserController,将结果保存在/tmp/UserController.java文件夹里。

[arthas@1645]$ jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

6.通过vim /tmp/UserController.java编辑java类。

7.通过sc查找加载UserContoller的ClassLoader,也可以在jad时显示源码,里面也有classLoader的信息。

以下三个命令任意一个都可以。可以看到,这个java类是由LaunchedURLClassLoader@1be6f5c3 这个类加载器加载的。

8.通过mc命令编译,同时指定--classLoaderClass参数指定ClassLoader:

[arthas@1645]$ mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp

也可以通过-c 参数指定ClassLoaderHash:

[arthas@1645]$ mc --c 1be6f5c3 /tmp/UserController.java -d /tmp

可以看到,在tmp文件夹下,根据UserController的类的全路径编译了一个class文件:

9.retransform 命令中西加载新编译好的UserContoller.class类:

10.重新编译文件可以看到,代码已经替换成最新的了:

11.访问:

显示已经替换过的类:retransform -l

恢复修改前的代码,清楚指定的类:retransform -d 1

清楚所有的:retransform --deleteAll

2.trace 方法内部调用路径,并输出方法路径上的每个节点上耗时

可以观察方法执行的时候哪个子调用比较慢

[arthas@1645]$ trace ClassName methodName

trace 命令能主动搜索 class-patternmethod-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。在进行性能调优的时候十分有效。

参数说明:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
express观察表达式,默认值为:{params,target,returnObj},单个值可以不用加 {},多个值需要加
condition-express条件表达式
[ E ]开启正则表达式匹配,默认为通配符匹配
[ n: ]命令执行次数
[ #cost ]方法执行耗时
[ --skipJDKMethod ]跳过jdk方法,默认为true

不跳过JDK方法:

只展示耗时大于1ms的调用路径:

动态trace:

从上图中可以看到,primeFactors的方法耗时最长,如果想深入primeFactors方法,可以打开一个新的终端,使用telnet localhost 3658 连接上arthas,在trace primeFactors时指定listenerId。

这时终端2打印的结果,说明已经增强了一个函数:Affect(class count: 1 , method count: 1),但不再打印更多的结果。

再查看终端1,可以发现trace的结果增加了一层,打印了primeFactors函数里的内容:

注意 --listenerId指定的id在前一条命令的输出中可以看到。

3.stack 查看某个函数的调用堆栈路径

很多时候,在一个方法被执行时,方法的执行路径非常多,或者根本就不着调这个方法时从哪里被执行的,就可以使用stack命令。此命令和trace命令结构类似。

[arthas@1645]$ stack demo.MathGame primeFactors

参数说明:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
express观察表达式,默认值为:{params,target,returnObj},单个值可以不用加 {},多个值需要加
condition-express条件表达式
[ E ]开启正则表达式匹配,默认为通配符匹配
[ n: ]命令执行次数

4.tt 命令

tt是TimeTunnel 的缩写,tt命令记录方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。

这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

参数说明:

参数名称参数说明
-t记录下类对应的方法的每次执行情况
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
[ n: ]命令执行次数
condition-express条件表达式

表格字段说明:

表格字段字段解释
index时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
timestamp方法执行的本机时间,记录了这个时间片段所发生的本机时间
cost(ms)方法执行的耗时
is-ret方法是否以正常返回的形式结束
is-exp方法是否以抛异常的形式结束
object执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
class执行的类名
method执行的方法名

检索调用记录:

tt -l 检索所有的调用记录:

筛选出 primeFactors 方法的调用信息:

通过 -i 参数后边跟着对应的 INDEX 编号查看到他的详细信息:

重做一次调用:

tt 命令由于保存了当时调用的所有现场信息,所以我们可以自己主动对一个 INDEX 编号的时间片自主发起一次调用。此时需要使用 -p 参数。通过 --replay-times 指定 调用次数,通过 --replay-interval 指定多次调用间隔(单位ms, 默认1000ms)

需要强调的点

  1. ThreadLocal 信息丢失

很多框架偷偷的将一些环境变量信息塞到了发起调用线程的 ThreadLocal 中,由于调用线程发生了变化,这些 ThreadLocal 线程信息无法通过 Arthas 保存,所以这些信息将会丢失。
2. 引用的对象

需要强调的是,tt 命令是将当前环境的对象引用保存起来,但仅仅也只能保存一个引用而已。如果方法内部对入参进行了变更,或者返回的对象经过了后续的处理,那么在 tt 查看的时候将无法看到当时最准确的值。这也是为什么 watch 命令存在的意义。

5.monitor 方法执行监控

对匹配的class-pattern / method-pattern的类、方法的调用进行监控。monitor命令是一个非实时返回的命令(并不是输入之后立即返回,而是不断的等待目标java进程返回信息)。

参数说明:

参数名称参数说明
class-pattern类名表达式匹配
method-pattern方法名表达式匹配
[ E ]开启正则表达式匹配,默认为通配符匹配
[ c: ]统计周期,默认值为120秒,是一个整型的参数值

监控项说明:

监控项timestampclassmethodtotalsuccesstailrtfail-rate
说明时间戳java类方法调用次数成功次数失败次数平均rt失败率

5.target-ip

target-ip 为指定绑定的IP,如果不指定IP,Arthas只listen 127.0.0.1,所以如果想从远程连接,则可以使用 --target-ip参数指定listen的IP。

java -jar arthas-boot.jar --target-ip IP

绑定远程访问IP后,可以在通过telnet 或者http的方式远程连接Arthas进行问题排查

还有更多的功能请查看arthas的官方文档。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用矩阵的n次方求图的连通性

设A(n x n)为一个图的邻接矩阵,则a(i,j)表示两个点之间是否连通(1:连通,0:不连通)。那么A的k次方中的每一个a(i,j)表示点i和j之间长度为k的路的条…

使用HBuilder新建项目

依次点击文件→新建→选择Web项目(按下CtrlN,W可以触发快速新建(MacOS请使用CommandN,然后左键点击Web项目)) 如上图,请在A处填写新建项目的名称,B处填写(或选择)项目保存路径(更改此路径HBuilder会记录,下次默认使用更改后的路径)&#xff0…

iOS应用开发视频教程笔记(二)My First iOS App

这课主要是以一个计算器一个用为例子,教你怎么使用XCode,如何使用MVC设计模式创建应用。 (1)新建一个single view application模版的应用 打开xcode并点击“创建一个新xcode项目”,进入项目创建界面,这个界面让我们为应用选择一个…

牛顿迭代法(Newton#39;s Method)

牛顿迭代法(简称牛顿法)由英国著名的数学家牛顿爵士最早提出。可是,这一方法在牛顿生前并未公开发表(讨厌的数学家们还是鼓捣出来了)牛顿法的作用是使用迭代的方法来求解函数方程的根。简单地说,牛顿法就是…

【深入理解计算机系统CSAPP】第六章 存储器层次结构

🚀 优质资源分享 🚀 学习路线指引(点击解锁)知识定位人群定位🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一…

【转】无刷新验证用户名可用性

在用户注册时&#xff0c;我们经常需要检查用户名是否存在&#xff0c;本文就是实现无刷新验证用户名 打开开发环境VS 2005,新建项目(或打开现有项目),新建一个Web窗体,命名为 Default.aspx 代码如下&#xff1a; View Code <% Page Language"C#" AutoEventWireu…

Python数据分析--Numpy常用函数介绍(2)

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)

&#xff08;其实今天好热啊&#xff1f; 题目大意&#xff1a;插入&#xff0c;删除&#xff0c;k小&#xff0c;前驱后继&#xff0c;数的排名。 splay和treap裸题...过几天补个treap的 splay: #include<iostream> #include<cstdlib> #include<cstring> #i…

手机相机自动识别语音提示

技术背景&#xff1a; 时下流行的手机拍照功能越来越多&#xff0c;在众多的手机拍照过程中&#xff0c;我们只在于手机拍照的效果和风景是否美好&#xff0c;甚至拿着手机自我狂拍&#xff0c;留下美好的记忆和回忆。 有时候根据手机相机的已有技术功能随便一设置就能拍到理想…

c# Invoke和BeginInvoke 区别

转自http://www.cnblogs.com/c2303191/articles/826571.html Control的Invoke和BeginInvoke是相对于支线线程&#xff08;因为一般在支线线程中调用&#xff0c;用来更新主线程ui&#xff09;Invoke立即插入主线程中执行&#xff0c;而BeginInvoke 要等主线程结束才执行 近日&a…

04 Springboot 格式化LocalDateTime

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

DNN使用非80端口和总是跳转到http://localhost问题的解决

2019独角兽企业重金招聘Python工程师标准>>> 我试图在一台服务器上安装一个DNN网站时&#xff0c;遇到了一些问题。问题一&#xff1a;遇到的第一个问题就是网站总是自动导向到localhost。不管我怎么试&#xff0c;只要我输入http://domain.com/dnn&#xff0c;总是…

Jmter操作数据库

1、导入jdbc的jar包&#xff0c;因为jmeter本身不能直接连接mysql&#xff0c;所以需要导入第三方的jar包&#xff0c;来连接mysql&#xff0c;如下操作&#xff1a;2、创建数据库连接如下&#xff1a; 3、配置mysql的url、端口号、账号、密码注意上面的Database URL&#xff1…

ComponentOne FlexGrid for WinForms 中文版快速入门(9)—过滤

C1FlexGrid过滤 表格中的数据过滤通常有两种形式&#xff1a; 基于表头&#xff1a;过滤器的图标出现在有一个过滤器适用于它的每一列。用户可以通过点击过滤器的图标来查看和编辑过滤器。这是Windows 7或Vista或C1FlexGrid控件使用的机制。这种类型的过滤器的主要优点是&…

Pycharm搜索导航之文件名、符号名搜索

1、准备一个工程 向你的工程中添加一个Python文件&#xff0c;并输入一些源码&#xff0c;例如&#xff1a; 2、转到对应文件、类、符号 Pycharm提供的一个很强力的功能就是能够根据名称跳转到任何文件、类、符号所在定义位置。 3、跳转到文件 按下CtrlShiftN快捷键&#xff0c…

分享网页设计当中使用进度条打造精美界面最佳例子

进度条是用户界面的重要组成部分&#xff0c;他向用户显示当前的下载进度&#xff0c;一个小的圆形因素使得界面不是更方便也更容易理解让我们举个例子&#xff0c;想象你去一个网站&#xff0c;你需要下载视频&#xff0c;你选择一个文件&#xff0c;按下"下载"按钮…

基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

软件项目管理 3.5.敏捷生存期模型

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…

spark内核揭秘-02-spark集群概览

2019独角兽企业重金招聘Python工程师标准>>> Spark集群预览&#xff1a; 官方文档对spark集群的初步描述如下&#xff0c;这是一个典型的主从结构&#xff1a; 官方文档对spark集群中的一些关键点给出详细的指导&#xff1a; 其Worker的定义如下所示&#xff1a; 需…

使用docker创建和运行跨平台的容器化的mssql数据库

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…