前言

Arthas 是Alibaba开源的Java诊断工具。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。对分秒必争的线上异常,Arthas可帮助我们快速诊断相关问题。

下载安装

下载Arthasarthas-boot.jar

wget https://alibaba.github.io/arthas/arthas-boot.jar

下载arthas之后,先来了解帮助信息,可以通过java -jar arthas-boot.jar -h命令查看,这里给出了一些例子和参数说明

[root@izwz94a0v1sz0gk4rezdcbz arthas]# java -jar arthas-boot.jar -h
[INFO] arthas-boot version: 3.1.4
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>] [--stat-url
<value>] [pid] Bootstrap Arthas EXAMPLES:
java -jar arthas-boot.jar <pid>
java -jar arthas-boot.jar --target-ip 0.0.0.0
java -jar arthas-boot.jar --telnet-port 9999 --http-port -1
java -jar arthas-boot.jar --tunnel-server 'ws://192.168.10.11:7777/ws'
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.1.4
java -jar arthas-boot.jar --versions
java -jar arthas-boot.jar --session-timeout 3600
java -jar arthas-boot.jar --attach-only
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
WIKI:
https://alibaba.github.io/arthas 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 maven 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
--stat-url <value> The report stat url
<pid> Target pid

启动

启动arthas之前,先启动一个springboot的应用。该demo在地址https://github.com/yangtao...

java -jar ytao-springboot-demo.jar

启动arthas-boot.jar命令

java -jar arthas-boot.jar

这里注意需要启动demoarthas使用同一权限用户,否则使用attach机制获取不到进程信息(这里刚使用时没注意,遇到过这个问题)。

例:root用户启动 demou1用户启动arthas时,打印信息 Can not find java process. Try to pass <pid> in command line.

查看源码,在获取进程之后,添加日志输出。结果为空,返回-1,判断结果小于0时,直接退出。

启动类Bootstrap#main的代码

进程工具类ProcessUtils#select的代码

通过上面也分析到,我们启动arthas之前,必须要先启动我们的目标进程,否则arthas可能无法启动。

使用root用户启动成功界面

选择java进程,这里我们的ytao-springboot-demo是 1,选择后会有连接信息

[INFO] arthas home: /root/.arthas/lib/3.1.4/arthas
[INFO] Try to attach process 22005
[INFO] Attach process 22005 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.1.4
pid 17339
time 2019-10-17 02:29:06

dashboard 数据面板

使用dashboard命令,可以查看线程,内存,GC,以及Runtime信息

jad 反编译

有时我们会遇到线上代码运行结果不是我们期望的结果,有种情况就是线上代码不是我们想要的版本,但是要查看的话,需要下载后再进行反编译。

这时arthasjad可以帮助我们线上进行即时反编译,确认代码是否符合我们的版本。

jad com.ytao.service.UserServiceImpl

watch 函数执行信息

使用watch命令可以查看函数的执行信息。watch的参数列表(来自官网)

参数 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
express 观察表达式
condition-express 条件表达式
[b] 在方法调用之前观察
[e] 在方法异常之后观察
[s] 在方法返回之后观察
[f] 在方法结束之后(正常返回和异常返回)观察
[E] 开启正则表达式匹配,默认为通配符匹配
[x:] 指定输出结果的属性遍历深度,默认为 1

当我们遇到线上数据bug时,我们一般处理的手段就是开发环境模拟线上数据,从生产日志中查找线索,再或者远程debug。以上不管哪种排查手段,相对都是比较麻烦。

这时Arthas的watch可以帮助我们查看实时的代码执行情况。使用观察表达式可以查看函数的参数,返回值,异常信息。观察表达式主要由OGNL表达式组成,所以可以编写OGNL表达式来执行。

观察表达式的变量

变量 变量说明
params 函数的入参
returnObj 函数的返回值
throwExp 异常信息
target 当前对象

查看一个函数的入参和返回值

watch com.ytao.service.UserServiceImpl getUser "{params,returnObj}"

打印信息isEmpty=false;size=1可以看到参数为非空,参数数量为一个。查看具体入参信息

watch com.ytao.service.UserServiceImpl getUser "{params[0],returnObj}"

查看异常信息

watch com.ytao.service.UserServiceImpl getUser "throwExp"

当我们传入一个参数为-1时,打印出我们定义的非法参数异常

