在使用 Arthas 之前,当遇到 Java 线上问题时,如 CPU 飙升、负载突高、内存溢出等问题,你需要查命令,查网络,然后 jps、jstack、jmap、jhat、jstat、hprof 等一通操作。最终焦头烂额,还不一定能查出问题所在。而现在,大多数的常见问题你都可以使用 Arthas 轻松定位,迅速解决,及时止损,准时下班。
但是作为性能测试工作者,我不可能像开发人员一样,满足于Arthas在单机调试和监视方面的使用,我肯定经常需要在测试项目中跨服务器调用,甚至分布式调用。由于网上有关介绍Arthas远程监视的文章比较少(关键有的文章写的太复杂,我也看不明白),所以我自己专门花了一天时间研究了一下,写出以下的使用说明:
Arthas 是阿里开源 Java 诊断工具。支持 JDK6+, 采用命令行交互模式,提供 Tab 自动不全,可以方便的定位和诊断线上程序运行问题。Arthas 官方文档十分详细,本文部分参考了官方文档内容,同时在开源在的 Github 的项目里也有大量的使用案例,也可以进行学习参考。
开源地址:https://github.com/alibaba/arthas
官方文档:https://alibaba.github.io/arthas
得益于 Arthas 强大且丰富的功能,让 Arthas 能做的事情超乎想象。下面仅仅列举几项常见的使用情况,更多的使用场景可以在熟悉了 Arthas 之后自行探索。
前文已经提到,Arthas 是一款命令行交互模式的 Java 诊断工具,由于是 Java 编写,所以可以直接下载相应 的 jar 包运行。
可以在官方 Github 上进行下载,如果速度较慢,可以尝试国内的码云 Gitee 下载。
# github下载
wget https://alibaba.github.io/arthas/arthas-boot.jar
# 或者 Gitee 下载
wget https://arthas.gitee.io/arthas-boot.jar
Arthas 只是一个 java 程序,所以可以直接用 java -jar
运行。运行时或者运行之后要选择要监测的 Java 进程。
本地访问的运行方式(默认方式,进入本地console访问):
# 运行方式1,先运行,在选择 Java 进程 PID
java -jar arthas-boot.jar
# 选择要监控的JAVA进程(输入[]内编号1、2(不是PID)回车)
[INFO] arthas-boot version: 3.3.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 94098 /mnt/zfbb/zfbb-app-1.0-SNAPSHOT.jar
[2]: 20766 SpringBlade.jar
# 运行方式2,运行时直接指定要监控的 Java 进程 PID
java -jar arthas-boot.jar [PID]
远程访问的运行方式(通过URL访问):
# target-ip 要用对外能被访问到的IP
java -jar arthas-boot.jar --target-ip 172.16.1.133
# 然后是选择被监控JAVA进程,和本地模式一样,注意端口3658的连接
# arthas-client connect 172.16.1.133 3658
另外如果下载的是完整包(arthas-x.x.x-bin.zip),自带有启动脚本as.sh(windows下是as.bat),启动命令样如如下:
EXAMPLES:
./as.sh
./as.sh --target-ip 0.0.0.0
./as.sh --telnet-port 9999 --http-port -1
./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws'
./as.sh --tunnel-server 'ws://192.168.10.11:7777/ws' --agent-id bvDOe8XbTM2pQWjF4cfw
./as.sh --stat-url 'http://192.168.10.11:8080/api/stat'
./as.sh -c 'sysprop; thread'
./as.sh -f batch.as
./as.sh --use-version 3.3.3
./as.sh --session-timeout 3600
./as.sh --attach-only
./as.sh --select arthas-demo
./as.sh --repo-mirror aliyun --use-http
以上举例的是linux环境的运行命令,其实windows下是一样的,在CMD窗口就能运行,但是要注意的是很多人的Windows是没有装Telnet命令,自己要知道这一点,装windows自带的Telnet客户端就行(不装肯定启动报错,本地console也靠telnet连接的) 。
注意(很多人踩坑):按默认启动arthas进程后,就会开启两个端口 3658(Server默认端口,通过telnet访问,可用--telnet-port 修改)和 8563(http默认端口,通过浏览器访问,可用 --http-port 修改),这两监听端口都会绑定到待监控的JAVA进程上,如下所示,全都绑定到了 PID=94098 上:
而要开启arthas的远程访问模式,必须确保 3658 和 8563 端口不被占用,如果原来已开启了arthas本地访问模式,必须在console (控制台)模式下先stop停止服务(推荐方式),或者直接杀掉我们所监控的pid=94098进程也能完全退出Arthas,然后再开启arthas的远程访问方式(另外要实现对外访问,必须在防火墙里放开 8563 端口)。否则,随意切换到远程访问方式启动arthas,可能就直接报错了:
一旦采用远程访问方式,如果还想在本地打开console操作,同样也必须通过 java -jar arthas-boot.jar --target-ip 172.16.1.133 的方式连接并进入操作。
总结:
只要是按上面提到的远程访问方式运行,就支持webConsole访问,通过浏览器http访问8563端口,但注意的是,页面上IP也必须指定服务端的IP,不能用默认的127.0.0.1(这是不方便地方,按理服务端都指定IP了,客户端就不应该让人再输一遍),如下:
注意:可能webConsole是浏览器以websocket方式连接的,如果长时间不连接,就会自动断开(8563端口会自动切断,需要重新开启),这时候还可以用telnet连接,因为3658端口是服务端口,只要不停止arthas,就会一直连通。
由于webConsole时间长了不连接就会自动断开了(估计是两小时),这时候就不能用http连接了,但还是支持通过telnet连接,在CMD中,通过telnet命令连接(默认没有的就装一下,windows系统自带的但默认没启用)或是装第三方Telnet工具:
C:\Users\A>telnet 172.16.1.133 3658
上面的远程方式,有个缺点,就是每次都要连到被监控的机器,开启arthas,并指定要监控的JAVA进程,这些操作,出于安全考虑,可能用户现场都不让你操作(你都要时不时的连人家机器了,还叫什么远程监控)。这时候就要考虑下面的tunnel server的方案:
https://alibaba.github.io/arthas/web-console.html#arthas-tunnel-serverarthas
1.下载部署arthas tunnel server
https://github.com/alibaba/arthas/releases
2. Arthas tunnel server是一个spring boot fat jar应用,直接java -jar
启动:
nohup java -jar arthas-tunnel-server-3.3.3.jar --server.port=8888 > output.log 2>&1 &
默认情况下,arthas tunnel server的web端口是8080(
我们可以指定成8888端口,以免和别的系统冲突)
,arthas agent连接的端口是7777(
如果要修改可以打开解压包,拽出application.properties文件,重新指定端口)
。
3. 启动arthas,注册到tunnel server,并指定一个agent-id:mytest123456(默认是随机产生):
java -jar arthas-boot.jar --tunnel-server 'ws://172.16.1.133:7777/ws' --agent-id mytest123456
然后根据提示选择要监控的Java进程:
[INFO] arthas-boot version: 3.3.3
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER.
* [1]: 99057 /mnt/zfbb/zfbb-app-1.0-SNAPSHOT.jar
[2]: 102928 SpringBlade.jar
[3]: 34759 arthas-tunnel-server-3.3.3.jar
1
[INFO] arthas home: /root/.arthas/lib/3.3.3/arthas
[INFO] Try to attach process 99057
[INFO] Attach process 99057 success.
[INFO] arthas-client connect 127.0.0.1 3658
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://alibaba.github.io/arthas
tutorials https://alibaba.github.io/arthas/arthas-tutorials
version 3.3.3
pid 99057
time 2020-06-11 13:29:19
id mytest123456
当我们看到最后的id mytest123456,就表示agent注册成功。
4. 启动之后,可以访问 http://{yourIP}:8888/,再通过agentId
连接到已注册的arthas agent上:
5. 另外通过Spring Boot的Endpoint,可以查看到具体的连接信息: http://{yourIP}:8888/actuator/arthas,登陆用户名是arthas
,密码在arthas tunnel server的日志里可以找到,比如:
登录后,就能看到都有哪些agentId
注册上来,这样我们可选择性的连接:
看到这我们就明显了,arthas tunnel server和arthas agents是可以分布式部署的,相当于通过tunnel server可以把很多arthas实例管理起来,想连哪个就连哪个(而且不用担心断开,后续可以自动重连成功)。目前在Linux下测试都非常顺利,而将widnows下的agent注册到server端多少会因为防火墙或杀毒软件的影响不太顺利(毕竟依赖于telnet通信)。
另外我们启动arthas,也可以按以下方式,明确IP为agent-id(方便识别),同时明确target-ip(可以同时支持telnet方式和tunnel web-console方式连接),最后再带上要监控的进程号,如下所示:
java -jar arthas-boot.jar --tunnel-server 'ws://172.16.1.133:7777/ws' --target-ip 172.16.1.53 --agent-id 172.16.1.53 99057
这样通过IP就能记住agent-id,省得容易忘记还要通过 session命令重连来获取 agentId。
另外关于分布远程连接,arthas社区里也有人提供了一些解决方案,比如《Arthas Web-Console一站式解决方案》
最后放一张arthas tunnel server的架构示意图,有助于我们理解tunnel server和arthas agent的关系,如下所示:
先写到这吧,本来还打算写点使用心得(以后的吧)。这工具在定位和分析Java性能方面确实挺方便,但是很多开发人员对这个工具的熟悉程度肯定比我这个测试人员高多了,所以我属于班门弄虎了。
基础命令
help——查看命令帮助信息
cls——清空当前屏幕区域
session——查看当前会话的信息
reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
version——输出当前目标 Java 进程所加载的 Arthas 版本号
quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
stop ——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
keymap——Arthas快捷键列表及自定义快捷键
jvm相关
dashboard——当前系统的实时数据面板;例子:dashboard -n 10
thread——查看当前 JVM 的线程堆栈信息;例子:thread [pid](常指定pid线程),thread -n 5(CPU最高的五个线程)
jvm——查看当前 JVM 的信息
sysprop——查看和修改JVM的系统属性
getstatic——查看类的静态属性;例子:getstatic demo.MathGame random
class/classloader相关
sc——查看JVM已加载的类信息;支持通配符 sc *server*
sm——查看已加载类的方法信息;支持通过配符 sm *server*
dump——dump 已加载类的 byte code 到特定目录;例子:dump *StringUtils
redefine——加载外部的.class文件,redefine到JVM里;例子:redefine /tmp/Test.class
jad——反编译指定已加载类的源码(或类中方法的源码);例子:jad java.lang.String toString
classloader——查看classloader的继承树,urls,类加载信息,使用classloader去getResource
monitor/watch/trace相关
monitor——方法执行监控;例子(要指定类名和方法名):monitor org.apache.commons.lang.StringUtils isBlank
watch——方法执行数据观测;例子:watch org.apache.commons.lang.StringUtils isBlank '{params, returnObj}' -x 2
trace——方法内部调用路径,并输出方法路径上的每个节点上耗时;例子:trace *.commons.lang.StringUtils isBlank
stack——输出当前方法被调用的调用路径;例子:stack org.apache.commons.lang.StringUtils isBlank
tt——方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测;例子:tt -t *.commons.lang.StringUtils isEmpty
请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 shutdown 或将增强过的类执行 reset 命令(因为线上不能随便重启服务,通过reset可以清理内存中的增加类信息)。
options
options——查看或设置Arthas全局开关;注意设置全局配置有风险(比如引起服务进程异常退出)。
管道
Arthas支持使用管道对上述命令的结果进行进一步的处理,如:sm org.apache.log4j.Logger | grep getLogger
grep——搜索满足条件的结果
plaintext——将命令的结果去除颜色
wc——按行统计输出结果
转载请注明来源smooth的博客:https://smooth.blog.csdn.net/