面临的性能问题
上线前经过了性能测试,上线后却仍然出现了性能告警……
TPS不高,CPU利用率也不高,加大并发时,TPS却上不去……
当我们进行性能问题分析诊断或者性能调优时候,可以从应用程序、中间件环境、硬件环境等几个角度进行排查。
- 硬件环境:应用程序运行的机器环境,主要有3个维度CPU、内存、磁盘IO,本文主要记录针对这3个方面的分析工具
- 应用程序:通过增加资源也就是扩容可以提高系统总体的TPS,但是这种方法,往往会掩盖掉程序本身存在的设计和编码缺陷,还是需要从代码上进行分析,例如缓存设计和命中率,数据库连接设计,数据结构和算法,资源合理释放。
- 中间件环境:例如高并发下数据库mysql性能调优,通常有建索引,慢SQL分析,SQL语句优化,Buffer Pool调整等措施;Tomcat的JVM内存启动参数调优等。
CPU分析工具
image.png如果去做个统计,top可能是使用频率最高的命令了。进入top后,
- 按1可以查看到每核的详细指标
- 默认是按照CPU使用率排序,按shift+M按内存使用率排序
从上之下,从左到右,常查看的指标有 - load average:CPU任务排队情况。有3个值,统计维度分别是1分钟,5分钟,15分钟的均值。当为0时,不排队;当为1时,刚好在承受范围内,超过1后数值越大,说明排队情况越严重。如果是多核(可通过按1查看多少核,或者通过 cat /proc/cpuinfo | grep processor查看多少核)例如n, 那么当为n时表示刚好在承受范围内。根据实际的压测时间,结合1分钟,5分钟,15分钟的趋势来判断队列情况。
- Cpu(s)是cpu的使用率,常用的是us用户空间占用CPU比例,sy系统内核,id空闲cpu。其他几项含义,ni用户空间内改变过优先级的进程,wa是cpu等待io的比例,hi硬中断占用比例,si软中断占用比例,st虚拟机偷走比例。
- Mem是物理内存的各项值。物理内存的总量、剩余量、使用量、缓存内存量
- Swap是交换区的各项值。总量、剩余量、使用量,可被系统进程使用的内存。一个不太准确的计算公式,available = free + buffer /cache,也就是说极端情况下,即使free的内存为0,但是available的内存足够,也不会影响系统正常运行。内存也可以通过 free -mh命令查询,可读性更好一些
再往下就是进程的信息了,一般操作步骤是
- 从top结果中,找到占用资源最高的进程,记录进程ID
- jstack 进程ID > jstack.txt 将堆栈信息保存到文本文件中
- 使用top -Hp 进程ID,显示这个进程内线程的监控数据
- 关注占用资源最高的现成PID,使用 printf '%x' 线程PID,打印出十六进制,例如printf '%x' 1234得到4d2,这是为了配合在堆栈信息中搜索16进制标识的线程信息。
-
在上一步保存的jstack.txt中搜索上一步打印出来的十六进制的线程ID。接下来,就需要在线程信息中仔细寻找自己熟悉的业务代码了,这个步骤一般都需要结合代码进行分析
image.png -
还需要分析jvm的gc数据,可使用 jstat -gc 进程ID 3000,每隔3秒打印gc的数据,其中YGC/YGCT表示young gc的总次数和总耗时,FGC/FGCT表示full gc的总次数和总耗时,关注gc的耗时过久,全gc次数过多等异常情况。其他字段S0/S1/E/O等含义和JVM堆的术语是一致的,见下图。
image.png
image.png
内存分析工具
正如前面的top命令可以展示多维度信息,内存分析的工具也可能包含多维度的信息
- free 最基础查看内存的工具,通过man free可以查看其支持的参数,一般free -mh就够用了
-
vmstat 2 第一个参数每X秒打印一次新的值,用在测试过程中连续查看变化趋势的场景。proc列中的r是任务排队数量,如果超过了CPU个数,代表CPU很忙,出现了拥塞,一般会伴随着较高的CPU使用率。B是等待IO的进程数量。Memory和Swap分别是内存和交换区,IO中的bi是每秒读磁盘的块数,bo是每秒写磁盘块数,一块一般1024字节。
image.png
磁盘IO分析工具
分为机械硬盘和固态硬盘,也就是常说的HDD和SSD。 lsblk -d -o name,rota查看机器上的硬盘类型,查询结果中ROTA=1表示是机械硬盘。
机械硬盘拥有高速旋转的盘片,通过磁头读写机械盘片的数据,SSD没有机械结构,采用闪存存储数据,寻道时间几乎为0,因此相比机械硬盘拥有更快的读写速度,价格较高。 基于特有的结构,机械硬盘的典型IO时间等于寻址时间+旋转延时+传送时间之和,即
IO Time = Seek Time + 60 sec/Rotational Speed/2 + IO Chunk Size/Transfer Rate
通过IO时间就可以计算出,操作系统每秒进行IO操作的次数IOPS=1/IO Time。除了磁盘处理的时间,还存在IO操作在队列中等待处理的现象,这两方面都可能形成磁盘IO瓶颈。查看IO性能指标例如使用率、IOPS、吞吐量使用 iostat -mx 3 每隔3秒打印一次,显示所有磁盘的信息,此时需要通过df命令查看应用程序数据写入在哪块盘例如盘是sda,就可以使用iostat -mx sda 3只查看特定盘的IO数据。iostat的结果中,IOPS即每秒IO操作次数等于r/s+w/s,每秒IO操作大小等于rMB/s+wMB/s。avgqu-sz是IO请求的队列长度,代表请求排队的情况,await是IO请求的响应时间。%util是磁盘IO的时间百分比,越高表示越忙,但是当存在并行IO操作时,这个值为100%也可能是正常情况,根据实际情况来分析。
image.png
性能测试时,需要通过测试确认磁盘的读写速度,其中/dev/zero和/dev/null是linux系统默认的2个特殊设备文件,/dev/zero是字符设备文件,提供无限的空数据流;而/dev/null是空设备,类似“黑洞”丢弃写入其中的所有数据
image.png
#硬盘写
time dd if=/dev/zero of=/tmp/test bs=8k count=1000000
#硬盘读
time dd if=/tmp/test of=/dev/null bs=8k
#硬盘读写
time dd if=/tmp/test of=/var/test bs=64k
#bs是每次读写的大小block size
网络IO分析工具
流量实时统计的脚本,原理是基于读取/proc/net/dev 文件里的内容
运行效果
image.png
#!/bin/bash
ethn=eth0
while true
do
RX_pre=$(cat /proc/net/dev | grep $ethn | sed 's/:/ /g' | awk '{print $2}')
TX_pre=$(cat /proc/net/dev | grep $ethn | sed 's/:/ /g' | awk '{print $10}')
sleep 1
RX_next=$(cat /proc/net/dev | grep $ethn | sed 's/:/ /g' | awk '{print $2}')
TX_next=$(cat /proc/net/dev | grep $ethn | sed 's/:/ /g' | awk '{print $10}')
clear
echo -e "\t 接收 \t \t \t 发送 `date +%k:%M:%S`"
RX=$((${RX_next}-${RX_pre}))
TX=$((${TX_next}-${TX_pre}))
if [[ $RX -lt 1024 ]];then
RX="${RX}B/s"
elif [[ $RX -gt 1048576 ]];then
RX=$(echo $RX | awk '{print $1/1048576 "MB/s"}')
else
RX=$(echo $RX | awk '{print $1/1024 "KB/s"}')
fi
if [[ $TX -lt 1024 ]];then
TX="${TX}B/s"
elif [[ $TX -gt 1048576 ]];then
TX=$(echo $TX | awk '{print $1/1048576 "MB/s"}')
else
TX=$(echo $TX | awk '{print $1/1024 "KB/s"}')
fi
echo -e "$ethn \t $RX \t \t $TX "
done
网友评论