watch除了观察表达式外,还能使用条件表达式,以及观察事件点

注意使用观察事件点时,有些观察表达式的变量不一定存在,比如使用-b时,返回值和异常信息都为空。

有时我们排查某个函数,不能马上获取到函数的信息,arthas给提供的后台异步任务可以帮助我们记录日志。使用方式和Linux的类似。

watch com.ytao.service.UserServiceImpl getUser "{params,returnObj}" > /log/w.log &

查看异步保存的日志

tt 定位异常调用

上面所介绍的watch可以排查函数的调用情况,比较适用在已知当次调用可能存在的情况后,查看信息。如果一个函数调用n次后,有几次为执行异常,我们要去找出这些异常的调用,在watch中排查就不怎么方便了。

使用tt命令可以较方便查看异常的调用及信息。对com.ytao.service.UserServiceImpl#getUser的函数查看,-t是每次调用该函数都会记录

tt -t com.ytao.service.UserServiceImpl getUser

记录信息

查看所有记录

tt -l

查看指定函数记录

tt -s 'method.name=="getUser"'

输出信息说明

表格字段 字段解释
INDEX 时间片段记录编号,每一个编号代表着一次调用,后续tt还有很多命令都是基于此编号指定记录操作,非常重要。
TIMESTAMP 方法执行的本机时间,记录了这个时间片段所发生的本机时间
COST(ms) 方法执行的耗时
IS-RET 方法是否以正常返回的形式结束
IS-EXP 方法是否以抛异常的形式结束
OBJECT 执行对象的hashCode(),注意,曾经有人误认为是对象在JVM中的内存地址,但很遗憾他不是。但他能帮助你简单的标记当前执行方法的类实体
CLASS 执行的类名
METHOD 执行的方法名

从上面参数中我们看到1003调用是以抛异常的形式结束,因为tt会记录每次调用的信息,所以我们可以查看1003的详细信息

tt -i 1003

trace 查看调用链路

我们常会遇到调用某个api时rt过长,我们就要找出调用链上的某个或几个函数进行优化,我们通常定位几个可能的锚点,打印各个锚点间的rt。或者从日志中找出日志打印的时间点计算出时间差,不管使用哪种方法都比较繁琐。当使用arthastrace命令可以轻松的完成我们的需求。

trace参数说明

参数 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
condition-express 条件表达式
[E] 开启正则表达式匹配,默认为通配符匹配
[n:] 命令执行次数
#cost 方法执行耗时

使用trace输出com.ytao.controller.UserController#getUser的信息

trace com.ytao.service.UserServiceImpl getUser

输出结果

在实际使用使用排查过程中,为了减少无用信息的输出,我们一般会使用#cost过滤耗时不长和jdk自带的函数,可以忽略的调用,减少信息的输出。例如:过滤掉小于1ms的调用

trace com.ytao.service.UserServiceImpl getUser  '#cost > 1'

redefine 实现热部署

当我们查找出bug,想要快速上线拯救苍生的时候,Arthas为我们准备了redefine命令来实现热更新。

尽管现在都在倡导jad/mc/redefine热更一条龙,但是线上代码建议本地编译好后再进行替换,避免手误操作。

首先先在UserServiceImpl中添加一行代码

获取classLoaderHash,通过sc命令获取类的信息

sc -d *UserServiceImpl

执行redefine修改的类

redefine -c 1d56ce6a /usr/local/jar/UserServiceImpl.class

通过打印的信息验证是否更新UserServiceImpl

Arthas的使用,除了上文中所讲解到的,还有一些其他的诊断功能,这只是我个人使用的方法。但是使用该类工具一定要有套组合拳,对排查问题过程中,遇到问题有对应的排查手段,并非盲目排查。

个人博客: https://ytao.top

我的公众号 ytao

