前言

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. Shel脚本-初步入门之《05》

    Shel脚本-初步入门-05 常用操作系统默认的 Shell 5.常用操作系统默认的 Shell 通过以下两种方法可以查看 CentOS Linux 系统默认的 Shell 方法1: echo $SH ...

  2. router-link路由传参

    router-link传参 [注意] 1.使用params方式传参时,只支持name跳转: 案例如下: 2.使用query传参,注意:两种都支持 案例如下 .

  3. Nginx的负载均衡配置(七)

    原文链接:https://www.cnblogs.com/knowledgesea/p/5199046.html 首先给大家说下upstream这个配置的,这个配置是写一组被代理的服务器地址,然后配置 ...

  4. 【使用篇二】SpringBoot热部署(11)

    热部署有三种方式: SpringLoader 插件 DevTools 工具 安装JRebel插件 注意:热部署的功能依赖于工具的自动编译,Eclipse-->Build Automaticall ...

  5. svn服务器端程序安装(二)

    1.下载 Setup-Subversion-1.8.9-1.msi 2. 双击,一直next (1) 修改安装地址,要求是非中文无空格 3. 安装完成后,检查是否已添加到系统的环境变量PATH中,若没 ...

  6. mybatis框架之多参数入参--传入Map集合

    需求:查询出指定性别和用户角色列表下的用户列表信息 实际上:mybatis在入参的时候,都是将参数封装成为map集合进行入参的,不管你是单参数入参,还是多参数入参,都是可以封装成map集合的,这是无可 ...

  7. VIJOS-P1325 桐桐的糖果计划

    VIJOS-P1325 桐桐的糖果计划 JDOJ 1432 桐桐的糖果计划 https://neooj.com/oldoj/problem.php?id=1432 Description 桐桐很喜欢吃 ...

  8. Spring事务异常rollback-only 笔记

    造成以上异常的原因情形: 在spring里面我们配置了事务的传播机制是REQUIRED,所以这两个事务最终会合并成一个事务.当a方法调用b方法时,程序中a方法中由于某某原因导致抛出异常(或者明确将该事 ...

  9. SpringBoot中的日志

    默认情况下,Spring Boot会用SLF4J + Logback来记录日志,并用INFO级别输出到控制台. SLF4J,即简单日志门面(Simple Logging Facade for Java ...

  10. 公司ES升级带来的坑怎么填?

    前言 公司的ES最近需要全部进行升级,目的是方便维护和统一管理.以前的版本不统一,这次准备统一升级到一个固定的版本. 同时还会给ES加上权限控制,虽然都是部署在内网,为了防止误操作,加上权限还是有必要 ...