arthas 线上运维学习笔记

  • Arthas是阿里的一款开源的线上JVM运维工具。开源地址:Github-alibaba/arthas ,最近由于线上问题频繁,但面对庞大的用户量,我们无法做出及时的重启,为此入手Arthas,旨在快速定位线上问题,解决用户困扰

安装

快速安装

  • 使用arthas-boot(推荐)

    下载arthas-boot.jar,然后用java -jar的方式启动:

    wget https://alibaba.github.io/arthas/arthas-boot.jar
    java -jar arthas-boot.jar
    
  • 如果下载速度比较慢,可以使用aliyun的镜像:

    java -jar arthas-boot.jar --repo-mirror aliyun --use-http
    
  • 如果从github下载有问题,可以使用gitee镜像

    wget https://arthas.gitee.io/arthas-boot.jar
    

使用as.sh安装

  • Arthas 支持在 Linux/Unix/Mac 等平台上一键安装

    curl -L https://alibaba.github.io/arthas/install.sh | sh
    
    • 对于as.sh方式,在安装的过程中还需要走互联网,为此对应博主这种企业内网无法联通外部网络的环境下,该方式并不通用

    • 上述命令会下载启动脚本文件 as.sh 到当前目录,你可以放在任何地方或将其加入到 $PATH 中。

    • 直接在shell下面执行./as.sh,就会进入交互界面。也可以执行./as.sh -h来获取更多参数信息。

      • 使用as.sh脚本执行的时候,需要先安装telnet,否则会报错
      arthas 线上运维学习笔记_第1张图片
      1563720118983.png
  • 如果从github下载有问题,可以使用gitee镜像

    curl -L https://arthas.gitee.io/install.sh | sh
    

全量安装

点击下载

  • 下载完成后arthas-packaging-3.1.1-bin解压后,在文件夹里有arthas-boot.jar,直接用java -jar的方式启动:

    java -jar arthas-boot.jar
    
  • 打印帮助信息:

    java -jar arthas-boot.jar -h
    

卸载

  • 在 Linux/Unix/Mac 平台

    rm -rf ~/.arthas/
    rm -rf ~/logs/arthas
    
  • Windows平台直接删除user home下面的.arthaslogs/arthas目录

启动

java -jar arthas-boot.jar --target-ip 0.0.0.0
arthas 线上运维学习笔记_第2张图片
1563721331455.png
  • 默认情况下, arthas server 侦听的是 127.0.0.1 这个IP,如果希望远程可以访问,可以使用--target-ip 的参数

  • arthas-bootArthas 的启动程序,它启动后,会列出所有的 Java 进程,输入需要诊断的目标进程序号即可

    arthas 线上运维学习笔记_第3张图片
    1563721311672.png
  • Arthas支持通过 Web Socket来连接。

    • 当在本地启动时,可以访问 http://127.0.0.1:8563/ ,通过浏览器来使用 Arthas。
    • 输入 help 可以看到常用的帮助命令:
  • arthas-boot.jar 支持很多参数,可以执行 java -jar arthas-boot.jar -h 查看

    D:\arthas>java -jar arthas-boot.jar -h
    [INFO] arthas-boot version: 3.1.1
    Usage: arthas-boot [-v] [--session-timeout ] [--arthas-home ]
           [--use-version ] [--target-ip ] [--attach-only] [--height
           ] [--width ] [-c ] [--repo-mirror ]
           [--versions] [-f ] [--telnet-port ] [--use-http] [-h]
           [--http-port ] [pid]
    
    Bootstrap Arthas
    
    EXAMPLES:
      java -jar arthas-boot.jar 
      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 -c 'sysprop; thread' 
      java -jar arthas-boot.jar -f batch.as 
      java -jar arthas-boot.jar --use-version 3.1.1
      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:
     -v,--verbose                   Verbose, print debug info.
        --session-timeout    The session timeout seconds, default 1800
                                    (30min)
        --arthas-home        The arthas home
        --use-version        Use special version arthas
        --target-ip          The target jvm listen ip, default 127.0.0.1
        --attach-only               Attach target process only, do not connect
        --height             arthas-client terminal height
        --width              arthas-client terminal width
     -c,--command            Command to execute, multiple commands separated
                                    by ;
        --repo-mirror        Use special maven repository mirror, value is
                                    center/aliyun or http repo url.
        --versions                  List local and remote arthas versions
     -f,--batch-file         The batch file to execute
        --telnet-port        The target jvm listen telnet port, default 3658
        --use-http                  Enforce use http to download, default use https
     -h,--help                      Print usage
        --http-port          The target jvm listen http port, default 8563
                               Target pid
    

