ITPub博客

首页 > 数据库 > 数据库开发技术 > 线上诊断神器 Arthas 专治疗疑难杂症

线上诊断神器 Arthas 专治疗疑难杂症

原创 数据库开发技术 作者:DevXTalk 时间:2023-12-19 08:30:00 0 删除 编辑

线上诊断神器 Arthas 专治疗疑难杂症

❝

当线上发生问题时是很烦人的,领导们心急如焚,程序员被夺命连环 call 加钉钉轰炸, "快看看这个 XXX 功能怎么不行了......很紧急快点来公司一趟处理下"。一般大家都会先通过日志来定位问题,能从日志中定位的问题一般是比较简单的逻辑问题或编程错误,当通过日志无法定位问题时这时候一部分同学就开启了瞎猜模式,好像蒙着眼睛开战斗机。瞎猜它行么?行! 毕竟总有蒙对的时候。今天就给大家推荐一款神器提高效率专治瞎猜。当再遇到问题,你就掏出这个大宝贝,一顿疯狂操作后分分钟把问题解决掉, 瞬间 B 格就高了, 拯救加班的小伙伴于水火之中,事了拂衣去,深藏功与名,从此以后公司里只留下你的传说。

❞

Arthas 简介

Arthas 是 Alibaba 开源的 Java 诊断工具产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。

通常,本地开发环境无法访问生产环境。如果在生产环境中遇到问题,则无法使用 IDE 远程调试。更糟糕的是,在生产环境中调试是不可接受的,因为它会暂停所有线程,导致服务暂停。

开发人员可以尝试在测试环境或者预发环境中复现生产环境中的问题。但是,某些问题无法在不同的环境中轻松复现,甚至在重新启动后就消失了。

Arthas 旨在解决这些问题。「开发人员可以在线解决生产问题。无需 JVM 重启,无需代码更改。Arthas 作为观察者永远不会暂停正在运行的线程。」

Arthas 能为你解决什么问题?

❝

想象一下一个英国绅士,站在你身边一口地道的伦敦腔 "What can I do for you, sir"

❞

当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到 JVM 的实时运行状态?
  7. 怎么快速定位应用的热点,生成火焰图?
  8. 怎样直接从 JVM 内查找某个类的实例?
❝

Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

❞

快速安装

1. 下载  arthas

Github 下载: https://github.com/alibaba/arthas/releases Maven 仓库下载 : https://arthas.aliyun.com/download/latest_version?mirror=aliyun

2. 下载文档

离线文档: https://arthas.aliyun.com/download/doc/latest_version?mirror=aliyun

快速开始

1. 启动 arthas

在命令行下面执行(使用和目标进程一致的用户启动,否则可能 attach 失败):

java -jar arthas-boot.jar
  • 执行该程序的用户需要和目标进程具有相同的权限。比如以admin用户来执行:sudo su admin && java -jar arthas-boot.jar 或 sudo -u admin -EH java -jar arthas-boot.jar。
  • 如果 attach 不上目标进程,可以查看~/logs/arthas/ 目录下的日志。
  • 如果下载速度比较慢,可以使用 aliyun 的镜像:java -jar arthas-boot.jar --repo-mirror aliyun --use-http
  • java -jar arthas-boot.jar -h 打印更多参数信息。
❝

会输出如下信息,包括了使用示例,和支持的命令和参数

❞
[INFO] JAVA_HOME: /usr/local/jdk8u152-x64/jdk1.8.0_152/jre
[INFO] arthas-boot version: 3.7.1
Usage: arthas-boot [-h] [--target-ip <value>] [--telnet-port <value>]
[--http-port <value>] [--session-timeout <value>] [--arthas-home <value>]
[--use-version <value>] [--repo-mirror <value>] [--versions] [--use-http]
[--attach-only] [-c <value>] [-f <value>] [--height <value>] [--width
<value>] [-v] [--tunnel-server <value>] [--agent-id <value>] [--app-name
<value>] [--username <value>] [--password <value>] [--stat-url <value>]
[--select <value>] [--disabled-commands <value>] [pid]

Bootstrap Arthas

EXAMPLES:
java -jar arthas-boot.jar <pid>
java -jar arthas-boot.jar --telnet-port 9999 --http-port -1
java -jar arthas-boot.jar --username admin --password <password>
java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws'
--app-name demoapp
java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws'
--agent-id bvDOe8XbTM2pQWjF4cfw
java -jar arthas-boot.jar --stat-url 'http://192.168.10.11:8080/api/stat'
java -jar arthas-boot.jar -c 'sysprop; thread' <pid>
java -jar arthas-boot.jar -f batch.as <pid>
java -jar arthas-boot.jar --use-version 3.7.1
java -jar arthas-boot.jar --versions
java -jar arthas-boot.jar --select math-game
java -jar arthas-boot.jar --session-timeout 3600
java -jar arthas-boot.jar --attach-only
java -jar arthas-boot.jar --disabled-commands stop,dump
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
WIKI:
https://arthas.aliyun.com/doc

