平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load、cpu、mem、qps、rt等。每个指标都有其独特的意义,很多时候在线上出现问题时,往往会伴随着某些指标的异常。大部分情况下,在问题发生之前,某些指标就会提前有异常显示。

对于这些指标的理解和查看、异常解决等,是程序员们重要的必备技能。本文,主要来介绍一下一个比较重要的指标——机器负载(Load),主要涉及负载的定义、查看负载方式、负载飙高排查思路等。

什么是负载

负载(load)是linux机器的一个重要指标,直观了反应了机器当前的状态。

来看下负载的定义是怎样的:

In UNIX computing, the system load is a measure of the amount of computational work that a computer system performs. The load average represents the average system load over a period of time. It conventionally appears in the form of three numbers which represent the system load during the last one-, five-, and fifteen-minute periods.(wikipedia)

简单解释一下:在UNIX系统中,系统负载是对当前CPU工作量的度量,被定义为特定时间间隔内运行队列中的平均线程数。load average 表示机器一段时间内的平均load。这个值越低越好。负载过高会导致机器无法处理其他请求及操作,甚至导致死机。

Linux的负载高,主要是由于CPU使用、内存使用、IO消耗三部分构成。任意一项使用过多,都将导致服务器负载的急剧攀升。

       /proc/loadavgThe  first  three fields in this file are load average figures giving the number of jobs in the run queue (stateR) or waiting for disk I/O (state D) averaged over 1, 5, and 15 minutes.  They are the same as the load  averagenumbers  given  by  uptime(1) and other programs.  The fourth field consists of two numbers separated by a slash(/).  The first of these is the number of currently executing kernel scheduling entities  (processes,  threads);this  will  be  less  than  or  equal  to the number of CPUs.  The value after the slash is the number of kernelscheduling entities that currently exist on the system.  The fifth field is the PID of the process that was mostrecently created on the system.

这段话大意是说,loadavg文件中前三个字段是平均负载值,分别代表1、5和15分钟的作业(job)数量的平均值,作业(job)包括运行队列(state R)或者等待磁盘I/O(state D)两种类型。这里面有这么几层信息:
  1. /proc/loadavg中前三个数字分别表示load1、load5、load15的值。
  2. load值代表的是对应时间内的jobs的平均数量,比如load1就表示过去1分钟内的jobs数量的平均值。job主要是一个shell概念,和进程组概念近似,这里应该属于用词不当(后面会分析,准确的用词应该是内核中的tasks或用户空间中的threads概念)。
  3. 而且只包含state状态为R和D的两种jobs,其他state状态不包含在内。

查看机器负载。

在Linux机器上,有多个命令都可以查看机器的负载信息。其中包括uptimetopw等。

uptime命令

uptime命令能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。

➜  ~ uptime
13:29  up 23:41, 3 users, load averages: 1.74 1.87 1.97
复制代码

这行信息的后半部分,显示"load average",它的意思是"系统的平均负荷",里面有三个数字,我们可以从中判断系统负荷是大还是小。

1.74 1.87 1.97 这三个数字的意思分别是1分钟、5分钟、15分钟内系统的平均负荷。我们一般表示为load1、load5、load15。

w命令

w命令的主要功能其实是显示目前登入系统的用户信息。但是与who不同的是,w命令功能更加强大,w命令还可以显示:当前时间,系统启动到现在的时间,登录用户的数目,系统在最近1分钟、5分钟和15分钟的平均负载。然后是每个用户的各项数据,项目显示顺序如下:登录帐号、终端名称、远 程主机名、登录时间、空闲时间、JCPU、PCPU、当前正在运行进程的命令行。

➜  ~ w
14:08  up 23:41, 3 users, load averages: 1.74 1.87 1.97
USER     TTY      FROM              LOGIN@  IDLE WHAT
hollis   console  -                六14   23:40 -
hollis   s000     -                六14   20:24 -zsh
hollis   s001     -                六15       - w
复制代码