使用技巧

  • 每个命令,都可以加上 -h 来查看对应的帮助信息,例如:sc -h
  • Tab 自动补全,例如:sysprop java. 按下 Tab 键,会补全对应的 key
  • 支持常见的命令行快捷键,比如 ctrl+a/e,更多输入 keymap 查看
  • 历史命令补全,输入一半时,按下Up/↑Down/↓ 来匹配,例如 sysprop ja 之后,按下 会帮你自动补全
  • 管道命令支持,例如 sysprop | wc -l

退出

  • exitquit 可以退出 Arthas
    • 退出 Arthas 之后,还可以再次使用 java -jar arthas-boot.jar 来链接
    • exit/quit 命令只是退出当前 session,arthas server 还在目标进程中运行,shutdown 命令才能完全退出 Arthas

常用命令

dashboard

  • dashboard 命令可以查看系统的实时数据面板。

  • qctrl+c 可以退出数据面展示

    arthas 线上运维学习笔记_第4张图片
    1563721359862.png

数据说明:

  • ID: Java级别的线程ID,注意这个ID不能跟jstack中的nativeID一一对应
  • NAME: 线程名
  • GROUP: 线程组名
  • PRIORITY: 线程优先级, 1~10之间的数字,越大表示优先级越高
  • STATE: 线程的状态
  • CPU%: 线程消耗的cpu占比,采样100ms,将所有线程在这100ms内的cpu使用量求和,再算出每个线程的cpu使用占比。
  • TIME: 线程运行总时间,数据格式为分:秒
  • INTERRUPTED: 线程当前的中断位状态
  • DAEMON: 是否是daemon线程

thread

  • 查看当前线程信息,查看线程的堆栈

  • 参数说明

    参数名称 参数说明
    id 线程id
    [n:] 指定最忙的前N个线程并打印堆栈
    [b] 找出当前阻塞其他线程的线程
    [i ] 指定cpu占比统计的采样间隔,单位为毫秒
  • thread 1 打印线程 ID 1 的线程栈信息

arthas 线上运维学习笔记_第5张图片
1563721533844.png
  • 查看 CPU 使用率 top n 的线程的栈,当前最忙的前 n 个线程:

    thread -n 3
    
    arthas 线上运维学习笔记_第6张图片
    1563721640496.png
  • 查看 5 秒内的 CPU 使用率 top n 的线程栈:

    thread -n 3 -i 5000
    
    arthas 线上运维学习笔记_第7张图片
    1563721743928.png
*   在该命令中,arthas 会停顿5秒,进行计算得出结果,为阿里点赞
  • 查看线程是否有阻塞:

    thread -b
    
    • 有时候我们发现应用出现卡顿,未响应, 通常是由于某个线程占用着某个锁, 并且其他线程都在等待这把锁的释放。 为了排查这类问题,此时使用 -b 参数,可以找到问题所在。
      • 目前只支持找出synchronized关键字阻塞住的线程, 如果是java.util.concurrent.Lock, 目前还不支持

