一、性能调优背景说明
1.1 生产环境中的问题
生产环境发生了内存溢出该如何处理?
生产环境应该给服务器分配多少内存合适?
如何对垃圾回收器的性能进行调优?
生产环境CPU负载飙高该如何处理?
生产环境应该给应用分配多少线程合适?
不加log,如何确定请求是否执行了某一行代码?
不加log,如何实时查看某个方法的入参与返回值?
……
1.2 为什么要调优
防止出现OOM
解决OOM
减少Full GC出现的频率
1.3 不同阶段的考虑
上线前
项目运行阶段
线上出现OOM
二、调优概述
2.1 监控的依据
运行日志
异常堆栈
GC日志
线程快照
堆转储快照
2.2 调优的大方向
合理地编写代码
充分并合理的使用硬件资源
合理地进行JVM调优
三、性能优化的步骤
3.1 性能监控(发现问题)
性能监控一种以非强行或者入侵方式收集或查看应用运营性能数据的活动。
监控通常是指一种在生产、质量评估或者开发环境下实施的带有预防或主动性的活动。
当应用相关干系人提出性能问题却没有提供足够多的线索时,首先我们需要进行性能监控,随后是性能分析。
主要会有以下几点问题:
GC频繁
cpu load过高
OOM
内存泄露
死锁
程序响应时间较长
3.2 性能分析(排查问题)
一种以侵入方式收集运行性能数据的活动,它会影响应用的吞吐量或响应性。
性能分析是针对性能问题的答复结果,关注的范围通常比性能监控更加集中。
性能分析很少在生产环境下进行,通常是在质量评估、系统测试或者开发环境下进行,是性能监控之后的步骤。
一般有以下几个方案:
打印GC日志,通过GCviewer或者 http://gceasy.io来分析异常信息
灵活运用 命令行工具、jstack、jmap、jinfo等
dump出堆文件,使用内存分析工具分析文件
使用阿里Arthas、jconsole、JVisualVM来实时查看JVM状态
jstack查看堆栈信息
3.3 性能调优(解决问题)
一种为改善应用响应性或吞吐量而更改参数、源代码、属性配置的活动,性能调优是在性能监控、性能分析之后的活动。
通常有以下几种方案:
适当增加内存,根据业务背景选择垃圾回收器
优化代码,控制内存使用
增加机器,分散节点压力
合理设置线程池线程数量
使用中间件提高程序效率,比如缓存、消息队列等
其他……
四、性能评价/测试指标
4.1停顿时间(或响应时间)
从系统层面来说:
提交请求和返回该请求的响应之间使用的时间,一般比较关注平均响应时间
常用操作的响应时间列表:
在垃圾回收环节中:
暂停时间:执行垃圾收集时,程序的工作线程被暂停的时间。
-XX:MaxGCPauseMillis
4.2 吞吐量
对单位时间内完成的工作量(请求)的量度。
在GC中:运行用户代码的事件占总运行时间的比例(总运行时间:程序的运行时间+内存回收的时间)
吞吐量为1-1/(1+n),其中-XX::GCTimeRatio=n
4.3 并发数
同一时刻,对服务器有实际交互的请求数
例如:1000个人同时在线,估计并发数在5% -15%之间,也就是同时并发量:50 - 150之间。
4.4 内存占用
Java堆区所占的内存大小
4.5 各指标相互间的关系
以高速公路通行状况为例:
吞吐量:每天通过高速公路收费站的车辆的数据(也可以理解为收费站收取的高速费)
并发数:高速公路上正在行驶的车辆的数目
响应时间:车速