arthas 线上排查常用命令
下载arthas-boot.jar,然后用java -jar的方式启动:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
或者
最新版下载
该版本支持查看方法内的局部变量:
arthas-with-line 下载
来源
https://github.com/alibaba/arthas/pull/2852
使用方法:
line com.xxx.AuthenticationFilter myMethod 338 -x 2
查看方法内部执行堆栈
方法内部调用路径,并输出方法路径上的每个节点上耗时
trace com.xxx.manage.impl.UserServiceImpl getUser '#cost > 10'
查看方法出入参
watch com.xxx.manage.impl.UserServiceImpl getUser '{params,returnObj,throwExp}' '#cost>200' -x 2
查看header
watch -x 3 -n 1 org.springframework.web.servlet.DispatcherServlet doDispatch '@org.springframework.web.context.request.RequestContextHolder@currentRequestAttributes().getRequest().getHeader("Authorization")'
筛选指定用户的请求
watch com.xxx.service.impl.UserServiceImpl getUser 'params' '@com.alibaba.fastjson.JSON@parseObject( new java.lang.String(@java.util.Base64@getUrlDecoder().decode(@org.springframework.web.context.request.RequestContextHolder@currentRequestAttributes().getRequest().getHeader("Authorization").split("\\.")[1]))).getString("u_id").equals("admin")'
查找类的 classLoaderHash
sc -d com.xxx.manage.util.SpringContext
查看类成员变量的值
vmtool --action getInstances --className 包名+类名 --express instances[0].需要查看的变量
vmtool --action getInstances --className com.xxx.xx --express instances[0].testname
## 在内存中查找字符串
vmtool --action getInstances --className java.lang.String --limit 1000000000 | grep myString
查看类中的静态变量
getstatic 包名+类名 静态变量名
getstatic com.test.TestClass staticName
执行类的方法
ognl -c 31221be2 '@com.manage.util.SpringContext@getBean("userService")' -x 2
ognl -c 31221be2 '@com.manage.util.SpringContext@getBean( @org.xx.XxService@class )' -x 3
获取spring配置
vmtool --action getInstances --className org.springframework.context.ConfigurableApplicationContext --express 'instances[0].getEnvironment().getProperty("server.port")'
或者
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
tt -i 1000 -w 'target.getApplicationContext().getBean("baiduSchedule").startSchedule()'
查看方法被调用堆栈
很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。
stack com.xxx.manage.impl.UserServiceImpl getUser
追踪jdk的方法
options unsafe true
表示构造方法
<init>
示例:
watch com.xxx.manage.impl.UserServiceImpl <init>
查询异常状态码返回的堆栈
stack -E javax.servlet.http.HttpServletResponse sendError|setStatus params[0]==404
代理类方法执行逻辑查找
sc com.abc.mapper.UserMapper
或
sc com.abc.mapper.UserFeign
反编译代理类
jad com.sun.proxy.$Proxy123
得到反射执行的实际类
watch com.sun.proxy.$Proxy123 abcMethod 'target.h.getClass().getName()'
追踪实际执行的方法
mybatis:
trace org.apache.ibatis.binding.MapperMethod execute
mybatis-plus:
trace com.baomidou.mybatisplus.core.override.MybatisMapperProxy invoke
mybatis 动态代理类
查看最高占用的线程
thread -n 3
查看当前JVM的系统属性
sysprop
查看当前JVM的环境属性
sysenv
查看,更新VM诊断相关的参数
vmoption
其他
查看第一个参数:
$ watch com.taobao.container.Test test "params[0]"
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 34 ms.
@ArrayList[
@Pojo[com.taobao.container.Test$Pojo@75a1cd57],
@Pojo[com.taobao.container.Test$Pojo@3d012ddd],
@Pojo[com.taobao.container.Test$Pojo@6f2b958e],
@Pojo[com.taobao.container.Test$Pojo@1eb44e46],
@Pojo[com.taobao.container.Test$Pojo@6504e3b2],
查看第一个参数的size:
$ watch com.taobao.container.Test test "params[0].size()"
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 22 ms.
@Integer[40]
将结果按name属性投影:
$ watch com.taobao.container.Test test "params[0].{ #this.name }"
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 25 ms.
@ArrayList[
@String[name 0],
@String[name 1],
按条件过滤:
$ watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 27 ms.
@ArrayList[
@Pojo[
name=null,
age=@Integer[32],
hobby=null,
],
]
@ArrayList[
@Pojo[
name=null,
age=@Integer[31],
hobby=null,
],
]
$ watch com.taobao.container.Test test "params[0].{? #this.name != null }" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 24 ms.
@ArrayList[
@Pojo[
name=@String[name 1],
age=@Integer[3],
hobby=null,
],
过滤后统计:
$ watch com.taobao.container.Test test "params[0].{? #this.age > 10 }.size()" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 29 ms.
@Integer[31]
@Integer[31]
判断字符串相等
比如第一个参数是String类型:
$ watch com.demo.Test test 'params[0]=="xyz"'
判断long型
$ watch com.demo.Test test 'params[0]==123456789L'
子表达式求值:
$ watch com.taobao.container.Test test "params[0].{? #this.age > 10 }.size().(#this > 20 ? #this - 10 : #this + 10)" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 76 ms.
@Integer[21]
@Integer[21]
选择第一个满足条件:
$ watch com.taobao.container.Test test "params[0].{^ #this.name != null}" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
@ArrayList[
@Pojo[
name=@String[name 0],
age=@Integer[2],
hobby=null,
],
]
$ watch com.taobao.container.Test test "params[0].{^ #this.name != null}.size()" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 57 ms.
@Integer[1]
选择最后一个满足条件:
$ watch com.taobao.container.Test test "params[0].{$ #this.name != null}" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
@ArrayList[
@Pojo[
name=@String[name 39],
age=@Integer[41],
hobby=null,
],
]
调用静态方法
$ watch com.taobao.container.Test test "@java.lang.Thread@currentThread()"
调用静态方法再调用非静态方法
$ watch com.taobao.container.Test test "@java.lang.Thread@currentThread().getContextClassLoader()"
https://github.com/alibaba/arthas/issues/71
https://github.com/alibaba/arthas/issues/11
https://blog.csdn.net/listeningsea/article/details/117700373
有问题请联系hudcan@sina.com
个人网站:http://ext.123cc.cc