arthas 线上排查常用命令

下载arthas-boot.jar,然后用java -jar的方式启动:

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

或者
最新版下载

查看方法内部执行堆栈

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

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

posted @ 2021-12-17 11:27  mysgk  阅读(773)  评论(0编辑  收藏  举报