当前位置: 首页>>杂谈>>正文


常用的Java性能测试工具实战

杂谈 去评论

nmon:获取系统性能数据

除了在上一篇博客中介绍的 top、free 等命令,还有一些将资源整合在一起的监控工具,nmon 便是一个老牌的 Linux 性能监控工具,它不仅有漂亮的监控界面,还能通过配套的nmonchar产出细致的监控报表。

在这里插入图片描述
我在对应用做性能评估时,通常会加上 nmon 的报告,这会让测试结果更加有说服力。你在平时工作中也可如此尝试。

上一篇博客中介绍的一些操作系统性能指标,都可从 nmon 中获取。它的监控范围很广,包括 CPU、内存、网络、磁盘、文件系统、NFS、系统资源等信息。

安装

nonm可以去它的官网下载后安装,不过我还是更喜欢用yum安装。但nmonchar暂不提供yum的下载方式,只能通过官网下载。具体方法如下:

# 安装yum源
yum -y install wget
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
# 更新yum源
yum makecache
# 安装ksh和nmon
yum -y install ksh  nmon

# 下载nmonchar 
wget https://udomain.dl.sourceforge.net/project/nmon/nmonchart40.tar  --no-check-certificate
# 解压nmonchart
tar -xf nmonchart40.tar 
# 移动到$Path
mv nmonchart /usr/local/bin

使用

直接执行nmon命令即可运行并进入软件首页,按 C 键可加入 CPU 面板;按 M 键可加入内存面板;按 N 键可加入网络;按 D 键可加入磁盘等。

此外,mono还可以静默采集,通过nmon -f -s 10 -c 30 -m .命令,可实现每 10 秒采集一次数据,共采集 30 次,它会把这一段时间之内的数据记录下来并存储到一个文件中,默认文件名为 机器名_日期时间字符串.nmon 。

需要注意的是这是一异步的命令,输入命令后,程序会在后台运行。一般来说,您是可以预估程序运行所需要的时间,如上文中的命令,就是需要10*30=300秒的时间。如果您采集数据的周期较长,不确定程序是否还在运行,那么您就可以通过ps -ef| grep nmon查询。

得到这个nmon文件后,可以通过nmonchart命令生成html。

在这里插入图片描述

在这里插入图片描述

如果您的html页面不能正常显示,大概率是因为有一个叫jsapi的资源不能在线加载,您可以通过查看浏览器控制台进行核实。要解决也很容易,下载相关资源后,再把html文件中的资源路径修改好就行。获取资源请点击此超链接:nmonchart页面所需资源:jsapi

jvisualvm:获取 JVM 性能数据

jvisualvm 原是随着 JDK 发布的一个工具,Java 9 之后开始单独发布。通过它,可以了解应用在运行中的内部情况。我们可以连接本地或者远程的服务器,监控大量的性能数据。

通过插件功能,jvisualvm 能获得更强大的扩展。如下图所示,建议把所有的插件下载下来进行体验。

在这里插入图片描述

要想监控远程的应用,还需要在被监控的 App 上加入 jmx 参数。

-Dcom.sun.management.jmxremote.port=14000
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false

上述配置的意义是开启 JMX 连接端口 14000,同时配置不需要 SSL 安全认证方式连接。

对于性能优化来说,我们主要用到它的采样器。注意,由于抽样分析过程对程序运行性能有较大的影响,一般我们只在测试环境中使用此功能。

在这里插入图片描述
对于一个 Java 应用来说,除了要关注它的 CPU 指标,垃圾回收方面也是不容忽视的性能点,我们主要关注以下三点。

  • CPU 分析:统计方法的执行次数和执行耗时,这些数据可用于分析哪个方法执行时间过长,成为热点等。
  • 内存分析:可以通过内存监视和内存快照等方式进行分析,进而检测内存泄漏问题,优化内存使用情况。
  • 线程分析:可以查看线程的状态变化,以及一些死锁情况。

JMC:获取 Java 应用详细性能数据

对于我们常用的 HotSpot 来说,有更强大的工具,那就是 JMC。 JMC 集成了一个非常好用的功能:JFR(Java Flight Recorder)。

Flight Recorder 源自飞机的黑盒子,是用来录制信息然后事后分析的。在 Java11 中,它可以通过 jcmd 命令进行录制,主要包括 configure、check、start、dump、stop 这五个命令,其执行顺序为,start — dump — stop,例如:

jcmd <pid> JFR.start
jcmd <pid> JFR.dump filename=recording.jfr 
jcmd <pid> JFR.stop

JFR 功能是建在 JVM 内部的,不需要额外依赖,可以直接使用,它能够监测大量数据。比如,我们提到的锁竞争、延迟、阻塞等;甚至在 JVM 内部,比如 SafePoint、JIT 编译等,也能去分析。

JMC 集成了 JFR 的功能,下面介绍一下 JMC 的使用。

录制

下图是录制了一个 Tomcat 一分钟之后的结果,从左边的菜单栏即可进入相应的性能界面。

在这里插入图片描述
通过录制数据,可以清晰了解到某一分钟内,操作系统资源,以及 JVM 内部的性能数据情况。

线程

选择相应的线程,即可了解线程的执行情况,比如 Wait、Idle 、Block 等状态和时序。

以 C2 编译器线程为例,可以看到详细的热点类,以及方法内联后的代码大小。如下图所示,C2 此时正在疯狂运转。

在这里插入图片描述

内存

通过内存界面,可以看到每个时间段内内存的申请情况。在排查内存溢出、内存泄漏等情况时,这个功能非常有用。

在这里插入图片描述

