针对不同层次进行性能测试的监控

在执行性能测试的过程中,监控服务端的资源消耗等也是必备内容,监控的结果是帮助测试发现问题的眼睛。然而在实操过程中大家喜欢用JMeter 工具提供的插件进行监控,但是并不推荐使用这种方式,原因如下:

  • 指标相对简单且固定,结果数据粗糙且界面显示并不是很友好;
  • 较大地增加了客户端压测机的资源开销,影响性能测试结果;
  • 特定环境下,在服务器上安装插件是不被允许的,会很不方便。

所以在这里,我们先来聊一下监控要点;

一、层次清晰

从执行一次性能测试来看,需要监控的内容有很多,重点是要能理清楚不同的监控类型,以及分别能够解决什么问题?

1、硬件层

硬件层是最容易想到的一个层面,一般包含了 CPU 的使用率内存使用率磁盘网络读写速度等,通过这些指标能够反馈出系统运行的基本情况,以及不同的 TPS 量级会消耗多少硬件资源。

2、系统层

系统层监控包括连接请求数拒绝数丢包率请求超时等,相对于基础的硬件监控而言,这些指标更能够反映出目前系统存在的瓶颈,从而为根因问题的定位提供有力的线索。

3、链路层

链路层是直接面向架构和代码的,它的监控能够帮助我们更加准确地看到代码执行了哪些函数涉及哪些服务,并且能够较为清晰地看到函数之间的调用耗时,还可以帮助定位代码存在的问题

4、业务层

业务层监控本意是帮助判断用户输入是否合规,代码逻辑是否健壮。对于性能测试而言,业务层的监控可以帮助我们发现脚本参数问题以及高并发下业务逻辑运行是否正常等,比如随着测试的进行,可能会存在商品库存不足的情况。如果有业务层面的监控,当库存低于某阈值时,可以进行一定的提示以规避此类问题。

二、定向深入

首先我们通过基本的监控可以获得一些异常点,比如 CPU 高了、磁盘在等待,这些说白了是表象问题。就比如说某位同事今天没来,通过没来这个现象并不能直接下定论说他生病了。对于监控也是这样,是否有定位根因问题的手段,CPU 高了,需不需要进行线程分析,需要哪些权限和定位工具,这些在监控部署时都需要考虑到。

1、CPU

top 是我们查看各个进程的资源占用状况最常用的命令,如下代码所示,这个命令简单却包含很大的信息量。

1
2
3
4
5
6
7
8
9
10
11
top - 18:17:47 up 158 days,  9:32,  2 users,

load average: 0.07, 0.15, 0.21

Tasks: 154 total, 1 running, 152 sleeping, 0 stopped, 1 zombie

%Cpu(s): 3.9 us, 1.3 sy, 0.0 ni, 94.6 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st

KiB Mem : 8010676 total, 337308 free, 6036100 used, 1637268 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 1223072 avail Mem

从以上的信息中,我们来介绍几个常用的重点指标

(1)load average

1
load average: 0.07, 0.15, 0.21

三个数字都是代表进程队列的长度,从左到右分别表示一分钟、 五分钟和十五分钟的数据,数字越小压力值就越低,数字越大则压力越高,然而这个数值多小算小呢?多大算大呢?以单核处理器为例,打个比方就像收费站的一个 ETC 通道一样:

  • 0 表示没有任何车辆需要通过;
  • 0 到 1 可以认为很流畅,车辆不需要任何等待就可以通过;
  • 1 表示正好在这个通道可接受范围之内;
  • 超过 1 就已经有车辆在后面排队了。

所以理想情况下,希望平均负载值在 1 以下。如果是 1 就代表目前没有可用资源了。在实际情况中,很多运维会把理想负载设置在 0.7 以下,这也是业内的一个“经验值”。

上面说的是一个单核处理器的情况,多核 CPU 的话,负载数值 / CPU 核数在 0.00~1.00 之间表示正常,理想值也是在 0.7 以内。

(2)CPU状态