Options and Arguments:
-h,--help Print usage
--target-ip <value> The target jvm listen ip, default 127.0.0.1
--telnet-port <value> The target jvm listen telnet port, default
3658
--http-port <value> The target jvm listen http port, default 8563
--session-timeout <value> The session timeout seconds, default 1800
(30min)
--arthas-home <value> The arthas home
--use-version <value> Use special version arthas
--repo-mirror <value> Use special remote repository mirror, value is
center/aliyun or http repo url.
--versions List local and remote arthas versions
--use-http Enforce use http to download, default use
https
--attach-only Attach target process only, do not connect
-c,--command <value> Command to execute, multiple commands
separated by ;
-f,--batch-file <value> The batch file to execute
--height <value> arthas-client terminal height
--width <value> arthas-client terminal width
-v,--verbose Verbose, print debug info.
--tunnel-server <value> The tunnel server url
--agent-id <value> The agent id register to tunnel server
--app-name <value> The app name
--username <value> The username
--password <value> The password
--stat-url <value> The report stat url
--select <value> select target process by classname or
JARfilename
--disabled-commands <value> disable some commands
<pid> Target pid

选择应用 java 进程:

$ $ java -jar arthas-boot.jar
* [1]: 26125
[2]: 33682 demo.jar

当启动了 arthas 却没有检测到 Java 进程时,我们可以先查到 Java 进程的进程 ID .

java -jar arthas-boot.jar
[INFO] JAVA_HOME: /usr/local/jdk8u152-x64/jdk1.8.0_152/jre
[INFO] arthas-boot version: 3.7.1
[INFO] Can not find java process. Try to run `jps` command lists the instrumented Java HotSpot VMs on the target system.
Please select an available pid.
java -jar arthas-boot.jar <pid>

2. 查看 dashboard

输入 dashboard ,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。

$ dashboard
ID NAME GROUP PRIORI STATE %CPU TIME INTERRU DAEMON
17 pool-2-thread-1 system 5 WAITIN 67 0:0 false false
27 Timer-for-arthas-dashb system 10 RUNNAB 32 0:0 false true
11 AsyncAppender-Worker-a system 9 WAITIN 0 0:0 false true
9 Attach Listener system 9 RUNNAB 0 0:0 false true
3 Finalizer system 8 WAITIN 0 0:0 false true
2 Reference Handler system 10 WAITIN 0 0:0 false true
4 Signal Dispatcher system 9 RUNNAB 0 0:0 false true
26 as-command-execute-dae system 10 TIMED_ 0 0:0 false true
13 job-timeout system 9 TIMED_ 0 0:0 false true
1 main main 5 TIMED_ 0 0:0 false false
14 nioEventLoopGroup-2-1 system 10 RUNNAB 0 0:0 false false
18 nioEventLoopGroup-2-2 system 10 RUNNAB 0 0:0 false false
23 nioEventLoopGroup-2-3 system 10 RUNNAB 0 0:0 false false
15 nioEventLoopGroup-3-1 system 10 RUNNAB 0 0:0 false false
Memory used total max usage GC
heap 32M 155M 1820M 1.77% gc.ps_scavenge.count 4
ps_eden_space 14M 65M 672M 2.21% gc.ps_scavenge.time(m 166
ps_survivor_space 4M 5M 5M s)
ps_old_gen 12M 85M 1365M 0.91% gc.ps_marksweep.count 0
nonheap 20M 23M -1 gc.ps_marksweep.time( 0
code_cache 3M 5M 240M 1.32% ms)
Runtime
os.name Mac OS X
os.version 10.13.4
java.version 1.8.0_162
java.home /Library/Java/JavaVir
tualMachines/jdk1.8.0
_162.jdk/Contents/Hom
e/jre

3. 通过 thread 命令来获取到 demo 进程的 Main Class

thread 1会打印线程 ID 1 的栈,通常是 main 函数的线程。

$ thread 1 | grep 'main('
at demo.MathGame.main(MathGame.java:17)

4. 通过 jad 来反编译某个类

比如 Spring 生成的某个代理对象

$ jad com.demo.Bean1$$EnhancerBySpringCGLIB$$5974b8b5