从上面的w命令的结果可以看到,当前系统时间是14:08,系统启动到现在经历了23小时41分钟,共有3个用户登录。系统在近1分钟、5分钟和15分钟的平均负载分别是1.74 1.87 1.97。这和uptime得到的结果相同。 下面还打印了一些登录的用户的各项数据,不详细介绍了。

top命令

top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。

➜  ~ top
Processes: 244 total, 3 running, 9 stuck, 232 sleeping, 1484 threads                                                                                                                               14:16:01
Load Avg: 1.74, 1.87, 1.97  CPU usage: 8.0% user, 6.79% sys, 85.19% idle   SharedLibs: 116M resident, 16M data, 14M linkedit. MemRegions: 66523 total, 2152M resident, 50M private, 930M shared.
PhysMem: 7819M used (1692M wired), 370M unused. VM: 682G vsize, 533M framework vsize, 6402060(0) swapins, 7234356(0) swapouts. Networks: packets: 383006/251M in, 334448/60M out.
Disks: 1057821/38G read, 350852/40G written.PID    COMMAND      %CPU TIME     #TH   #WQ  #PORT MEM    PURG   CMPRS  PGRP  PPID  STATE    BOOSTS          %CPU_ME %CPU_OTHRS UID  FAULTS    COW    MSGSENT   MSGRECV   SYSBSD    SYSMACH   CSW
30845  top          3.0  00:00.49 1/1   0    21    3632K  0B     0B     30845 1394  running  *0[1]           0.00000 0.00000    0    3283+     112    203556+   101770+   8212+     119901+   823+
30842  Google Chrom 0.0  00:47.39 17    0    155   130M   0B     0B     1146  1146  sleeping *0[1]           0.00000 0.00000    501  173746    2697   117678    37821     364228    444830    310043
复制代码

上面的输出结果中,Load Avg: 1.74, 1.87, 1.97显示的就是负载信息。

机器正常负载范围

对于机器的Load到底多少算正常的问题,一直都是很有争议的,不同人有着不同的理解。对于单个CPU,有人认为如果Load超过0.7就算是超出正常范围了。也有人认为只要不超过1都没问题。也有人认为,单个CPU的负载在2以下都可以接受。

为什么会有这么多不同的理解呢,是因为不同的机器除了CPU影响之外还有其他因素的影响,运行的程序、机器内存、甚至是机房温度等都有可能有区别。

比如,有些机器用于定时执行大量的跑批任务,这个时间段内,Load可能会飙的比较高。而其他时间可能会比较低。那么这段飙高时间我们要不要去排查问题呢?

我的建议是,最好根据自己机器的实际情况,建立一个指标的基线(如近一个月的平均值),只要日常的load在基线上下范围内不太大都可以接收,如果差距太多可能就要人为介入检查了。

但是,总要有个建议的阈值吧,关于这个值。阮一峰在自己的博客中有过以下建议:

当系统负荷持续大于0.7,你必须开始调查了,问题出在哪里,防止情况恶化。

当系统负荷持续大于1.0,你必须动手寻找解决办法,把这个值降下来。

当系统负荷达到5.0,就表明你的系统有很严重的问题,长时间没有响应,或者接近死机了。你不应该让系统达到这个值。

以上指标都是基于单CPU的,但是现在很多电脑都是多核的。所以,对一般的系统来说,是根据cpu数量去判断系统是否已经过载(Over Load)的。如果我们认为0.7算是单核机器负载的安全线的话,那么四核机器的负载最好保持在3(4*0.7 = 2.8)以下。

还有一点需要提一下,在Load Avg的指标中,有三个值,1分钟系统负荷、5分钟系统负荷,15分钟系统负荷。我们在排查问题的时候也是可以参考这三个值的。

一般情况下,1分钟系统负荷表示最近的暂时现象。15分钟系统负荷表示是持续现象,并非暂时问题。如果load15较高,而load1较低,可以认为情况有所好转。反之,情况可能在恶化。

如何降低负载

