随着应用负载的增加,系统资源的使用也会升高,甚至达到极限,而性能问题的本质,就是系统资源已经达到瓶颈,但请求的处理却还不够快,无法支撑更多的请求。性能分析就是找出应用或者系统的瓶颈,并设法避免或者缓解,从而更高效的利用系统资源处理更多的请求。
一般通过六个步骤:
1)定义:平均负载是单位时间内系统处于可运行和不可中断状态的平均进程数,即平均活跃进程数,可以理解为单位时间内的活跃进程数。可运行状态的进程就是处于Runable(就绪状态)和Running(运行状态)的进程,不可中断状态的进程是处于内核态流程中的进程,常见的是正在等待硬件设备的I/O响应,当一个进程正在读写磁盘的时候,是不可以被其他进程打断的,否则会导致磁盘数据与进程数据不一致,处于不可中断状态,不可中断状态是系统对进程和硬件设备的一种保护机制。
2)如何查看
通过top命令或者uptime查看
三个指标的含义:
up:上线运行天数
user:当前有几个用户
load avarage :平均负载 1分钟 5分钟 15分钟
3)如何判断平均负载高
理想情况下是每个CPU刚好都运行着一个进程,利用率和效率都会比较高,即平均负载等于CPU个数。
查看CPU核数的命令:
当平均负载大于CPU核数的时候说明负载高。平均负载的三个值都要看,第一个是当前的平均负载,对比前两个值可以看出平均负载的变化趋势。实际情况下平均负载高于CPU核数的70%的时候我们就要开始排查负载高的原因了。一旦负载过高,就会导致服务器响应变慢。
4)如何找出平均负载高的根源
iostat:
mpstat:是一个常用的多核CPU性能分析工具,用来实时查看每个CPU的性能指标以及平均指标
pidstat:是一个常用的进程性能分析工具,用来实时查看进程的CPU、I/O、内存以及上下文切换等性能指标。
先查看一下平均负载情况:
使用stress命令模拟一个CPU使用率100%的情况
watch -d uptime实时查看平均负载的变化情况;如果负载高,但是iowait低说明是CPU使用率高导致平均负载高;
变化后的平均负载
mpstat -P ALL 5 1 使用mpstat每隔5秒输出一次所有CPU的使用率,实时查看CPU使用率变化情况;
pidstat -u 5 1:每隔5秒钟输出一组进程的数据
1)定义:单位时间内CPU繁忙程度的统计。
2)如何查看
通过top命令查看%CPU
3)如何判断CPU利用率高
us :用户CPU消耗占比
sy:内核态CPU消耗占比
ni:低优先级用态CPU时间,1-19,越大有优先级越低
id:空闲时间占比,不包括等待I/O的时间
wa:系统等待I/O时间占比
hi:系统空闲的时间占比
si:虚拟机时间占比
st:系统运行在虚拟机中的时候,被其他虚拟机占用的CPU时间
CPU利用率=1-空闲时间/总CPU时间
平均CPU利用率=1-(空闲时间new-空闲时间old)/(总CPU时间new - 总CPU时间old)
top显示了系统总体CPU和内存使用情况,以及各个进程的资源使用情况。
ps则显示了每个进程的资源使用情况
当CPU利用率达到接近100%的时候说明CPU利用率高。
平均负载的定义说明它不仅包含了正在使用CPU的进程还包括等待CPU、等待I/O的进程。CPU利用率是单位时间内CPU繁忙程度的统计,有下面三种情况:
进程类型 | 原因 | 对应情况 |
CPU密集 | 大量使用CPU进行计算会导致平均负载升高,此时两者是一致的 | 平均负载高CPU利用率高 |
I/O密集型 | 等待I/O也会导致平均负载升高,但是CPU使用率不一定高 | 平均负载高CPU利用率不一定高 |
大量等待CPU | 大量等待CPU调度的进程也会导致平均负载升高,此时CPU使用率也会比较高 | 平均负载高CPU利用率高 |
1)整机:top
2)CPU:vmstat
查看所有cpu核信息 mpstat -P ALL 2
每个进程使用cpu的用量分解信息: pidstat -u1 -p进程编号
3)内存:free
应用程序可用内存数: free -m或许free -g
pidstat -p 进程号 -r 采样间隔秒数
4)硬盘:df
查看磁盘剩余空间数: df -h
5)磁盘IO:
磁盘I/O性能评估: iostat iostat -xdk 2 3
查看额外:pidstat -d采样间隔秒数 -p 进程号
6)网络IO:ifstat
1)jps 找出目前运行的java进程
2)jinfo 查询jvm的参赛配置信息
3)jstat 实时查询jvm运行状态
4)jmap 查看当前堆快照
jmap -dimp:format=b;file=heap.prof pid -F
5)jstack 查看当前运行的线程状态
假设生产环境出现CPU占用过高,如何定位?
1.先用top命令找出CPU占比最高的
2.ps -ef或者jps进一步定位是哪个后台程序的问题
ps -ef|grep pid
3.定位到具体线程或者代码
top -Hp pid -> tid
4.将需要的线程ID转换为16进制格式(英文小写格式)
printf "%x\n" tid
5.jstack进程ID | grep(16进制线程ID小写英文) -A 60