jvm

  • 查看当前JVM信息

    $ jvm
     RUNTIME
    -----------------------------------------------------------------------------------------------------------------------
     MACHINE-NAME                      18280@DESKTOP-040TJ8N
     JVM-START-TIME                    2019-07-21 22:52:26
     MANAGEMENT-SPEC-VERSION           1.2
     SPEC-NAME                         Java Virtual Machine Specification
     SPEC-VENDOR                       Oracle Corporation
     SPEC-VERSION                      1.8
     VM-NAME                           Java HotSpot(TM) 64-Bit Server VM
     VM-VENDOR                         Oracle Corporation
     VM-VERSION                        25.131-b11
     INPUT-ARGUMENTS                   -Djava.util.logging.config.file=H:\Development\ide\ideacfg\system\tomcat\Unnamed_pl
                                       atform\conf\logging.properties
                                       -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
                                       -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:2139,suspend=y,server=n
                                       -javaagent:H:\Development\ide\ideacfg\system\captureAgent\debugger-agent.jar=file:/
                                       C:/Users/guosucong/AppData/Local/Temp/capture5938.props
                                       -Dcom.sun.management.jmxremote=
                                       -Dcom.sun.management.jmxremote.port=1099
                                       -Dcom.sun.management.jmxremote.ssl=false
                                       -Dcom.sun.management.jmxremote.authenticate=false
                                       -Djava.rmi.server.hostname=127.0.0.1
                                       -Djdk.tls.ephemeralDHKeySize=2048
                                       -Djava.endorsed.dirs=D:\Development\Tomcat\apache-tomcat-7.0.75\endorsed
                                       -Dcatalina.base=H:\Development\ide\ideacfg\system\tomcat\Unnamed_platform
                                       -Dcatalina.home=D:\Development\Tomcat\apache-tomcat-7.0.75
                                       -Djava.io.tmpdir=D:\Development\Tomcat\apache-tomcat-7.0.75\temp
    
     CLASS-PATH                        D:\Development\Tomcat\apache-tomcat-7.0.75\bin\bootstrap.jar;D:\Development\Tomcat\
                                       apache-tomcat-7.0.75\bin\tomcat-juli.jar;H:\Development\ide\ideacfg\system\captureA
                                       gent\debugger-agent.jar
     BOOT-CLASS-PATH                   D:\Development\Java\jdk1.8.0_131\jre\lib\resources.jar;D:\Development\Java\jdk1.8.0
                                       _131\jre\lib\rt.jar;D:\Development\Java\jdk1.8.0_131\jre\lib\sunrsasign.jar;D:\Deve
                                       lopment\Java\jdk1.8.0_131\jre\lib\jsse.jar;D:\Development\Java\jdk1.8.0_131\jre\lib
                                       \jce.jar;D:\Development\Java\jdk1.8.0_131\jre\lib\charsets.jar;D:\Development\Java\
                                       jdk1.8.0_131\jre\lib\jfr.jar;D:\Development\Java\jdk1.8.0_131\jre\classes;H:\Develo
                                       pment\ide\ideacfg\system\captureAgent\debugger-agent-storage.jar
     LIBRARY-PATH                      D:\Development\Java\jdk1.8.0_131\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:
                                       \Windows;C:\ProgramData\Oracle\Java\javapath;%APPCAN_PATH%;D:\Development\Oracle\DB
                                       \product\11.2.0\dbhome_1\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbe
                                       m;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\NVIDIA Corpora
                                       tion\PhysX\Common;D:\VisualSVN Server\bin;D:\TortoiseSVN\bin;C:\ProgramData\chocola
                                       tey\bin;H:\Android\sdk\tools;H:\Android\sdk\platform-tools;D:\Development\TortoiseG
                                       it\bin;D:\Development\nodejs\;D:\Microsoft VS Code\bin;D:\Development\Java\jdk1.8.0
                                       _131\bin;D:\Development\Tomcat\apache-tomcat-7.0.75\bin;D:\Development\apache-maven
                                       -3.2.5\bin;D:\auto-tsschecker_v2.1;D:\Development\MySQL\Mysql5_7\MySQLServer\bin;D:
                                       \Development\apache-cxf-2.4.2\bin;C:\Users\guosucong\AppData\Local\Microsoft\Window
                                       sApps;D:\Development\kotlinc\bin;D:\Development\spring-2.0.0.BUILD-SNAPSHOT\bin;D:\
                                       Development\redis;D:\Development\gradle-4.4.1\bin;H:\Android\sdk\platform-tools;H:\
                                       Android\sdk\tools;D:\Microsoft VS Code\bin;D:\Development\apache-ant-1.9.9\bin;D:\D
                                       evelopment\sonarqube-6.7.4\bin;C:\Users\guosucong\AppData\Roaming\npm;D:\Developmen
                                       t\Git\bin;D:\Development\flutter\bin;.
    
    -----------------------------------------------------------------------------------------------------------------------
     CLASS-LOADING
    -----------------------------------------------------------------------------------------------------------------------
     LOADED-CLASS-COUNT                10418
     TOTAL-LOADED-CLASS-COUNT          10418
     UNLOADED-CLASS-COUNT              0
     IS-VERBOSE                        false
    
    -----------------------------------------------------------------------------------------------------------------------
     COMPILATION
    -----------------------------------------------------------------------------------------------------------------------
     NAME                              HotSpot 64-Bit Tiered Compilers
     TOTAL-COMPILE-TIME                46848(ms)
    
    -----------------------------------------------------------------------------------------------------------------------
     GARBAGE-COLLECTORS
    -----------------------------------------------------------------------------------------------------------------------
     PS Scavenge                       13/216(ms)
     [count/time]
     PS MarkSweep                      3/291(ms)
     [count/time]
    
    -----------------------------------------------------------------------------------------------------------------------
     MEMORY-MANAGERS
    -----------------------------------------------------------------------------------------------------------------------
     CodeCacheManager                  Code Cache
    
     Metaspace Manager                 Metaspace
                                       Compressed Class Space
    
     PS Scavenge                       PS Eden Space
                                       PS Survivor Space
    
     PS MarkSweep                      PS Eden Space
                                       PS Survivor Space
                                       PS Old Gen
    
    
    -----------------------------------------------------------------------------------------------------------------------
     MEMORY
    -----------------------------------------------------------------------------------------------------------------------
     HEAP-MEMORY-USAGE                 1436024832(1.34 GiB)/268435456(256.00 MiB)/3791650816(3.53 GiB)/1040965944(992.74 M
     [committed/init/max/used]         iB)
     NO-HEAP-MEMORY-USAGE              113754112(108.48 MiB)/2555904(2.44 MiB)/-1(-1 B)/111507424(106.34 MiB)
     [committed/init/max/used]
     PENDING-FINALIZE-COUNT            0
    
    -----------------------------------------------------------------------------------------------------------------------
     OPERATING-SYSTEM
    -----------------------------------------------------------------------------------------------------------------------
     OS                                Windows 10
     ARCH                              amd64
     PROCESSORS-COUNT                  8
     LOAD-AVERAGE                      -1.0
     VERSION                           10.0
    
    -----------------------------------------------------------------------------------------------------------------------
     THREAD
    -----------------------------------------------------------------------------------------------------------------------
     COUNT                             52
     DAEMON-COUNT                      23
     PEAK-COUNT                        53
     STARTED-COUNT                     71
     DEADLOCK-COUNT                    0
    
    -----------------------------------------------------------------------------------------------------------------------
     FILE-DESCRIPTOR
    -----------------------------------------------------------------------------------------------------------------------
     MAX-FILE-DESCRIPTOR-COUNT         -1
     OPEN-FILE-DESCRIPTOR-COUNT        -1
    Affect(row-cnt:0) cost in 4 ms.
    
  • THREAD相关

    • COUNT: JVM当前活跃的线程数
    • DAEMON-COUNT: JVM当前活跃的守护线程数
    • PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数
    • STARTED-COUNT: 从JVM启动开始总共启动过的线程次数
    • DEADLOCK-COUNT: JVM当前死锁的线程数
  • 文件描述符相关

    • MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数
    • OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数

