java性能分析(清算系统)
一、为什么要分析
本文以典型清算系统为例进行性能分析概要描述。清算系统与交易系统的区别就在于交易系统是对时效数据的处理,而清算系统是针对既有数据的批量处理。既然是跑批,那么清算时长就成为了衡量清算系统的主要指标。
结合现有清算系统,主要瓶颈基本体现在sql效率、代码质量、I/O、内存、CPU。
二、分析工具的使用
对于大部分开发者目前都是谈“性”色变。其实性能分析对于开发者来说是一件很简单的事情,学会简单的性能分析对于开发工作和问题排查都有百利而无一害。可以大大降低后续压测人员返工率。
接下来本文将介绍几种性能分析工具,可根据实际使用场景择优选择。
1、jvisualvm
优点:
1)无需单独安装
jvisualvm为jdk官方提供的性能监测工具,无需开发者再次手动安装,该工具位于JAVA_HOME的bin目录中。
2)实动态显示cpu、堆栈、类、线程的相关信息
3)远程检测
缺点:
1)没有数据库连接的检测
2)没有对代码执行时间的统计
操作概述
进入启动页,在左侧的“应用程序”列表里面选择本地或者远程的应用程序实例。
在概述页面可以获取到应用的JVM参数和系统的属性信息,通过此处参数分析我们可以了解到应用启动我们所增加的启动参数是否生效,配置的参数路径是否正确。
在监视页面可以实时看到CPU、类、CPU、线程数等信息,还可以通过“执行垃圾回收”按钮手动GC当前应用,“堆Dump”按钮拿到这一时刻程序的dump数据。
在弹出的heapdump标签页可以浏览这一时间点的线程执行数据,类实例数据。
在线程页面我们可以获取到线程的运行详细信息,包含线程名、运行时间、生命周期总时间。我们还可以通过点击“线程Dump”按钮获取到当前时间点所有线程的dump数据,此处显示的线程数据与“堆Dump”中获取的数据一致,用于分析线程假死,获取正在执行的代码。
在抽样器界面可以按需抽取指定时间的执行数据,其中包含总CPU数据、线程CPU数据、总类分配、线程类分配数据。
2、nmon
nmon主要用于对unix系列服务器的资源监控,可实时显示资源占用情况,生成指定时间段的报告文件。在开发测试中主要用于对硬件资源瓶颈的分析。
优点:
1)实动态显示服务器资源信息
2)安装便捷,解压即可用
3)可生成资源分析报告,按按任意频率采集。
缺点:
1)没有数据库连接的检测
2)没有对代码执行时间的统计
下载:http://nmon.sourceforge.net/pmwiki.php?n=Site.Download
操作概述
下载好对应操作系统的压缩包,直接解压到服务器任意目录即可,同时赋予该目录用户可执行权限。
nmon实时监控,通过执行./nmon_x86_rhel75
(其他系统启动脚本不一样,按需选择),启动nmon实时监控。
可通过主界面的监控开关直接选择到需要显示的资源数据。
按键 | 功能 |
---|---|
q | 停止并退出 Nmon |
c | 查看 CPU 统计数据 |
m | 查看内存统计数据 |
h | 查看帮助 |
d | 查看硬盘统计数据 |
k | 查看内核统计数据 |
n | 查看网络统计数据 |
N | 查看 NFS 统计数据 |
j | 查看文件系统统计数据 |
t | 查看高耗进程 |
V | 查看虚拟内存统计数据 |
v | 详细模式 |
生成报告
性能测试时,如果我们需要采取一段时间的系统资源变化用于分析,这时候我们就要用到nomon的数据采集功能。
nmon -f -T -s 5 -c 12 -m /home/nmonReport
参数如下:
参数 | 概述 |
---|---|
-f | 生成文件,文件名=主机名+当前时间.nmon |
-T | 显示资源占有率较高的进程 |
-s | -s 10表示每隔10秒采集一次数据 |
-c | -c 10表示总共采集十次数据 |
-m | 指定文件保存目录 |
由于生成的nmon文件是追加写原理,所以此处可以通过直接kill调nmon的采集进程来终止数据采集。通过数据采集功能我们得到了一个“localhost20200101.nmon”的文件。此时我们还需要去http://nmon.sourceforge.net/pmwiki.php?n=Site.Nmon-Analyser下载一个叫“nmon analyser”的工具,用它把我们刚才生成的nmon文件转化为excel文件,便于进行性能分析。
打开“nmon analyser v54.xlsm”文件,点击Analyze nmon data按钮,选择我们刚刚生成的nmon文件,点击下一步即可生成一份excel报告,其中包含对服务器硬件资源的各项监控,我们可以用这个功能来分析我们服务器的物理瓶颈究竟在哪里。也可以通过此方法发现代码中的一些不足并去优化我们的代码。
3、jprofiler
想必java开发人员都应该听说过这个神器吧,一款专业的jvm分析神器,他能让你更快捷的找到是哪里内存泄露,是哪行代码执行速度的不尽人意,是哪句sql在拼命的查询,是哪个线程在拼命地创建对象……
优点:
1)什么都好
缺点:
1)付费
下载:https://www.ej-technologies.com/products/jprofiler/overview.html
操作概述
1、远程监控
先按下载地址下载一个window客户端。然后在官网下载linux版本然后上传至服务器,找一个目录解压。解压后我们进入到bin目录执行./jpenable
需注意执行该语句地时候要和jar启动的用户使用同一个用户。
1)选择要监控的jvm。
2)选择监控模式GUI还是离线,此处我们选择【1】GUI。
3)输入挂载的端口,此处的端口我们在界面配置的地方要用到,我们以10012端口为例。
4)出现如下提示,即为成功启动监测。
5)然后我们再到GUI界面新建一个Remote Integration
6)选择电脑系统类型
7)选择jdk版本
8)选择GUI模板
9)地址填写
10)服务器jprofiler的路径填写
11)端口设置为10012
然后一直下一步即可。
12)选择Instrumentation
13)于是我们进入到了监测主界面,其他的操作就都监测本地程序一致了,请直接看第二点本地监测相关内容。
2、本地监测
本地监测有两种方式,一个是本地应用启动后attach 到 jvm,另一种是直接通过ide中的插件启动,一般我们使用的是第一种,可以脱离启动程序外挂监测,而第二种则对监测有一定效率影响。
profiler直接启动
attach到jvm
实际启动后都和第一节介绍的界面展示的是一样的,下面我们介绍下如何使用一系列手段分析我们程序的瓶颈。
1)首先attach to JVM。选择我们本地启动的应用。
2)Telemetries:展示内存、GC行为、类数量、线程数、CPU负载情况
3)Live memory:展示内存对象数量、内存calltree等信息。我们可以通过内存call tree准确的查到哪段代码创建了较多的对象,从而解决内存泄露等问题。
4)Heap Walker:使用此模块获取dump文件用于堆分析,多用于分析线程卡死和内存溢出。
5)CPU views:cpu视图,可通过此模块获取到cpu的calltree和热点代码,使用此功能我们能较好的定位每一行java语句执行时间。树状图的每一个子集即代表着调用了下一级的方法。
6)Treads:线程能检测,可以用于监测哪些线程有真正的调用起来,主要用于解决线程假死、线程阻塞等问题。
7)Databases:数据库监测模块,我们可以通过此处看到当前jvm有多少connections、连接时长、以及数据库调用代码的执行树和热点树。同时还支持对mongodb、hbase等数据库的访问监测。
8)JEE&Probes:用于接口统计,我们可以用此功能监测哪些请求是热点请求,以及请求时间。
4、oracle性能监测
当我们使用上面的手段来分析清算系统并把该优化的代码优化完成以后还发现性能不达标的时候或者我们已经确定是数据库出现瓶颈的时候,我们就要对数据库(包含数据库参数和代码sql)动手了。当然也可以按系统真实情况,选择先进行数据库优化也可。
说到oralce性能分析,我们的主角awr就要登场了。需注意的是10g以后版本的oracle才提供这种性能收集分析工具。
awr每小时对v$active_session_history视图采样一次,并持久化到硬盘保留7天,7天后旧的记录会被覆盖。
那么一般数据库性能都有什么瓶颈呢?一般就是CPU、内存、和I/O了。如果是I/O的话,我们在清算中通过nmon监控也可以初见端倪,如果非要确定是那一条语句,那么还是来到本章来看看awr报告是怎么生成的吧。
1、如何生成awr
1)登陆oracle 服务器,并跳转到想要生成报告的目录。例如:/home/oracle
2)连接数据库实例。例如:sqlplus / as sysdba
或 sqlplus test/test
3)执行如下对应语句,一般我们使用第一个单实例报告即可。
语句 | 描述 |
---|---|
@?/rdbms/admin/awrrpt; | 本实例AWR报告 |
@?/rdbms/admin/awrrpti; | 包括RAC中选择实例号 |
@?/rdbms/admin/awrddrpt; | AWR 比对报告 |
@?/RDBMS/admin/awrgrpt; | RAC全局AWR报告 |
4)输入报告类型,默认html
5)选择最近1天多多天的数据
6)选择0点到4点的(例子)
7)输入报告名称以html结尾
8)生成成功,返回到用户目录查看lst结尾的文件即可
那么问题来了,如果最小一个小时的周期数据太多了,不方便我们分析问题怎么办呢?oracle也提供了一个方法,那就是快照。我们需要在我们要收集的时间段代码执行前打上快照,在取报告前再打另一个快照,然后取这两个快照之间的数据就行了。
打快照需要在sqlplus登陆后执行exec dbms_workload_repository.create_snapshot();
语句。
当然仅仅生成报告距离分析出问题还很遥远,还需要我们去截图awr报告,确定唯一的问题sql ,问题需具体到是哪句sql慢?为什么慢?是否有数据库参数配置的不得当?是否由于I/O导致写数据瓶颈?是否由于Oracle硬解析sql语句导致CPU瓶颈?是否由于oracle bug或参数问题导致执行计划异常?预知后续请听下回分解。