greys(https://github.com/oldmanpushcart/greys-anatomy)是一款使用非常方便的JVM在线诊断工具,比BTrace学习成本低不少,能够观察到的信息也丰富,感觉它是Java线上调试的一大利器。
(更新:阿里官方又推出了arthus,和greys类似,操作更友好~)
今天帮别人在服务器上用greys排查线上web服务的问题,先说说安装启动的一些问题:
首先安装完后执行./greys.sh就报错:
illegal ENV, please set $JAVA_HOME to JDK6+
表明缺少JAVA_HOME环境变量,需要JDK1.6以上。用which java看到执行路径为/bin/java
继续看软连接后的真实路径:
命令行截图
然后设置环境变量export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.141-2.6.10.1.el7_3.x86_64/jre
再次启动greys,仍然报错了:
start greys failed, because : com.sun.tools.attach.VirtualMachineDescriptor
异常信息应该表明缺少这个类,该类存在于JDK下/lib/tools.jar中,而JRE中没有,只能再安装JDK环境,并且重新配置JAVA_HOME。
第三次次启动greys,依旧报错:
start greys failed, because : instrument library is missing in target VM
说明被代理的JVM启动程序不是JDK下的。这时需要重启服务进程,是否影响线上业务就需要自行权衡了。重启之后就能正常使用greys了。
再说说我常用的几个命令:
1. trace
github上使用的参考结果:
ga?>trace com.alibaba.manager.DefaultAddressManager toStringPass2
Press Ctrl+D to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 19 ms.
`---+Tracing for : thread_name="agent-test-address-printer" thread_id=0xb;is_daemon=false;priority=5;
`---+[0,0ms]com.alibaba.manager.DefaultAddressManager:toStringPass2()
+---[0,0ms]com.alibaba.Address:getAddressId()
+---[0,0ms]com.alibaba.Address:getAddressId()
+---[0,0ms]java.lang.Integer:valueOf()
+---[0,0ms]com.alibaba.Address:getAddressName()
主要用来监控方法执行时间,我常用来排查一些IO或线程阻塞问题。
2. watch
参考结果:
ga?>watch -b *Test printAddress '"params[0]="+params[0]'
Press Ctrl+D to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 32 ms.
params[0]=3163
params[0]=3164
这个是用来观察方法入参。
ga?>watch -s com.alibaba.manager.DefaultAddressManager newAddress returnObj -x 1
Press Ctrl+D to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 34 ms.
@Address[
username=@String[dukun],
addressId=@Integer[3244],
addressName=@String[ADDRESS],
]
这个是用来观察方法返回结果。
3. tt
参考结果:
ga?>tt -t -n 3 *Test printAddress
Press Ctrl+D to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 33 ms.
+----------+------------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| INDEX | PROCESS-ID | TIMESTAMP | COST(ms) | IS-RET | IS-EXP | OBJECT | CLASS | METHOD |
+----------+------------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1036 | 1009 | 2015-12-06 16:57:06 | 1 | false | true | 0x2062a3d | AgentTest | printAddress |
+----------+------------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1037 | 1010 | 2015-12-06 16:57:07 | 0 | false | true | 0x2062a3d | AgentTest | printAddress |
+----------+------------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
watch命令的参数比较多,这个命令比较简单,可以把方法调用现场的信息都显示出来。
这些命令具体的参数和表达式写法可以参考github上的使用说明。
网友评论