sc

  • 查找 JVM 加载类,Search-Class 的简写,这个命令能搜索出所有已经加载到 JVM 中的 Class 信息,sc -d *MathGame
  • 如果搜索的是接口,还会搜索所有的实现类。比如查看所有的 Filter 实现类:
sc javax.servlet.Filter

-d 参数可以打印出类加载的具体信息,方便定位类加载问题

sc 支持通配符,比如搜索所有的 StringUtils

Copysc *StringUtils

[图片上传失败...(image-2b1ed8-1590935866588)]

打印类的 Field 信息:

Copysc -d -f demo.MathGame

sm

  • 查看已加载类的方法信息Search-Method 的简写,这个命令能搜索出所有已经加载了 Class 信息的方法信息。
  • sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到
  • 查看 String 类的全部方法:
sm java.lang.String
arthas 线上运维学习笔记_第8张图片
1563722348451.png
  • 查看具体方法的信息:
sm java.lang.String toString
arthas 线上运维学习笔记_第9张图片
1563722440683.png
  • 通过 -d 参数可以打印函数的具体属性,展示每个方法的详细信息
sm -d java.math.RoundingMode
arthas 线上运维学习笔记_第10张图片
1563722486838.png

jad

  • 反编译指定已加载类的源码 ,jad 命令将 JVM 中实际运行的 class 的 byte code 反编译成 java 代码,便于你理解业务逻辑
  • 参数说明