导致负载高的原因可能很复杂,有可能是硬件问题也可能是软件问题。

如果是硬件问题,那么说明机器性能确实就不行了,那么解决起来很简单,直接换机器就可以了。

前面我们提过,CPU使用、内存使用、IO消耗都可能导致负载高。如果是软件问题,有可能由于Java中的某些线程被长时间占用、大量内存持续占用等导致。建议从以下几个方面排查代码问题:

1、是否有内存泄露导致频繁GC 2、是否有死锁发生 3、是否有大字段的读写 4、会不会是数据库操作导致的,排查SQL语句问题。5、死循环

这里还有个建议,如果发现线上机器Load飙高,可以考虑先把堆栈内存dump下来后,进行重启,暂时解决问题,然后再考虑回滚和排查问题。

Java Web应用Load飙高排查思路

1、使用uptime查看当前load,发现load飙高。

➜  ~ uptime
13:29  up 23:41, 3 users, load averages: 10 10 10
复制代码

2、使用top命令,查看占用CPU较高的进程ID。

➜  ~ topPID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1893 admin     20   0 7127m 2.6g  38m S 181.7 32.6  10:20.26 java
复制代码

发现PID为1893的进程占用CPU 181%。而且是一个Java进程,基本断定是软件问题。

3、使用 top命令,查看具体是哪个线程占用率较高

➜  ~ top -Hp 1893
PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
4519 admin     20   0 7127m 2.6g  38m R 18.6 32.6   0:40.11 java
复制代码

4、使用printf命令查看这个线程的16进制

➜  ~ printf %x 4519
11a7
复制代码

5、使用jstack命令查看当前线程正在执行的方法。(Java命令学习系列(二)——Jstack)

➜  ~ jstack 1893 |grep -A 200 11a7
"thread-5" #500 daemon prio=10 os_prio=0 tid=0x00007f632314a800 nid=0x11a2 runnable [0x000000005442a000]
java.lang.Thread.State: RUNNABLE
at sun.misc.URLClassPath$Loader.findResource(URLClassPath.java:684)
at sun.misc.URLClassPath.findResource(URLClassPath.java:188)
at java.net.URLClassLoader$2.run(URLClassLoader.java:569)
at java.net.URLClassLoader$2.run(URLClassLoader.java:567)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findResource(URLClassLoader.java:566)
at org.hibernate.validator.internal.xml.ValidationXmlParser.getInputStreamForPath(ValidationXmlParser.java:248)
at com.hollis.test.util.BeanValidator.validate(BeanValidator.java:30)
复制代码

从上面的线程的栈日志中,可以发现,当前占用CPU较高的线程正在执行我代码的com.hollis.test.util.BeanValidator.validate(BeanValidator.java:30)类。那么就可以去排查这个类是否用法有问题了。

分析Linux Load高时的一个误区

区分了R和D状态线程对Linux load的影响,我们再来看一个绝大多数人都曾经历的误区。当linux系统load标高时,很多人都会去top一下,查看当前系统谁占用的CPU Usage最高。
  •   这里补充一个背景知识,只有当进程(线程)处于R状态时,才耗费CPU Usage,其他状态(包括D状态)并不耗费CPU Usage。当load高主要是由D状态线程数量过多导致的时候,此时从top中按CPU Usage的排名是不会发现任何线索的。
  •   即使当load高是由R状态线程数量过多导致,如果运行top命令时导致load高的R状态线程已经结束,此时也不会从按CPU Usage的排名的top输出中发现线索的。默认情况下,top命令是3秒中刷新,只显示3秒内的CPU Usage信息。

作者:Hollis_公众号Hollis
链接:https://juejin.im/post/5b0262edf265da0b9b079fa7
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

