系统的性能是指操作系统完成任务的有效性、稳定性和响应速度。当应用出现问题时,应当从系统、网络和应用程序等方面综合排查。
1. 系统
(1)CPU
在 Linux 系统下,可以从 /proc/cpuinfo 文件中读取 CPU 信息。
- 查看 CPU 个数:$ grep 'physical id' /proc/cpuinfo
- 查看 CPU 物理核数:$ grep 'cpu cores' /proc/cpuinfo
- 查看 CPU 逻辑核数:$ grep 'siblings' /proc/cpuinfo
使用 top 命令查看 CPU 使用情况。
Cpu(s): 0.2%us, 0.2%sy, 0.0%ni, 98.4%id, 1.1%wa, 0.0%hi, 0.1%si, 0.0%st
- us(user CPU time):用户空间CPU占用率。这个数值高表示应用程序比较繁忙。
- sy(system CPU time):内核空间CPU占用率。这个数值高表示系统存在某些瓶颈。
- ni(nice CPU time):用户进程空间改变过优先级的进程CPU占用率。
- id(idle):空闲CPU占用率。
- wa(iowait):等待IO的CPU占用率。这个数值高表示 IO 存在瓶颈,可以用 iostat 等命令进一步分析。
- hi(hardware irq):硬件中断请求。由外设硬件发出的,需要有中断控制器参与,特点是快速执行。
- si(software irq):软件中断请求。由软件程序发出的中断信号,特点是延迟执行。
- st(steal time):其他虚拟机占用CPU百分比。这个数值高,要检查下宿主机或其他虚拟机是否异常。
CPU 使用率是非空闲 CPU 占比,反映了 CPU 的繁忙程度。
- CPU 密集型应用,大量进程在等待或使用 CPU,此时 CPU 使用率与平均负载呈正相关。
- I/O 密集型应用,大量进程在等待 I/O,此时平均负载会升高,但 CPU 使用率不一定很高。
平均负载不仅包括正在使用 CPU 的进程,还包括等待 CPU 或 I/O 的进程。使用 uptime 命令(top 命令或者 w 命令)查看系统平均负载。
load average: 0.23, 0.28, 0.23
这 3 个数值分别表示 1分钟、5分钟、15分钟内系统的平均负载。如果数值超过 CPU 核数,要重点查看下了。
vmstat(Virtual Meomory Statistics,虚拟内存统计),可以对操作系统的进程、内存、磁盘IO、CPU活动等进行整体监视。
$ vmstat 1 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 2533408 563268 96116 8964228 0 0 3 32 0 0 10 2 88 0 0 0 0 2533408 563128 96116 8964260 0 0 0 59 1551 2848 0 0 100 0 0 0 0 2533408 563004 96116 8964264 0 0 0 486 1775 3163 0 0 98 2 0 0 0 2533408 562724 96116 8964264 0 0 0 46 1573 2897 0 0 99 0 0 0 0 2533408 562492 96116 8964280 0 0 0 129 2023 3393 0 0 99 0 0
如何排查用户空间 CPU 使用率高?
用户空间 CPU 使用率反映了应用程序的繁忙程度,通常与我们的代码息息相关。如果想定位消耗 CPU 最多的 Java 代码,可以遵循如下思路:
1. 通过 top 命令找到 CPU 消耗最多的进程号;
2. 通过 top -Hp 进程号 命令找到 CPU 消耗最多的线程号(列名仍然为 PID);
3. 通过 printf "%x\n" 线程号 命令输出该线程号对应的 16 进制数字;
4. 通过 jstack 进程号 | grep 16进制线程号 -A 10 命令找到 CPU 消耗最多的线程方法堆栈。
(2)内存
内存是评判服务器的一个非常重要的指标。内存的多少,可能会直接影响服务器的整体性能。
内存包括物理内存(RAM)和Swap分区。当物理内存不足时,物理内存中的一部分空间被释放出来,临时保存到Swap分区,等到那些程序要运行时,再从Swap分区中把数据恢复到内存中。
$ free -h total used free shared buffers cached Mem: 7.8G 7.0G 812M 13M 260M 5.7G -/+ buffers/cache: 1.1G 6.7G Swap: 8.0G 0B 8.0G
内存中的Buffer和Cache
Buffer(缓冲区)是将内存中的数据,不立刻写入磁盘等设备,而是达到缓冲大小后再一次性写入。可以减少对磁盘的IO操作。
Cache(高速缓存)是CPU与内存之间的一种容量较小但速度很快的存储器。CPU的速度远高于内存,CPU直接从内存中存取数据时要等待一定时间,而Cache可以保存CPU刚用过或循环使用的一部分数据,当CPU再次使用这部分数据时,直接从Cache中存取,不需要再到内存中存取数据,减少了CPU等待时间。
(3)磁盘
$ iostat -dk #查看磁盘IO的TPS和吞吐量 Linux 3.10.0-514.26.2.el7.x86_64 (zabbixmon) 09/09/2019 _x86_64_ (8 CPU) Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vda 1.82 0.29 19.60 5640041 387295600 vdb 26.25 593.20 324.17 11720415812 6404949908 dm-0 18.74 593.20 324.17 11720415556 6404949908 $ iostat -dx #查看磁盘响应时间(await)和使用率(%util) Linux 3.10.0-514.26.2.el7.x86_64 (zabbixmon) 09/09/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.00 2.66 0.01 1.81 0.29 19.60 21.84 0.01 3.69 6.38 3.68 0.40 0.07 vdb 0.00 0.01 1.59 24.65 593.19 324.17 69.90 0.14 5.21 23.47 4.03 1.14 2.99 dm-0 0.00 0.00 1.60 17.15 593.19 324.17 97.90 0.14 7.31 23.44 5.81 1.60 2.99
tps:设备每秒的IO请求数。
rrqm/s:设备每秒相关的读请求有多少被合并了。
await:每个I/O请求的平均处理时间,即响应时间。
%util:磁盘繁忙程度。
2. 网络
netstat命令用来显示网络连接、路由表和网络接口信息。
$ netstat -ant Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:10050 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN tcp 0 0 10.10.3.101:10050 10.10.3.101:32940 TIME_WAIT tcp 0 0 10.10.3.101:805 10.10.1.21:2049 ESTABLISHED
LISTEN:监听TCP端口的连接请求。
ESTABLISHED:代表一个打开的连接。
CLOSE_WAIT:等待从本地发来的连接中断请求。
TIME_WAIT:等待2MSL时间以确保远程TCP接收到连接中断请求的确认。
$ netstat -ant | awk '/^tcp/ {++S[$NF]} END{ for (i in S) print i,S[i]}' TIME_WAIT 176 CLOSE_WAIT 1 ESTABLISHED 41 LISTEN 10
3. 应用程序
(1)数据库连接池
- 建立数据库连接池对象。
- 按照事先指定的参数创建初始数量的数据库连接(即:空闲连接数)。
- 对于一个数据库访问请求,直接从连接池中得到一个连接。如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大(即:最大活跃连接数),创建一个新的数据库连接。
- 存取数据库。
- 关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中。如实际空闲连接数大于初始空闲连接数则释放连接)。
- 释放数据库连接池对象(服务器停止、维护期间,释放数据库连接池对象,并释放所有连接)。