5. 退出 arthas

如果只是退出当前的连接,可以用quit或者exit命令。Attach 到目标进程上的 arthas 还会继续运行,端口会保持开放,下次连接时可以直接连接上。

如果想完全退出 arthas,可以执行stop命令。

命令列表

1. jvm 相关指令

  • dashboard - 当前系统的实时数据面板
  • getstatic - 查看类的静态属性
  • heapdump - dump java heap, 类似 jmap 命令的 heap dump 功能
  • jvm - 查看当前 JVM 的信息
  • logger - 查看和修改 logger
  • mbean - 查看 Mbean 的信息
  • memory - 查看 JVM 的内存信息
  • ognl - 执行 ognl 表达式
  • perfcounter - 查看当前 JVM 的 Perf Counter 信息
  • sysenv - 查看 JVM 的环境变量
  • sysprop - 查看和修改 JVM 的系统属性
  • thread - 查看当前 JVM 的线程堆栈信息
  • vmoption - 查看和修改 JVM 里诊断相关的 option
  • vmtool - 从 jvm 里查询对象,执行 forceGc

2.基础命令

  • base64 - base64 编码转换,和 linux 里的 base64 命令类似
  • cat - 打印文件内容,和 linux 里的 cat 命令类似
  • cls - 清空当前屏幕区域
  • echo - 打印参数,和 linux 里的 echo 命令类似
  • grep - 匹配查找,和 linux 里的 grep 命令类似
  • help - 查看命令帮助信息
  • history - 打印命令历史
  • keymap - Arthas 快捷键列表及自定义快捷键
  • pwd - 返回当前的工作目录,和 linux 命令类似
  • quit - 退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • reset - 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • session - 查看当前会话的信息
  • stop - 关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • tee - 复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似
  • version - 输出当前目标 Java 进程所加载的 Arthas 版本号

3.class/classloader 相关

  • classloader - 查看 classloader 的继承树,urls,类加载信息,使用 classloader 去 getResource
  • dump - dump 已加载类的 byte code 到特定目录
  • jad - 反编译指定已加载类的源码
  • mc - 内存编译器,内存编译.java文件为.class文件
  • redefine - 加载外部的.class文件,redefine 到 JVM 里
  • retransform - 加载外部的.class文件,retransform 到 JVM 里
  • sc - 查看 JVM 已加载的类信息
  • sm - 查看已加载类的方法信息

4.monitor/watch/trace 相关

❝

注意 请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 stop 或将增强过的类执行 reset 命令。

❞
  • monitor - 方法执行监控
  • stack - 输出当前方法被调用的调用路径
  • trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时
  • tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
  • watch - 方法执行数据观测

5.profiler/火焰图

  • profiler - 使用async-profiler对应用采样,生成火焰图
  • jfr - 动态开启关闭 JFR 记录

6.管道

Arthas 支持使用管道对上述命令的结果进行进一步的处理,如sm java.lang.String * | grep 'index'

  • grep - 搜索满足条件的结果
  • plaintext - 将命令的结果去除 ANSI 颜色
  • wc - 按行统计输出结果

7.后台异步任务

当线上出现偶发的问题,比如需要 watch 某个条件,而这个条件一天可能才会出现一次时,异步后台任务就派上用场了,详情请参考这里

  • 使用 > 将结果重写向到日志文件,使用 & 指定命令是后台运行,session 断开不影响任务执行(生命周期默认为 1 天)
  • jobs - 列出所有 job
  • kill - 强制终止任务
  • fg - 将暂停的任务拉到前台执行
  • bg - 将暂停的任务放到后台执行

Arthas IDEA 插件

  • etbrains 插件获取地址:https://plugins.jetbrains.com/plugin/13581-arthas-idea
  • 用文档:https://www.yuque.com/arthas-idea-plugin
  • 码地址:https://github.com/WangJi92/arthas-idea-plugin

下载 Plugin :

鼠标右键使用,可以快速复制得到 Arthas 命令:

trace io.grpc.Context *  -n 5 --skipJDKMethod false 

watch io.grpc.Context * '{params,returnObj,throwExp}' -n 5 -x 3

stack io.grpc.Context * -n 5

monitor io.grpc.Context * -n 10 --cycle 10

sc -d io.grpc.Context

sm io.grpc.Context *

jad --source-only io.grpc.Context

heapdump /tmp/dump.hprof

thread -i 3000 -n 5

看完本文有收获?转发给更多的朋友吧

DevXTalk 不止于技术

原文作者:DevXTalk;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-03-23

  • 博文量
    178
  • 访问量
    82582