阿里在线诊断工具----------Arthas


目录

  • 官方地址
  • 实时查看方法的入参-出参
  • 记录几次现场的请求-返回数据
  • 检查接口具体哪一个步骤慢
  • 没有源码怎么办
  • 线程相关
    • 查看最忙的线程
    • 查看正在阻塞别的线程的线程
    • 查看线程堆栈
  • 查看线程cpu占比
  • 推荐公众号

官方地址 【阿里在线诊断工具----------Arthas】https://alibaba.github.io/arthas/
下面展示几种使用场景
实时查看方法的入参-出参 watch命令
[arthas@8279]$ watch com.example.controller.UserController getUser '{params,returnObj,throwExp}' -n 5 -x 3 '1==1' Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 1) cost in 78 ms, listenerId: 1 ts=2020-06-09 20:19:08; [cost=165.157044ms] result=@ArrayList[ @Object[][ @Integer[5], ], @User[ id=@Integer[5], userName=null, userPwd=null, modified=@Date[2020-06-08 18:07:12,000], created=null, appType=null, status=@Integer[0], dbSet=null, ], null, ]如上打印信息,入参-出参很明显的列出来了

记录几次现场的请求-返回数据
记录getUser 三次请求-返回数据 为什么要指定次数,万一一瞬间请求量很大会撑爆内存[arthas@8279]$ tt -t -n 3 com.example.controller.UserController getUser Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 1) cost in 46 ms, listenerId: 2 INDTIMESTAMPCOST(IS-ISOBJECTCLASSMETHOD EXms)RET-E XP -------------------------------------------------------------------------------- 1002020-06-092.424trufa0x21a58dUserControllergetUser 020:24:50631els5d e 1002020-06-092.027trufa0x21a58dUserControllergetUser 120:24:52686els5d e 1002020-06-091.325trufa0x21a58dUserControllergetUser 220:24:52218els5d e Command execution times exceed limit: 3, so command will exit. You can set it with -n option.展示所有记录的请求-返回数据 [arthas@8279]$ tt -l INDTIMESTAMPCOST(IS-ISOBJECTCLASSMETHOD EXms)RET-E XP -------------------------------------------------------------------------------- 1002020-06-092.424trufa0x21a58dUserControllergetUser 020:24:50631els5d e 1002020-06-092.027trufa0x21a58dUserControllergetUser 120:24:52686els5d e 1002020-06-091.325trufa0x21a58dUserControllergetUser 220:24:52218els5d e Affect(row-cnt:3) cost in 6 ms.展示具体一次的请求-返回数据 [arthas@8279]$ tt -i 1000 INDEX1000 GMT-CREATE2020-06-09 20:24:50 COST(ms)2.424631 OBJECT0x21a58d5d CLASScom.example.controller.UserController METHODgetUser IS-RETURNtrue IS-EXCEPTIONfalse PARAMETERS[0]@Integer[5] RETURN-OBJ@User[ id=@Integer[5], userName=null, userPwd=null, modified=@Date[2020-06-08 18:07:12,000], created=null, appType=null, status=@Integer[0], dbSet=null, ] Affect(row-cnt:1) cost in 5 ms.由Arthas-重新请求一次 [arthas@8279]$ tt -i 1000 -p RE-INDEX1000 GMT-REPLAY2020-06-09 20:26:30 OBJECT0x21a58d5d CLASScom.example.controller.UserController METHODgetUser PARAMETERS[0]@Integer[5] IS-RETURNtrue IS-EXCEPTIONfalse COST(ms)3.14049 RETURN-OBJ@User[ id=@Integer[5], userName=null, userPwd=null, modified=@Date[2020-06-08 18:07:12,000], created=null, appType=null, status=@Integer[0], dbSet=null, ] Time fragment[1000] successfully replayed 1 times.

检查接口具体哪一个步骤慢 trace命令 查看接口中具体哪个方法慢
传统方式,在全部方法前后加时间(获取部分认为有可能慢的方法),然后加日志
arthas方式
阿里在线诊断工具----------Arthas
文章图片

