开展服务端性能测试时,如果发现系统变慢了,我们通常都会用 uptime 或 top 命令,来观察系统的负载情况。

如上uptime命令的输出,大家知道每列的含义吗?

20:14 #当前时间

Up 53 days,3:03 #系统运行时间

Load average #分别代表过去1分钟、5分钟、15分钟的平均负载


什么是系统平均负载?


一定会有同学会说,平均负载不就是单位时间的 CPU 使用率吗?上面 0.11,就代表 CPU 使用率是 11%。其实不是这样的。


CPU 负载值在 Linux 系统中表示正在运行,处于可运行状态的平均作业数(读取一组与流程执行线程对应的机器语言的程序指令),或者非常重要,休眠但不可中断(不可交错的休眠状态))。也就是说,要计算 CPU 负载的值,只考虑正在运行或等待分配 CPU 时间的进程。不考虑正常的休眠过程(休眠状态),僵尸或停止的过程。


简单来说,平均负载是指单位时间内,系统处于可运行状态不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。


可运行状态的进程,指的是正在使用CPU或者正在等待CPU的进程,也就是我们常用 ps 命令看到处于 R 状态(Running 或 Runnable)的进程。


不可中断状态的进程,指的是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如常见是等待硬件设备的 I/O 响应。也就是我们在ps 命令看到的D状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。 比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时间的进程就处于不可中断状态。如果此时的进程被打断,就容易出现磁盘数据与进程数据不一致的问题。


所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。


因此,我们可以简单理解为,平均负载其实就是平均活跃进程数。平均活跃进程数,直观上的理解就是单位时间内的活跃进程数。 理想的状态是每个CPU上都刚好运行着一个进程,这样每个CPU都得到了充分利用。


以下是单核处理器计算机中不同负载值的含义:

  • 0.00:没有任何作业正在运行或等待 CPU 执行,即 CPU 完全空闲。因此,如果正在运行的程序(进程)需要执行任务,它会向 CPU 请求操作系统,并立即为该进程分配 CPU 时间,因为没有其他进程在竞争它。- 0.50:没有任何作业在等待,但 CPU 正在处理以前的作业,并且它正在以 50% 的容量进行处理。在这种情况下,操作系统还可以立即将 CPU 时间分配给其他进程,而无需将其置于保持状态。- 1.00:队列中没有作业,但 CPU 正在以 100% 的容量处理先前的作业,因此如果新进程请求 CPU 时间,则必须将其保留到另一个作业完成或当前 CPU 插槽时间(例如,CPU tick)到期,操作系统决定哪一个是下一个给定的进程优先级。- 1.50:CPU 工作在其容量的 100%,15个工作中有5个请求CPU时间,即 33.33%,必须排队等待其他人耗尽他们分配的时间。因此,一旦超过1.0 的阈值,就可以说系统过载,因为它不能立即处理所请求的 100% 的工作。

那么很显然,"load average"的值越低,比如等于0.05或0.03,就说明服务器的工作量越小,系统负载比较低。


多处理器和多核系统


在具有多个处理器或核心(多个逻辑 CPU)的系统中,CPU 负载的含义取决于系统中的处理器数量。因此,具有4 个处理器的计算机在达到4.0的负载之前将不会被100%使用,因此在解释由 top,uptime等命令提供的3个负载值时,你必须要做的第一件事就是将它们分开。考虑系统中存在的逻辑CPU数量,并从中得出结论。


举个例子,如果你的计算机装了 2 个 CPU,会发生什么情况呢? 2 个 CPU,意味着计算机的处理能力翻了一倍,能够同时处理的进程数量也翻了一倍。所以,2 个CPU表明系统负载可以达到 2.0,此时每个 CPU 都达到 100%的工作量。以此类推,n 个 CPU 的计算机,可接受的系统负载最大为n。芯片厂商往往在一个 CPU 内部,包含多个CPU核心,这被称为多核CPU。在系统负载方面,多核 CPU 与多 CPU 效果类似,所以考虑系统负载的时候,必须考虑这台计算机有几个 CPU、每个 CPU 有几个核心。然后,把系统负荷除以总的核心数,只要每个核心的负荷不超过 1.0,就表明计算机正常运行。


CPU使用率


如果我们观察在给定时间间隔内通过 CPU 的不同进程,则使用率表示相对于 CPU 执行与每个进程相对应的指令的那个时间间隔的时间部分。但这种只计算了运行的进程,而不包括那些正在等待,无论它们是在队列(可运行状态)还是休眠但不可中断(例如在等待输入/输出操作的结束)的部分。 因此,这个指标可以让我们了解哪些进程最大程度地挤压 CPU,但是如果系统状态过载或者未充分利用,则不能给出真实的系统状态。


现实工作中,我们经常容易把平均负载和 CPU 使用率混淆,从上面我们知道平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括正在使用 CPU 的进程,还包括等待 CPU 和等待I/O 的进程。而 CPU使用率,从上面的解释我们知道是单位时间内繁忙程度,跟平均负载并不一定完全对应。比如:


- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,这时候两者是一致的。- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高。- 大量等待 CPU 的进程调度也会导致平均负载很高,此时的 CPU 使用率也会比较高。


不同负载的处理建议


系统过载并超过1.0的负载值有时不是问题,因为即使有一些延迟,CPU也会处理队列中的作业,负载将再次降低到1.0以下的值。但是如果系统的持续负载值大于1,则意味着它无法吸收执行中的所有负载,因此其响应时间将增加,系统将变得缓慢或无响应。


- >=0.70:没有任何反应,但有必要监控 CPU 负载。如果在一段时间内保持这种状态,就必须在事情变得更糟之前进行调查。- >=1.00:存在问题,您必须找到并修复它,否则系统负载的主要高峰将导致您的应用程序变慢或无响应。- >=3.00:你的系统变得 非常慢。甚至很难从命令行操作它来试图找出问题的原因,因此修复问题需要的时间比我们之前采取的行动要长。你冒的风险是系统会更饱和,甚至可能会崩溃。- >=5.00:你可能无法恢复系统。你可以等待奇迹自发降低负载,或者如果你知道发生了什么并且可以负担得起,你可以在控制台中启动 kill-9<process_name> 之类的命令 ,并祈求它运行在某些时候,以减轻系统负荷并重新获得其控制权。否则,你肯定别无选择,只能重新启动计算机。