参数名称 参数说明
class-pattern 类名表达式匹配
[c:] 类所属 ClassLoader 的 hashcode
[E] 开启正则表达式匹配,默认为通配符匹配
  • 通过 jad 命令反编译代码:
jad demo.MatthGame
$ jad com.platform.controller.SysConfigController

ClassLoader:
+-WebappClassLoader
    context: /platform
    delegate: false
    repositories:
      /WEB-INF/classes/
  ----------> Parent Classloader:
  java.net.URLClassLoader@2d127a61

  +-java.net.URLClassLoader@2d127a61
    +-sun.misc.Launcher$AppClassLoader@18b4aac2
      +-sun.misc.Launcher$ExtClassLoader@6dde5c8c

Location:
/H:/Development/ideaworkspace/platform/platform-framework/target/platform-framework/WEB-INF/classes/

/*
 * Decompiled with CFR 0_132.
 *
 * Could not load the following classes:
 *  com.platform.annotation.SysLog
 *  com.platform.controller.AbstractController
 *  com.platform.entity.SysConfigEntity
 *  com.platform.service.SysConfigService
 *  com.platform.utils.PageUtils
 *  com.platform.utils.Query
 *  com.platform.utils.R
 *  com.platform.validator.ValidatorUtils
 *  org.apache.shiro.authz.annotation.RequiresPermissions
 *  org.springframework.beans.factory.annotation.Autowired
 *  org.springframework.web.bind.annotation.PathVariable
 *  org.springframework.web.bind.annotation.RequestBody
 *  org.springframework.web.bind.annotation.RequestMapping
 *  org.springframework.web.bind.annotation.RequestParam
 *  org.springframework.web.bind.annotation.RestController
 */
package com.platform.controller;

import com.platform.annotation.SysLog;
import com.platform.controller.AbstractController;
import com.platform.entity.SysConfigEntity;
import com.platform.service.SysConfigService;
import com.platform.utils.PageUtils;
import com.platform.utils.Query;
import com.platform.utils.R;
import com.platform.validator.ValidatorUtils;
import java.util.List;
import java.util.Map;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value={"/sys/config"})
public class SysConfigController
extends AbstractController {
    @Autowired
    private SysConfigService sysConfigService;

    @RequestMapping(value={"/list"})
    @RequiresPermissions(value={"sys:config:list"})
    public R list(@RequestParam Map params) {
        Query query = new Query(params);
        List configList = this.sysConfigService.queryList((Map)query);
        int total = this.sysConfigService.queryTotal((Map)query);
        PageUtils pageUtil = new PageUtils(configList, total, query.getLimit(), query.getPage());
        return R.ok().put("page", (Object)pageUtil);
    }

    @RequestMapping(value={"/info/{id}"})
    @RequiresPermissions(value={"sys:config:info"})
    public R info(@PathVariable(value="id") Long id) {
        SysConfigEntity config = this.sysConfigService.queryObject(id);
        return R.ok().put("config", (Object)config);
    }

    @SysLog(value="\u4fdd\u5b58\u914d\u7f6e")
    @RequestMapping(value={"/save"})
    @RequiresPermissions(value={"sys:config:save"})
    public R save(@RequestBody SysConfigEntity config) {
        ValidatorUtils.validateEntity((Object)config, (Class[])new Class[0]);
        this.sysConfigService.save(config);
        return R.ok();
    }

    @SysLog(value="\u4fee\u6539\u914d\u7f6e")
    @RequestMapping(value={"/update"})
    @RequiresPermissions(value={"sys:config:update"})
    public R update(@RequestBody SysConfigEntity config) {
        ValidatorUtils.validateEntity((Object)config, (Class[])new Class[0]);
        this.sysConfigService.update(config);
        return R.ok();
    }

    @SysLog(value="\u5220\u9664\u914d\u7f6e")
    @RequestMapping(value={"/delete"})
    @RequiresPermissions(value={"sys:config:delete"})
    public R delete(@RequestBody Long[] ids) {
        this.sysConfigService.deleteBatch(ids);
        return R.ok();
    }
}
  • 通过该工具,我们往往能看到线上当前代码的情况,有时候在线上环境中手头没有源代码的情况之下,可以通过该命令对指定的类进行反编译,找到问题的根源,从而快速的定位问题与获取解决方案,该命令可以与其他命令结合,反编译后得出源文件,对文件代码进行修改后通过mc命令编译,通过redefine热加载回JVM内存,达到无需重启,修复线上问题,但是对于反编译出来的源代码,可能出现错乱问题,所以还是慎重使用,一般用于查看线上问题。

