阿里线上排查Java工具arthas

1.离线安装    

下载地址  https://arthas.aliyun.com/download/doc/latest_version?mirror=aliyun

2.启动

    2.1  用as.sh启动    解压后 ./as.sh 启动

    2.2  用arthas-boot启动   java -jar arthas-boot.jar

3.命令介绍

3.1 sm(search method)     查找方法

    usage:  sm  com.tgram.rwpt.gateway.filter.AccessGatewayFilter    

    Usage:  sm -d com.tgram.rwpt.gateway.filter.AccessGatewayFilter  getOrder    展示方法的详细信息

3.2 jad   对类进行反编译

     Usage:  jad com.tgram.rwpt.gateway.filter.AccessGatewayFilter  

3.3 dashboard 当前系统的实时数据面板,按ctrl+c退出

      Usage: dashboard -i(刷新数据时间间隔ms)  1000  -n(刷新实时数据的次数) 5

3.4 thread  查看当前线程信息,查看线程的堆栈

      Usage:  thread  -n  3  展示当前最忙的前3个线程的堆栈信息

      Usage:  thread  id    显示指定线程的运行堆栈

      Usage:  thread -b    找出当前阻塞其他线程的线程(注意, 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持。) 

3.5 jvm  查看当前jvm信息

3.6 sysprop  查看当前jvm的系统属性

3.7 sysenv    查看当前jvm的环境属性

3.8 vmoption   查看/更新VM诊断相关参数

3.9 getstatic    查看类的静态属性

     Usage:   getstatic  com.tgram.rwpt.task.entity.ActionEntity  COLUMN_TYPE

     静态属性可以是复杂对象,通过ognl进行遍历,过滤,访问对象的内部属性等操作

     Usage:  假设n是个Map,Map的key是个Enum,我们想过滤出Map中key为某个enum的值

     getstatic  com.alibaba.arthas.Test   n  ‘entrySet().iterator.{? #this.key.name==“STOP”}'

3.10 ognl  执行ognl表达式

     Usage:   ognl ‘@java.lang.System@out.println(“test")'  调用静态函数   

     Usage:   ognl ‘@demo.MathGame@random’   获取静态类的静态字段

3.11 sc  (search class) 查看jvm已加载的类信息

      Usage:  sc -d  -f com.tgram.rwpt.gateway.filter.AccessGatewayFilter   -d 输出当前类的详细信息  -f   输出当前   类的成员变量(需要配合参数-d一起使用)

3.12 dump 已加载类的bytecode到特写目录

3.13 watch

        watch *.CommonTest test "{params,returnObj,throwExp}" '#cost>10 && params[0]==1' -x 5 -n 1

          解析

    *.CommonTest 类名

    test 方法名

    监控入参、返回、异常

    params 入参

    returnObj 返回

    throwExp 异常

   

    监控指标

    '#cost>10 && params[0]==1' 耗时超过10ms 且 第一个参数等于1

    -x 5 监控数据遍历深度5

    -n 1 只监控一次

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

tt -l   查看调用记录

tt  -I index值   查看调用信息

tt -I index值  -p  - -replay_times(指定调用次数)  - - replay_interval(指定多次调用时间间隔,默认ms)   重做一次调用

进阶

1.案例:排查函数调用异常现象

watch com.example.demo.arthas.user.UserController  *  '{params,throwExp}’ 'params[0] > 100'  -x  2

第一个参数为类名

第二个参数为函数名,支持通配

第三个参数为返回值表达式,它实际上是一个ognl表达式,它支持一些内置对象

  • loader

  • clazz

  • method

  • target

  • params

  • returnObj

  • throwExp

  • isBefore

  • isThrow

  • isReturn

第四个参数为条件表达式

当异常时捕获

watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e

按照耗时进行过滤

watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200’

2.案例  热更新代码, 通过jad/mc/redefine命令实现动态更新代码的功能

2.1 jad反编译UserController,并把编译的结果保存在/tmp/UserController.java中

jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java

2.2 用vim编辑源文件

Vim /tmp/UserController.java

2.3 sc查找加载UserCotroller的ClassLoader

sc -d *UserController | grep classLoaderHash

2.4使用Mc(Memory Complier)命令来编译,并且通过-c或者—classLoaderClass参数指定ClassLoader

mc --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader /tmp/UserController.java -d /tmp

2.4再使用redefine命令重新加载新编译好的UserController.class

redefine /tmp/com/example/demo/arthas/user/UserController.class

案例3  动态更新应用Logger Level

3.1 查找USerController的ClassLoder

sc -d com.example.demo.arthas.user.UserController  | grep classLoaderHash

3.2用ognl节能logger

ognl —classLoaderClass org.springframework.boot.loader.LaunchedURLClass

3.3单独设置UserController的logger level

ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger.setLevel(@ch.qos.logback.classic.Level@DEBUG)’

4.案例4 获取Spring Context

4.1使用tt命令获取到spring context (tt即TimeTunnel,它可以记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测)

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

4.2 使用tt命令从调用记录里获取 到spring context

tt -i 1000 -w 'target.getApplicationContext()’

4.3 获取spring bean,并调用函数

tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()’

案例5  排查http请求返回401

5.1 跟踪所有的Filter函数

trace javax.servlet.Filter *

5.2 通过stack获取调用栈

stack javax.servlet.http.HttpServletResponse sendError 'params[0]==401’

案例6 排查Http请求返回404

6.1跟踪所有servlet函数

trace javax.servlet.Servlet * > /tmp/servlet.txt

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值