如上图所示,很明显的展示方法的耗时
参数请参考
https://alibaba.github.io/arthas/trace.html
没有源码怎么办 1.搜索项目中已加载的类
sc *Controller
[arthas@7387]$ sc *Controller com.example.controller.CustomerSourceSelfController com.example.controller.UserController 。。。。。。。。 返回加载的类

2.搜索某个类中有那些方法
sm com.example.controller.CustomerSourceSelfController
[arthas@7387]$ sm com.example.controller.UserController com.example.controller.UserController ()V com.example.controller.UserController GetUser(I)Ljava/lang/String; Affect(row-cnt:2) cost in 40 ms.可以看到有GetUser方法

3.反编译类
jad com.example.controller.UserController
[arthas@7387]$ jad com.example.controller.UserControllerClassLoader: +-sun.misc.Launcher$AppClassLoader@18b4aac2 +-sun.misc.Launcher$ExtClassLoader@222114baLocation: /Users/admin/Downloads/cloud/springBoot_Mybatis/Springboot_Mybatis/target/classes//* * Decompiled with CFR. * * Could not load the following classes: *com.example.service.UserService */ package com.example.controller; import com.example.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping(value=https://www.it610.com/article/{"/testBoot"}) public class UserController { @Autowired private UserService userService; @RequestMapping(value=https://www.it610.com/article/{"getUser/{id}"}) public String GetUser(@PathVariable int id) { return this.userService.Sel(id).toString(); } }Affect(row-cnt:1) cost in 961 ms.

线程相关 查看最忙的线程
会展示完整的堆栈和cpu占用率 [arthas@8279]$ thread -n 3 "as-command-execute-daemon" Id=89 cpuUsage=100% RUNNABLE at sun.management.ThreadImpl.dumpThreads0(Native Method) at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448) at com.taobao.arthas.core.command.monitor200.ThreadCommand.processTopBusyThreads(ThreadCommand.java:194) at com.taobao.arthas.core.command.monitor200.ThreadCommand.process(ThreadCommand.java:115) at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.process(AnnotatedCommandImpl.java:82) at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl.access$100(AnnotatedCommandImpl.java:18) at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:111) at com.taobao.arthas.core.shell.command.impl.AnnotatedCommandImpl$ProcessHandler.handle(AnnotatedCommandImpl.java:108) at com.taobao.arthas.core.shell.system.impl.ProcessImpl$CommandProcessTask.run(ProcessImpl.java:372) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)"Reference Handler" Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference$Lock@156ce6cb at java.lang.Object.wait(Native Method) -waiting on java.lang.ref.Reference$Lock@156ce6cb at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)"Finalizer" Id=3 cpuUsage=0% WAITING on java.lang.ref.ReferenceQueue$Lock@216e434e at java.lang.Object.wait(Native Method) -waiting on java.lang.ref.ReferenceQueue$Lock@216e434e at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

查看正在阻塞别的线程的线程
[arthas@8539]$ thread -b "http-nio-8077-exec-5" Id=28 TIMED_WAITING at java.lang.Thread.sleep(Native Method) at com.example.controller.UserController.getUse2r(UserController.java:42) -locked java.lang.Object@64ecdcc5 <---- but blocks 1 other threads! at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

查看线程堆栈
[arthas@8539]$ thread 3 "Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@31258ebf at java.lang.Object.wait(Native Method) -waiting on java.lang.ref.ReferenceQueue$Lock@31258ebf at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)Affect(row-cnt:0) cost in 2 ms.

查看线程cpu占比
thread -i 3 Threads Total: 32, NEW: 0, RUNNABLE: 12, BLOCKED: 0, WAITING: 14, TIMED_WAITING: 6, TERMINATED: 0 IDNAMEGROUPPRIORITYSTATE%CPUTIMEINTERRUPTEDDAEMON 50as-command-execute-daemonsystem10RUNNABLE1000:0falsetrue 16Attach Listenersystem9RUNNABLE00:0falsetrue 20ContainerBackgroundProcessor[StandardEngine[ main5TIMED_WAITING00:0falsetrue 39DestroyJavaVMmain5RUNNABLE00:2falsefalse

推荐公众号 有彩蛋哦!!!(或者公众号内点击网赚获取彩蛋)
阿里在线诊断工具----------Arthas
文章图片

    推荐阅读