mc

redefine

monitor

trace

watch

watch 命令可以查看函数的:

  • 参数
  • 返回值
  • 异常信息
Copywatch demo.MathGame primeFactors returnObj

[图片上传失败...(image-c6fd81-1590935866588)]

Copywatch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2
  1. 第一个参数是类名,支持通配
  2. 第二个参数是函数名,支持通配
  3. 第三个参数是定义返回值
  4. -x 2 是为了将结果展开

返回值表达式实际是一个 ognl 表示,支持一些内置对象:

  • loader
  • clazz
  • method
  • target
  • params
  • returnObj
  • throwExp
  • isBefore
  • isThrow
  • isReturn

watch命令支持按请求耗时进行过滤:

watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'

Arthas在 watch/trace 等命令时,实际上是修改了应用的字节码,插入增强的代码。显式执行 reset 命令,可以清除掉这些增强代码


ognl

获取静态类的静态字段:

ognl '@demo.MathGame@random'

具体,查看执行ognl表达式

trace

方法内部调用路径,并输出方法路径上的每个节点上耗时

trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路

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

很多时候我们只想看到某个方法的 rt 大于某个时间之后的 trace 结果,现在 Arthas 可以按照方法执行的耗时来进行过滤了,例如 trace *StringUtils isBlank '#cost>100' 表示当执行时间超过 100ms 的时候,才会输出 trace 的结果。

watch/stack/trace 这个三个命令都支持 #cost

trace 函数:

$ trace demo.MathGame run
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 42 ms.
`---ts=2018-12-04 00:44:17;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    `---[10.611029ms] demo.MathGame:run()
        +---[0.05638ms] java.util.Random:nextInt()
        +---[10.036885ms] demo.MathGame:primeFactors()
        `---[0.170316ms] demo.MathGame:print()

过滤掉 jdk 的函数:

$ trace -j  demo.MathGame run
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 31 ms.
`---ts=2018-12-04 01:09:14;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    `---[5.190646ms] demo.MathGame:run()
        +---[4.465779ms] demo.MathGame:primeFactors()
        `---[0.375324ms] demo.MathGame:print()
  • -j: jdkMethodSkip, skip jdk method trace

trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销

stack

输出当前方法被调用的调用路径

很多时候我们都知道一个方法被执行,但这个方法被执行的路径非常多,或者你根本就不知道这个方法是从那里被执行了,此时你需要的是 stack 命令。

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

据执行时间来过滤:

$ stack demo.MathGame primeFactors '#cost>5'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 35 ms.
ts=2018-12-04 01:35:58;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@3d4eac69
    @demo.MathGame.run()
        at demo.MathGame.main(MathGame.java:16)

实战

启动 Spring Boot Demo

wget https://github.com/hengyunabc/katacoda-scenarios/raw/master/demo-arthas-spring-boot.jar
java -jar demo-arthas-spring-boot.jar

启动 arthas-boot

wget https://alibaba.github.io/arthas/arthas-boot.jar
java -jar arthas-boot.jar --target-ip 0.0.0.0

就像基础教程说过的,选择目标进程

查看 JVM 信息

sysprop

  • 查看当前 JVM 的系统属性(System Property)
    • sysprop 打印所有 System Properties
    • 指定单个 key:sysprop java.version
    • 通过 grep 过滤:sysprop|grep user
    • 设置新的value: sysprop testKey testValue

[图片上传失败...(image-51b975-1590935866588)]

sysenv

  • sysenv 命令查看当前 JVM 的环境属性(System Environment Variables)

[图片上传失败...(image-e209dc-1590935866588)]

  • 也是支持查看单个环境变量值:

    sysenv USER
    

分析线程阻塞

不重启修复BUG

参考

  • 官宣-Arthas入门
  • Java 诊断工具 Arthas 教程学习笔记

你可能感兴趣的:(arthas 线上运维学习笔记)