负载(Load)分析及问题排查相关推荐

  1. 服务器性能指标(一)——负载(Load)分析及问题排查

    转载自 服务器性能指标(一)--负载(Load)分析及问题排查 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在 ...

  2. 负载分析及问题排查极简教程

    作者 | Hollis ,来自 | Hollis 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在线上出现问题时 ...

  3. cpu使用率低负载高,原因分析-----举例命令排查过程

    原因总结 产生的原因一句话总结就是:等待磁盘I/O完成的进程过多,导致进程队列长度过大,但是cpu运行的进程却很少,这样就体现到负载过大了,cpu使用率低. 下面内容是具体的原理分析:在分析负载为什么 ...

  4. 服务器性能指标(二)——CPU利用率分析及问题排查

    转载自  服务器性能指标(二)--CPU利用率分析及问题排查 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在线 ...

  5. 线上服务器内存分析及问题排查

    转载自  线上服务器内存分析及问题排查 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在线上出现问题时,往往会伴 ...

  6. 服务器性能指标(二)-- 线上服务器内存分析及问题排查

    服务器性能指标(二)-- 线上服务器内存分析及问题排查 平常的工作中,在衡量服务器的性能时,经常会涉及到几个指标,load.cpu.mem.qps.rt等.每个指标都有其独特的意义,很多时候在线上出现 ...

  7. linux load average,Linux 平均负载 Load Average 详解

    一.什么是Load Average? 系统负载(System Load)是系统CPU繁忙程度的度量,即有多少进程在等待被CPU调度(进程等待队列的长度). 平均负载(Load Average)是一段时 ...

  8. ARMS V4.3发布,应用监控全新支持内存快照分析,全息排查等功能。

    信息摘要: ARMS V4.3发布,应用监控全新支持内存快照分析,全息排查等功能. 适用客户: 企业开发和运维人员. 版本/规格功能: 1. 支持内存快照分析,内存对象分布一览无遗,内存泄露秒级定位. ...

  9. php 系统平均负载,Linux_解析Linux系统的平均负载概念,一、什么是系统平均负载(Load a - phpStudy...

    解析Linux系统的平均负载概念 一.什么是系统平均负载(Load average)?在Linux系统中,uptime.w.top等命令都会有系统平均负载load average的输出,那么什么是系统 ...

最新文章

  1. 基于yolov5的工业缺陷检测方案
  2. redis的分布式解决方式--codis (转)
  3. python 并行计算 opencv_opencv-python计算影像
  4. Hibernate框架的配置
  5. Inside ASP.NET 2.0 – Controls Model(转载)
  6. Sqlserver中查询存储过程是否包含某些文本
  7. 2019年工程造价表_2019年工程造价咨询统计公报
  8. Unity笔记(正版全阶段)目录
  9. linux 手动睡眠
  10. sql 子查询(mysql)
  11. JAVA 正则表达式 RegexUtil
  12. 自动检查点(Automatic Checkpointing)
  13. 广告点击率预测_用于广告点击率预测的逻辑回归你会了吗?
  14. html音乐播放器如何添加暂停按钮,HotKey播放/暂停HTML5音乐播放器
  15. 《NX-OS与Cisco Nexus交换技术:下一代数据中心架构(第2版)》一2.8 Cisco FabricPath...
  16. java cmd 乱码_java在cmd运行时出现乱码解决方法
  17. 一年级计算c语言编程,用C语言switch语句做一年级算术题。
  18. linux打印文件名称唯美,程序员的情人节应该这么优雅度过(附源码)
  19. 计算机无法识别打印机驱动,打印机连电脑,电脑说无法识别。为什么?
  20. 计算机考研380分难吗,考研380分相当于高考多少分的难度

热门文章

  1. Python @staticmethod
  2. Java内置的观察者模式的使用
  3. [leetcode]687. Longest Univalue Path
  4. 软件工程实践2017结对第二次作业
  5. SQL Server类型与C#类型对应关系
  6. 树莓派利用PuTTY进行远程登录
  7. 中国医学不能走西方道路
  8. 建议收藏!数据中台行业发展概况及展望
  9. uboot启动第一阶段——start.S
  10. win7怎么清理java缓存文件夹_win7系统清理电脑缓存文件的方法