什么是系统平均负载(Load Average)?Load Average是CPU的Load,它所包含的信息不是CPU的使用率状况,而是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息。load average 表示机器一段时间内的平均load。这个值越低越好。负载过高会导致机器无法处理其他请求及操作,甚至导致死机。 系统平均负载被定义为在特定时间间隔内运行队列中的平均进程树。如果一个进程满足以下条件则其就会位于运行队列中: - 它没有在等待I/O操作的结果 - 它没有主动进入等待状态(也就是没有调用'wait') - 没有被停止(例如:等待终止) 什么影响系统负载Linux的负载高,主要是由于CPU使用、内存使用、IO消耗三部分构成。任意一项使用过多,都将导致服务器负载的急剧攀升。 怎么查看机器负载uptime [root@init ~]# uptime 10:43:03 up 18 days, 12:22, 2 users, load average: 0.00, 0.01, 0.05 uptime 命令能够打印系统总共运行了多长时间和系统的平均负载。uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。w命令 [root@init ~]# w 10:45:06 up 18 days, 12:24, 2 users, load average: 0.00, 0.01, 0.05 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 118.24.213.153 10:03 2.00s 0.11s 0.11s -bash root pts/1 118.24.213.153 10:25 12:02 0.21s 0.15s vim 2019-07-16-18-24-13.txt w命令的主要功能其实是显示目前登入系统的用户信息。但是与who不同的是,w命令功能更加强大,w命令还可以显示:当前时间,系统启动到现在的时间,登录用户的数目,系统在最近1分钟、5分钟和15分钟的平均负载。然后是每个用户的各项数据,项目显示顺序如下:登录帐号、终端名称、远 程主机名、登录时间、空闲时间、JCPU、PCPU、当前正在运行进程的命令行。 top命令 [root@init ~]# top top - 10:46:16 up 18 days, 12:25, 2 users, load average: 0.00, 0.01, 0.05 Tasks: 201 total, 1 running, 200 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.1 sy, 0.0 ni, 99.9 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 16266396 total, 338700 free, 414376 used, 15513320 buff/cache KiB Swap: 0 total, 0 free, 0 used. 15366108 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 27209 root 200677088170441988 S 0.7 0.1 122:16.24 barad_agent 16628 root 200571356111683112 S 0.3 0.1 3:28.59 YDService 22994 root 2001984431121840 S 0.3 0.0 9:09.03 haproxy 27207 root 2001574527528992 S 0.3 0.0 0:16.10 barad_agent 288967020018448857564156 S 0.3 0.0 0:11.83 postgres 1 root 20019218047242196 S 0.0 0.0 17:55.27 systemd 2 root 200000 S 0.0 0.0 0:00.82 kthreadd 3 root 200000 S 0.0 0.0 1:47.45 ksoftirqd/0 5 root 0 -20 000 S 0.0 0.0 0:00.00 kworker/0:0H top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。 top命令详解 第一行:(当前系统时间) (系统以及运行时间) (系统负载 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。) 第二行: Tasks: 29 total 进程总数 1 running 正在运行的进程数 28 sleeping 睡眠的进程数 0 stopped 停止的进程数 0 zombie 僵尸进程数 第三行: Cpu(s): 0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间占用CPU百分比 0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比 98.7% id 空闲CPU百分比 0.0% wa 等待输入输出的CPU时间百分比 0.0% hi 硬中断占用cpu的百分比 0.0% si 软中断占用cpu百分比 %st:被虚拟机偷走的cpu 0.0% wa 的百分比可以大致的体现出当前的磁盘io请求是否频繁。如果 wa的数量比较大,说明等待输入输出的的io比较多。 第四行: KiB Mem : 1016916 total 内存总量(我这里是1G) free 内存空闲量 used 内存使用量 buff/cache 缓存的内存量 第五行: KiB Swap: 0 total 交换区总量 KiB Swap: 0 total 交换区总量 0 used交换区使用量 第六行: PID 进程号 USER 进程创建者 PR 进程优先级 NI nice值。越小优先级越高,最小-20,最大20(用户设置最大19) VIRT 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES RES 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA SHR 共享内存大小,单位kb S 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 %CPU 进程占用cpu百分比 %MEM 进程占用内存百分比 TIME+ 进程运行时间 COMMAND 进程名称
top命令(进入后使用) P:以占据CPU百分比排序 M:以占据内存百分比排序 T:以累积占用CPU时间排序 q:退出命令:按q键退出top查看页面 s:修改刷新时间间隔。按下s键,然后按下数字,即可修改刷新时间间隔为你输入的数字,单位为秒。例如:按下s键,在按数字1键,即可实现每秒刷新一次 k:终止指定的进程。按下k键-->再输入要杀死的进程的pid-->按enter键-->(选择信号类型,以数字标示,默认15为杀死)本步可省略按enter键(常用为-9) 机器的正常负载范围对一般的系统来说,是根据cpu数量去判断系统是否已经过载(Over Load)的。如果我们认为0.7算是单核机器负载的安全线的话,那么四核机器的负载最好保持在(4*0.7 = 2.8)以下。一般情况下,1分钟系统负荷表示最近的暂时现象。15分钟系统负荷表示是持续现象,并非暂时问题。如果load15较高,而load1较低,可以认为情况有所好转。反之,情况可能在恶化。 如何降低系统负载导致负载高的原因可能很复杂,有可能是硬件问题也可能是软件问题。 如果是硬件问题,那么说明机器性能确实就不行了,那么解决起来很简单,直接换机器就可以了。 另外,CPU使用、内存使用、IO消耗都可能导致负载高。 如果是软件问题,有可能由于Java中的某些线程被长时间占用、大量内存持续占用等导致。建议从以下几个方面排查代码问题: 1、是否有内存泄露导致频繁GC 2、是否有死锁发生 3、是否有大字段的读写 4、会不会是数据库操作导致的,排查SQL语句问题。 如果发现线上机器Load飙高,可以考虑先把堆栈内存dump下来后,进行重启,暂时解决问题,然后再考虑回滚和排查问题。 到底什么是ioio涉及到的概念
io模式IO模式
select、poll、epoll详解
查看磁盘io的三种方式1.用 top 命令中的cpu 信息观察 0.0% wa 的百分比可以大致的体现出当前的磁盘io请求是否频繁。如果 wa的数量比较大,说明等待输入输出的的io比较多。 2.vmstat [root@init ~]# vmstat 2 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1003168722434841529482800167311329400 00031599624348415294828000189416720010000 0003163842434841529482800006174820010000 00031624424348415294832000685934710010000 00031661624348415294832000147125060010000 vmstat 命令报告关于线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息。由 vmstat 命令生成的报告可以用于平衡系统负载活动。系统范围内的这些统计信息(所有的处理器中)都计算出以百分比表示的平均值,或者计算其总和。
3.iostat 安装: Iostat 是 sysstat 工具集的一个工具,需要安装。 Centos的安装方式是: yum install sysstat Ubuntu的安装方式是: aptitude install sysstat [root@init ~]# iostat -dx Linux 3.10.0-862.el7.x86_64 (init)07/17/2019 _x86_64_ (8 CPU) 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.01 18.89 0.83 37.11 102.06 459.69 29.61 0.41 10.72 38.96 10.09 0.72 2.75 vdb 0.00 0.17 0.02 2.08 0.71 22.21 21.84 0.01 5.47 12.11 5.40 0.99 0.21 vdc 0.19 12.43 1.13 10.12 21.28 98.28 21.26 0.04 3.54 2.09 3.71 0.36 0.40 scd0 0.00 0.00 0.00 0.00 0.02 0.00 64.78 0.00 0.33 0.33 0.00 0.26 0.00 使用: iostat -dx 显示磁盘扩展信息 r/s 和 w/s 分别是每秒的读操作和写操作,而rKB/s 和wKB/s 列以每秒千字节为单位显示了读和写的数据量 如果这两对数据值都很高的话说明磁盘io操作是很频繁。 4.查看io较高的进程 [root@init ~]# iotop Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --system --deserialize 16 2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd] 3 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0] 5 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/0:0H] 7 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [migration/0] 8 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_bh] 9 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_sched] 10 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [lru-add-drain] 11 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [watchdog/0] 12 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [watchdog/1] 13 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [migration/1] java应用load飙高排查1、使用uptime查看当前load,发现load飙高。 ➜ ~ uptime 13:29 up 23:41, 3 users, load averages: 101010 2、使用top命令,查看占用CPU较高的进程ID。 ➜ ~ top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1893 admin 200 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 200 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)类。那么就可以去排查这个类是否用法有问题了 ---------------------------------------------------------------------------------------------------------------------- 我们尊重原创,也注重分享,文章来源于微信公众号:Devops小王子,建议关注公众号查看原文。如若侵权请联系qter@qter.org。 ---------------------------------------------------------------------------------------------------------------------- |