一些竞争非常严重的锁信息,以及一些死锁信息,都可以在锁信息界面中找到。可以看到,一些锁的具体 ID,以及关联的线程信息,都可以进行联动分析。

在这里插入图片描述

文件和 Socket

文件和 Socket 界面能够监控对 I/O 的读写,界面一目了然。如果你的应用 I/O 操作比较繁重,比如日志打印比较多、网络读写频繁,就可以在这里监控到相应的信息,并能够和执行栈关联起来。

在这里插入图片描述

方法调用

这个和 jvisualvm 的功能类似,展示的是方法调用信息和排行。从这里可以看到一些高耗时方法和热点方法。

在这里插入图片描述

垃圾回收

如果垃圾回收过于频繁,就会影响应用的性能。JFR 对垃圾回收进行了详细的记录,比如什么时候发生了垃圾回收,用的什么垃圾回收器,每次垃圾回收的耗时,甚至是什么原因引起的等问题,都可以在这里看到。

在这里插入图片描述

JIT

JIT 编译后的代码,执行速度会特别快,但它需要一个编译过程。编译界面显示了详细的 JIT 编译过程信息,包括生成后的 CodeCache 大小、方法内联信息等。

在这里插入图片描述

TLAB

JVM 默认给每个线程开辟一个 buffer 区域,用来加速对象分配,这就是 TLAB(Thread Local Allocation Buffer)的概念。这个 buffer,就放在 Eden 区。

原理和 Java 语言中的 ThreadLocal 类似,能够避免对公共区的操作,可以减少一些锁竞争。如下图所示的界面,详细地显示了这个分配过程。

在这里插入图片描述
在后面的文章中,我们会有多个使用此工具的分析案例。

Arthas :获取单个请求的调用链耗时

Arthas 是阿里开源的Java 诊断工具,可以排查内存溢出、CPU 飙升、负载高等内容,可以说是一个 jstack、jmap 等命令的大集合。

安装

安装运行方式非常简单:通过运行curl -O https://arthas.aliyun.com/arthas-boot.jar命令下载相关jar包,然后运行java -jar arthas-boot.jar即可启动。如下图所示:

在这里插入图片描述
如果您明明运行的有java项目,但是Arthas 启动后却报如下提示,说找不到任何java进程,如下所示:

[INFO] Can not find java process. Try to run `jps` command lists the instrumented Java HotSpot VMs on the target system.Please select an available pid.

那很有可能是因为您安装的是OpenJDK,缺乏Java的某些工具包导致,可以通过安装openjdk-devel来解决,例如OpenJDK11可以通过yum install java-11-openjdk-devel 安装实现。

使用

Arthas 支持很多命令,我们以 trace 命令为例。

有时候,我们统计到某个接口的耗时非常高,但又无法找到具体原因时,就可以使用这个 trace 命令。该命令会从方法执行开始记录整个链路上的执行情况,然后统计每个节点的性能开销,最终以树状打印,很多性能问题一眼就能看出来。

下面就是一个执行结果示例。

在这里插入图片描述
后续的博文会有实例来演示如何找到问题发生的具体原因。

wrk:获取 Web 接口的性能数据

wrk是一款 HTTP 压测工具,和 ab 命令类似,它也是一个命令行工具。

安装

最常见的方法是通过下载源码,然后编译出二进制文件,但这种方法比较麻烦,所以我把已经编译好的二进制文件传到了CSDN上,大家可以下载后直接使用。请点击右侧的超链接跳:wrk(编译完成的可执行文件)

在这里也贴出通过源码编译出可执行文件的办法:

yum install -y git gcc
git clone https://github.com/wg/wrk.git  
cd wrk 
make
# 如果make命令报错,则运行下面一行命令,否则就不需要运行。
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel asciidoc perl-ExtUtils-MakeMaker
mv wrk   /usr/local/bin

使用

使用方法如下

-c, --connections <N>  跟服务器建立并保持的TCP连接数量  
-d, --duration    <T>  压测时间           
-t, --threads     <N>  使用多少个线程进行压测   
-s, --script      <S>  指定Lua脚本路径       
-H, --header      <H>  为每一个HTTP请求添加HTTP头      
    --latency          在压测结束后,打印延迟统计信息   
    --timeout     <T>  超时时间     
-v, --version          打印正在使用的wrk的详细版本信息
<N>代表数字参数,支持国际单位 (1k, 1M, 1G)
<T>代表时间参数,支持时间单位 (2s, 2m, 2h)

例如:

在这里插入图片描述
可以看到,wrk 统计了常见的性能指标,对 Web 服务性能测试非常有用。同时,wrk 支持 Lua 脚本,用来控制 setup、init、delay、request、response 等函数,可以更好地模拟用户请求。

小结

了获取更多性能数据,我们在本文时介绍了以下 5 款工具。

  • nmon 获取系统性能数据;

  • jvisualvm获取 JVM 性能数据;

  • jmc 获取 Java 应用详细性能数据;

  • arthas 获取单个请求的调用链耗时;

  • wrk 获取 Web 接口的性能数据。

可以看出,这些工具有偏低层的、有偏应用的、有偏统计的、有偏细节的,在定位性能问题时,你需要灵活地使用这些工具,既从全貌上掌握应用的属性,也从细节上找到性能的瓶颈,对应用性能进行全方位的掌控。

这些工具能够很好地帮助我们找到系统的瓶颈点,那么对代码进行优化时,如何分析优化效果呢?又如何对代码片段进行快速、专业的测试呢?下一篇文章,我将解答以上问题。

原文链接:如何获取Java运行时的性能数据
本文由《堆栈答案》整理。文章地址: https://stackanswer.com/category/tattle-tittle/3.html,未经允许,请勿转载。