Java诊断利器Arthas优雅排查生产环境的更多相关文章

  1. Alibaba Java Diagnostic Tool Arthas/Alibaba Java诊断利器Arthas

    Arthas 用户文档 — Arthas 3.1.0 文档https://alibaba.github.io/arthas/ alibaba/arthas: Alibaba Java Diagnost ...

  2. Java诊断利器Arthas

    1 简介 Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 这个类从哪个 jar 包加载的?为什么会报各种类相关的 ...

  3. 带你上手阿里开源的 Java 诊断利器:Arthas

    本文适合有 Java 基础知识的人群. 本文作者:HelloGitHub-秦人 HelloGitHub 推出的<讲解开源项目>系列,今天给大家带来一款阿里开源的 Java 诊断利器 Art ...

  4. Java 诊断工具 Arthas 教程学习笔记

    Java 诊断利器 Arthas,是阿里的一款开源工具.Github-alibaba/arthas 上可以看到它的介绍.了解它,主要是最近对分析 Java 错误堆栈比较感兴趣,机缘巧合看到了它. 本文 ...

  5. java 诊断工具——Arthas

    该说不说!小编做的这些功能,最讨厌的就是优化!某些前辈大佬写的代码小辈我实在不敢恭维!那逻辑!那sql! 接下来!今天的主角就登场了,阿里巴巴最近开源出来的一个针对 java 的工具,主要是针对 ja ...

  6. Alibaba Java诊断工具Arthas之快速安装和简单使用

    Alibaba Java诊断工具Arthas简单介绍 : 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决: 1.这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception ...

  7. Java诊断工具Arthas

    Java诊断工具Arthas 1. Arthas简介 Arthas是阿里开源的一个线上java诊断工具,发现阿里还是挺喜欢开源一些技术的,造福人类.昨天试用了一下,发现真是强大,解决了我工作两年的很多 ...

  8. 【Java】15分钟快速体验阿里Java诊断工具Arthas

    [墙裂推荐]15分钟快速体验阿里Java诊断工具Arthas : https://alibaba.github.io/arthas/arthas-tutorials?language=cn&i ...

  9. Alibaba Java诊断工具Arthas查看Dubbo动态代理类

    原创/朱季谦 阅读Dubbo源码过程中,会发现,Dubbo消费端在做远程调用时,默认通过 Javassist 框架为服务接口生成动态代理类,接着再去调用代理类实现远程接口调用.在阅读这部分源码时,最后 ...

随机推荐

  1. JS中key-value存取

    获取Key 在代码中,遇到需要单独提取对象的key值时可使用 Object.keys(object) object是你需要操作的对象Object.keys()会返回一个存储对象中所有key值的数组获取 ...

  2. 201871010105-曹玉中《面向对象程序设计(java)》第十三周学习总结

    201871010105-曹玉中<面向对象程序设计(java)>第十三周学习总结 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ ...

  3. 【作用域】词法作用域(静态作用域,如:js)、动态作用域(如:.bash脚本)

    作用域 作用域是指程序源代码中定义变量的区域. 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限. JavaScript 采用词法作用域(lexical scoping),也就是静态作 ...

  4. 每天一道Rust-LeetCode(2019-06-14)

    每天一道Rust-LeetCode(2019-06-14) 常数时间插入.删除和获取随机元素 坚持每天一道题,刷题学习Rust. 题目描述 https://leetcode-cn.com/proble ...

  5. webapi序列化控制

    我们都知道在使用WebApi的时候Controller会自动将Action的返回值自动进行各种序列化处理(序列化为json,xml等),但是如果Controller的自动序列化后的结果不是我们想要的该 ...

  6. Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解

    Happy Birthday, Polycarp! Make Them Odd As Simple as One and Two Let's Play the Words? Two Fairs Bea ...

  7. Linux配置DHCP服务器,DHCP中继配置

    配置dhcp服务器 第一步:配置网卡 第二步: 安装dhcp (需要先构建yum仓库,构建yum仓库的方法在之前的博客里有) 编写dhcp.conf文件 进去以后会出现这个内容 需要执行下面的内容将内 ...

  8. 动态规划 | 对输入进行hash处理的LIS 1045

    把序列M处理为有序序列,并且M不存在的序列要在A中删除. 对A进行了处理之后,执行LIS的操作(O(N^2)复杂度).当然可以优化为对数复杂度的,不过pat不卡这个. LCS解法:动态规划 | 保留重 ...

  9. VC修改本机IP地址

    http://www.vcchar.com/thread-1527-1-1.html 设置IP地址只需要更改注册表中关于适配器的相应设置,但更改后需要重新启动系统才能生效,而AddIPAddress函 ...

  10. [LeetCode] 307. Range Sum Query - Mutable 区域和检索 - 可变

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...