从 top 中你也可以看到每种类型进程消耗的 CPU 时间百分比,如下所示:

1
%Cpu(s):  3.9 us,  1.3 sy,  0.0 ni, 94.6 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
  • us 列显示了用户进程所花费 CPU 时间的百分比。这个数值越高,说明用户进程消耗的 CPU 时间越多,可以用来分析代码中的 CPU 消耗热点。
  • sy 列表示系统进程消耗的 CPU 时间百分比。
  • ni 列表示改变优先级的进程占用 CPU 的百分比。
  • id 列表示 CPU 处于空闲状态的时间百分比。
  • wa 列显示了 I/O 等待所占用的 CPU 时间的百分比,这里 wa 的参考值为 0.5,如果长期高于这个参考值,需要注意是否存在磁盘瓶颈。
  • hi 列表示硬件中断占用 CPU 时间百分比。
  • si 列表示软件中断占用 CPU 时间百分比。
  • st 列表示当系统运行在虚拟机中时,当前虚拟机在等待 CPU 为它服务的时间;

在已经输入 top 的情况下再输入数字 1,可以查看 CPU 的核数和每个核的运行状态。如下图是两核 CPU 的运行状态。

1
2
3
%Cpu0  :  3.0 us,  1.7 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

%Cpu1 : 2.4 us, 1.0 sy, 0.0 ni, 96.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

2、内存

最常见的是通过 free 来查看 Linux 内存使用情况。

1
2
3
4
5
6
7
[root@JD ~]# free -m

total used free shared buff/cache available

Mem: 7822 5917 302 373 1602 1195

Swap: 0 0 0

通过单词的意思我们也能大概看出来 total、used、free 表示什么,它们分别是总的物理内存大小、已经被使用的物理内存和空闲的物理内存值是多少。

3、磁盘

(1)iostat

1
2
3
4
5
6
7
8
9
10
11
 [root@JD ~]# iostat -x

Linux 3.10.0-514.el7.x86_64 (JD) 01/18/2021 _x86_64_ (2 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle

5.24 0.00 1.57 0.07 0.00 93.12

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util

vda 0.00 0.29 0.57 5.30 20.50 630.14 221.82 0.07 11.53 59.83 6.36 1.18 0.69

通过这个命令你能看到磁盘实时运行的情况,一般可以优先看 idle、util 和 svctm 这几列的数值:

  • idle 代表磁盘空闲百分比;
  • util 接近 100%,表示磁盘产生的 I/O 请求太多,I/O 系统已经满负荷在工作,该磁盘可能存在瓶颈;
  • svctm 代表平均每次设备 I/O 操作的服务时间 (毫秒)。

(2)iotop

iotop 这个命令并不是 linux 原生的,需要安装,以 CentOS 7.0 为例:

1
[root@JD ~]# yum -y install iotop

安装完成之后,直接输入 iotop,示意如下,就能清楚地看到哪些进程在消耗磁盘资源。

1
2
3
6448 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % ifrit-agent

14647 be/4 root 0.00 B/s 7.70 K/s 0.00 % 0.00 % java -Dserver.port=9080

4、网络

(1)netstat

netstat 能提供 TCP 和 UDP 的连接状态等统计信息,可以简单判断网络是否存在堵塞。

1
2
3
4
5
6
7
8
9
10
11
[root@JD ~]# netstat

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address Foreign Address State

tcp 0 1 JD:49190 169.254.169.250:http FIN_WAIT1

tcp 0 0 JD:39444 169.254.169.254:http TIME_WAIT

tcp 0 0 JD:us-srv worker-18.:sentinel-ent ESTABLISHED
  • Proto:协议名(可以 TCP 协议或者 UDP 协议)。
  • recv-Q:网络接收队列还有多少请求在排队。
  • send-Q:网络发送队列有多少请求在排队。

recv-Q 和 send-Q 如果长期不为 0,很可能存在网络拥堵,这个是判断网络瓶颈的重要依据。

  • Foreign Address:与本机端口通信的外部 socket。
  • State:TCP 的连接状态。