Arthas
概述
Arthas 是 阿里巴巴最近开源出来的一个针对 java 的工具,主要是针对 java 的问题进行诊断。
- 这个工具可以协助你做下面这些事情:
- 这个类是从哪个 jar 包加载而来的?
- 为什么会报各种类相关的 Exception?
- 线上遇到问题无法 debug,难道只能反复通过增加日志再重新发布吗?
- 线上的代码为什么没有执行到这里?是由于代码没有 commit?还是搞错了分支?
- 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现。
- 是否有一个全局视角来查看系统的运行状况?
- 有什么办法可以监控到JVM的实时运行状态?
本文档目前仅用于windows环境。
参考:https://alibaba.github.io/arthas/
下载安装:
https://www.jianshu.com/p/c2d19e4470b6 参考
1.下载地址:
2.下载bin包并解压:
使用:
简单使用:
首先,启动你的tomcat的项目。
打开cmd查看你的tomcat的pid:netstat -ano|findstr 7004
拿到PID以后,切换到Arthas的路径下执行as.bat PID
启动arthas服务,会占用3658 8563 两个端口;已经占用的需要提前释放;然后会弹出一个监控页面。此时执行:dashboard
会出现:整个进程的情况
Ctrl+C也能退出实时刷新。
help——查看命令帮助信息
cat——打印文件内容,和linux里的cat命令类似
pwd——返回当前的工作目录,和linux命令类似
cls——清空当前屏幕区域
session——查看当前会话的信息
reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
version——输出当前目标 Java 进程所加载的 Arthas 版本号
history——打印命令历史
quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
shutdown——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
keymap——Arthas快捷键列表及自定义快捷键
监控命令:
1.monitor: 方法执行监控
monitor 命令是一个非实时返回命令。
实时返回命令是输入之后立即返回,而非实时返回的命令,则是不断的等待目标 Java 进程返回信息,直到用户输入 Ctrl+C 为止。
案例1
每5秒进行检查一次,检查5秒内产生的访问
2.watch: 方法执行数据观测
特别说明:
- watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后
- 4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出
- 这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参
- 当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在
案例1
注:如果需要查看详细的返回值信息,可以设置-x 3增加属性遍历深度默认值为1。
案例2
注:发现入参数量为0,但实际加单是有传递参数的。原因是因为addOrder()方法没有参数。
案例3
案例4
3.tt: 记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。
watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。
这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。
4.options: 全局开关
打开执行结果存日志功能:options save-result true
注:也可以执行以下命令,后台运行内容保存到指定文件
5.getstatic
通过getstatic命令可以方便的查看类的静态属性。使用方法为getstatic
class_name
field_name
如果该静态属性是一个复杂对象,还可以支持在该属性上通过ognl表示进行遍历,过滤,访问对象的内部属性等操作。
性能相关的命令
Stack-输出当前方法被调用的调用路径
stack cn.com.tcsl.canyin.pos.reception.controller.ReceptionBusinessController incrPointList
Jad-反编译class
jad cn.com.tcsl.canyin.pos.reception.controller.ReceptionBusinessController incrPointList
Trace-命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。
[[email protected]]$ trace cn.com.tcsl.canyin.wuu.service.local.CrmService getCrmCardMessage
[[email protected]]$ trace -j cn.com.tcsl.canyin.wuu.service.local.CrmService getCrmCardMessage
过滤 java的自带函数
[[email protected]]$ trace -j cn.com.tcsl.canyin.pos.controller.AddOrderController addOrder 'cost>10'
过滤处理时间超过10ms的请求(整个方法超过10ms)
这里存在一个统计不准确的问题,就是所有方法耗时加起来可能会小于该监测方法的总耗时,这个是由于 Arthas 本身的逻辑会有一定的耗时
Jvm-查看当前 JVM 的信息
Thread-查看当前 JVM 的线程堆栈信息
Thread PID 查看指定线程详细信息
Thread –n 3 输出最忙的N的线程
Thread –b 找出阻塞其它线程的线程
Sysprop-可以打印所有的System Properties信息
[[email protected]]$ sysprop file.encoding 查看单key
sysprop file.encoding UTF-8 修改配置
Sysenv-命令可以获取到环境变量,比如ssh登录的ip等
其他常用指令
Sc-打印api包下所有的类
sc cn.com.tcsl.canyin.pos.*
搜索接口实现类
sc javax.servlet.Filter
查看详细信息
sc -d javax.servlet.Filter
Sm-打印类的详细信息
[[email protected]]$ sm -d cn.com.tcsl.canyin.pos.controller.AddOrderController
打印指定方法的详细信息
sm -d cn.com.tcsl.canyin.pos.controller.AddOrderController addOrder
Ognl-可以动态执行代码
Ognl ognl '@[email protected]("hello ognl")'
Dump- 类似jmap命令的heap dump功能
热部署
jad/mc/redefine线上热更新一条龙
1.将反编译的文件保存到一个指定路径
[[email protected]]$ jad --source-only cn.com.tcsl.canyin.pos.controller.AddOrderController > tmp/AddOrderController.java
这个路径在你的tomcat下。。。。。
2.找到文件对应JVM的classloader
sc -d *AddOrderController | grep classLoaderHash
- 编译修改好的文件,用指定classloader
mc -c 10fe49d6 tmp/TcslCollectionUtil.java -d tmp
如果用jad反编译的文件修改完在编译.class文件总有问题,一但复杂的文件就会各种报错,缺少符号,jar找不到之类的。有说是jad流程有BUG的:
- 执行热部署
使用mc编译后的文件
redefine S:/work/Tomcat/bin/tmp/cn/com/tcsl/framework/common/util/TcslCollectionUtil.class
直接使用编译后文件执行热部署
替换文件的反编译如下:
本地代码如下:
[[email protected]]$ redefine tmp/AddOrderController.class tmp/BizAddOrder.class
热部署不支持新增类和方法,也就是只能update现有的代码。
正在跑的函数,没有退出不能生效。
使用想法:
可以靠java启动。
首先在目前已存在的Listener就够用实在不行就实现HttpServlet走init;方法中调用Process p = Runtime.getRuntime().exec(cmd);
cmd既是查询pid和执行as.bat pid。
远程监控:
参考:https://blog.csdn.net/lang_programmer/article/details/84726303
https://www.cnblogs.com/theRhyme/p/10659265.html
1.被调用端启动Arthas需要使用命令:
java -jar arthas-boot.jar --target-ip 192.168.9.165
--target-ip即监听的端口对外暴露,外部访问使用,你监听IP即可。
2.执行完它会让你选去监听那个PID
可能有多个,你需要选择需要监控的。
启动成功如下:
- 外部访问
另一台机器也需要启动arthas服务并在web页面输入ip即可监控到
另外退出时一定要shutdowm你的arthas服务,不然下次启动报错
Linux上监控
1.首先 curl -L https://alibaba.github.io/arthas/install.sh | sh(下载)
2. ./as.sh(启动)
3.执行完第三行命令后arthas 会自动查找 可以attach的pid 供你选择,然后你选择其前面的数字
4.然后执行dashboard 可以显示该jvm的状况