type
status
date
slug
summary
tags
category
icon
password

1、内存瓶颈

1.1 free

free 是查看内存使用情况,包括物理内存、交换内存 (swap) 和内核缓冲区内存。
free -h -s 3 表示每隔三秒输出一次内存情况,命令如下
  • Mem:是内存的使用情况。
  • Swap:是交换空间的使用情况。
  • total: 系统总的可用物理内存和交换空间大小。
  • used: 已经被使用的物理内存和交换空间。
  • free: 还有多少物理内存和交换空间可用使用,是真正尚未被使用的物理内存数量
  • shared:被共享使用的物理内存大小。
  • buff/cache:被 buffer(缓冲区) 和 cache(缓存) 使用的物理内存大小。
  • available: 还可以被应用程序使用的物理内存大小,它是从应用程序的角度看到的可用内存数量,available ≈ free + buffer + cache
交换空间 (swap space)
swap space 是磁盘上的一块区域,当系统物理内存吃紧时,Linux 会将内存中不常访问的数据保存到 swap 上,这样系统就有更多的物理内存为各个进程服务,而当系统需要访问 swap 上存储的内容时,再将 swap 上的数据加载到内存中,这就是常说的换出和换入。交换空间可以在一定程度上缓解内存不足的情况,但是它需要读写磁盘数据,所以性能不是很高。

1.2 vmstat(推荐)

vmstat(VirtualMeomoryStatistics,虚拟内存统计)是 Linux 中监控内存的常用工具,可对操作系统的虚拟内存、进程、CPU 等的整体情况进行监视,推荐使用。
vmstat 5 3 表示每隔 5 秒统计一次,一共统计三次。
procs
  • r:表示运行和等待 CPU 时间片的进程数(就是说多少个进程真的分配到 CPU),这个值如果长期大于系统 CPU 个数,说明 CPU 不足,需要增加 CPU
  • b:表示在等待资源的进程数,比如正在等待 I/O 或者内存交换等。
memory
  • swpd:表示切换到内存交换区的内存大小,即虚拟内存已使用的大小(单位 KB),如果大于 0,表示你的机器物理内存不足了,如果不是程序内存泄露的原因,那么你该升级内存了或者把耗内存的任务迁移到其他机器
  • free:表示当前空闲的物理内存。
  • buff:表示缓冲大小,一般对块设备的读写才需要缓冲
  • cache:表示缓存大小,一般作为文件系统进行缓冲,频繁访问的文件都会被缓存,如果 cache 值非常大说明缓存文件比较多,如果此时 io 中的 bi 比较小,说明文件系统效率比较好。
swap
  • si:表示数据由磁盘读入内存;通俗的讲就是每秒从磁盘读入虚拟内存的大小,如果这个值大于 0,表示物理内存不够用或者内存泄露了,要查找耗内存进程解决掉
  • so:表示由内存写入磁盘,也就是由内存交换区进入内存的数据大小。
注意:一般情况下 si、so 的值都为 0,如果 si、so 的值长期不为 0,则说明系统内存不足,需要增加系统内存
io
  • bi:表示由块设备读入数据的总量,即读磁盘,单位 kb/s
  • bo:表示写到块设备数据的总量,即写磁盘,单位 kb/s
注意:如果 bi+bo 的值过大,且 wa 值较大,则表示系统磁盘 IO 瓶颈。
system
  • in:表示某一时间间隔内观测到的每秒设备终端数。
  • cs:表示每秒产生的上下文切换次数,这个值要越小越好,太大了,要考虑调低线程或者进程的数目。例如在 apache 和 nginx 这种 web 服务器中,我们一般做性能测试时会进行几千并发甚至几万并发的测试,选择 web 服务器的进程可以由进程或者线程的峰值一直下调,压测,直到 cs 到一个比较小的值,这个进程和线程数就是比较合适的值了。系统调用也是,每次调用系统函数,我们的代码就会进入内核空间,导致上下文切换,这个是很耗资源,也要尽量避免频繁调用系统函数。上下文切换次数过多表示你的 CPU 大部分浪费在上下文切换,导致 CPU 干正经事的时间少了,CPU 没有充分利用,是不可取的。
注意:这两个值越大,则由内核消耗的 CPU 就越多。
CPU
  • us:表示用户进程消耗的 CPU 时间百分比,us 值越高,说明用户进程消耗 CPU 时间越多,如果长期大于 50%,则需要考虑优化程序或者算法
  • sy:表示系统内核进程消耗的 CPU 时间百分比,一般来说 us+sy 应该小于 80%,如果大于 80%,说明可能存在 CPU 瓶颈
  • id:表示 CPU 处在空间状态的时间百分比。
  • wa:表示 I/O 等待所占用的 CPU 时间百分比,wa 值越高,说明 I/O 等待越严重,根据经验 wa 的参考值为 20%,如果超过 20%,说明 I/O 等待严重,引起 I/O 等待的原因可能是磁盘大量随机读写造成的,也可能是磁盘或者监控器的贷款瓶颈(主要是块操作)造成的

1.3 sar

sar 和 free 类似 sar -r 3 每隔三秒输出一次内存信息:

2、CPU 瓶颈

查看机器 cpu 核数
查看 CPU 信息(型号)
查看物理 CPU 个数
查看每个物理 CPU 中 core 的个数 (即核数)
查看逻辑 CPU 的个数

2.1 top

在 Linux 内核的操作系统中,进程是根据虚拟运行时间(由进程优先级、nice 值加上实际占用的 CPU 时间进行动态计算得出)进行动态调度的。在执行进程时,需要从用户态转换到内核态,用户空间不能直接操作内核空间的函数。通常要利用系统调用来完成进程调度,而用户空间到内核空间的转换通常是通过软中断来完成的。例如要进行磁盘操作,用户态需要通过系统调用内核的磁盘操作指令,所以 CPU 消耗的时间被切分成用户态 CPU 消耗、系统(内核) CPU 消耗,以及磁盘操作 CPU 消耗。执行进程时,需要经过一系列的操作,进程首先在用户态执行,在执行过程中会进行进程优先级的调整(nice),通过系统调用到内核,再通过内核调用,硬中断、软中断,让硬件执行任务。执行完成之后,再从内核态返回给系统调用,最后系统调用将结果返回给用户态的进程。
top 可以查看 CPU 总体消耗,包括分项消耗,如 User,System,Idle,nice 等。常用操作:
  • Shift + H 显示 java 线程;
  • Shift + M 按照内存使用排序;
  • Shift + P 按照 CPU 使用时间(使用率)排序;
  • Shift + T 按照 CPU 累积使用时间排序;
  • 进入 top 视图按 1,可以看到多核 CPU 各 CPU 的负载情况。
第一行:15:24:11 up 8 days, 7:52, 1 user, load average: 5.73, 6.85, 7.33: 15:24:11 系统时间,up 8 days 运行时间,1 user 当前登录用户数,load average 负载均衡情况,分别表示 1 分钟,5 分钟,15 分钟负载情况。
第二行:Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie: 总进程数 17,运行数 1,休眠 16,停止 0,僵尸进程 0。
第三行:%Cpu(s): 13.9 us, 9.2 sy, 0.0 ni, 76.1 id, 0.1 wa, 0.0 hi, 0.1 si, 0.7 st用户空间 CPU 占比 13.9%,内核空间 CPU 占比 9.2%,改变过优先级的进程 CPU 占比 0%,空闲 CPU 占比 76.1IO 等待占用 CPU 占比 0.1%,硬中断占用 CPU 占比 0%,软中断占用 CPU 占比 0.1%, 当前 VM 中的 cpu 时钟被虚拟化偷走的比例 0.7%。
第四和第五行表示内存和 swap 区域的使用情况。
第七行表示:
  • PID: 进程 id
  • USER: 进程所有者
  • PR: 进程优先级
  • NI:nice 值。负值表示高优先级,正值表示低优先级
  • VIRT: 虚拟内存,进程使用的虚拟内存总量,单位 kb。VIRT=SWAP+RES
  • RES: 常驻内存,进程使用的、未被换出的物理内存大小,单位 kb。RES=CODE+DATA
  • SHR: 共享内存,共享内存大小,单位 kb
  • S: 进程状态。D = 不可中断的睡眠状态 R = 运行 S = 睡眠 T = 跟踪 / 停止 Z = 僵尸进程
  • %CPU: 上次更新到现在的 CPU 时间占用百分比
  • %MEM : 进程使用的物理内存百分比
  • TIME+ : 进程使用的 CPU 时间总计,单位 1/100 秒
  • COMMAND : 进程名称(命令名 / 命令行)
计算在 cpu load 里面的 uninterruptedsleep 的任务数量

2.2 sar

通过 sar -u 3 可以查看 CPU 总体消耗占比:
  • %user:用户空间的 CPU 使用。
  • %nice: 改变过优先级的进程的 CPU 使用率。
  • %system: 内核空间的 CPU 使用率。
  • %iowait: CPU 等待 IO 的百分比 。
  • %steal: 虚拟机的虚拟机 CPU 使用的 CPU。
  • %idle: 空闲的 CPU。
在以上的显示当中,主要看 %iowait%idle
  • %iowait 的值过高,表示硬盘存在 I/O 瓶颈;
  • %idle 的值高但系统响应慢时,有可能是 CPU 等待分配内存,此时应加大内存容量;
  • %idle 的值持续低于 10,则系统的 CPU 处理能力相对较低,表明系统中最需要解决的资源是 CPU;

3、网络瓶颈

3.1 定位丢包,错包情况

watch more /proc/net/dev 用于定位丢包,错包情况,以便看网络瓶颈,重点关注 drop (包被丢弃) 和网络包传送的总量,不要超过网络上限:
  • 最左边的表示接口的名字,Receive 表示收包,Transmit 表示发送包;
  • bytes:表示收发的字节数;
  • packets:表示收发正确的包量;
  • errs:表示收发错误的包量;
  • drop:表示收发丢弃的包量;

3.2 查看路由经过的地址

traceroute ip 可以查看路由经过的地址,常用来统计网络在各个路由区段的耗时,如:

3.3 查看网络错误

netstat -i 可以查看网络错误:
  • Iface: 网络接口名称;
  • MTU: 最大传输单元,它限制了数据帧的最大长度,不同的网络类型都有一个上限值,如:以太网的 MTU 是 1500;
  • RX-OK:接收时,正确的数据包数。
  • RX-ERR:接收时,产生错误的数据包数。
  • RX-DRP:接收时,丢弃的数据包数。
  • RX-OVR:接收时,由于过速(在数据传输中,由于接收设备不能接收按照发送速率传送来的数据而使数据丢失)而丢失的数据包数。
  • TX-OK:发送时,正确的数据包数。
  • TX-ERR:发送时,产生错误的数据包数。
  • TX-DRP:发送时,丢弃的数据包数。
  • TX-OVR:发送时,由于过速而丢失的数据包数。
  • Flg:标志,B 已经设置了一个广播地址。L 该接口是一个回送设备。M 接收所有数据包(混乱模式)。N 避免跟踪。O 在该接口上,禁用 ARP。P 这是一个点到点链接。R 接口正在运行。U 接口处于 “活动” 状态。

3.4 包的重传率

cat /proc/net/snmp 用来查看和分析 240 秒内网络包量,流量,错包,丢包。通过 RetransSegsOutSegs 来计算重传率 tcpetr=RetransSegs/OutSegs
重传率 = 292/223186≈0.13%
  • 平均每秒新增 TCP 连接数:通过 /proc/net/snmp 文件得到最近 240 秒内 PassiveOpens 的增量,除以 240 得到每秒的平均增量;
  • 机器的 TCP 连接数 :通过 /proc/net/snmp 文件的 CurrEstab 得到 TCP 连接数;
  • 平均每秒的 UDP 接收数据报:通过 /proc/net/snmp 文件得到最近 240 秒内 InDatagrams 的增量,除以 240 得到平均每秒的 UDP 接收数据报;
  • 平均每秒的 UDP 发送数据报:通过 /proc/net/snmp 文件得到最近 240 秒内 OutDatagrams 的增量,除以 240 得到平均每秒的 UDP 发送数据报;

4、磁盘瓶颈

4.1 查看磁盘剩余空间

查看磁盘剩余空间使用 df -hl 命令:

4.2 查看磁盘已使用空间

du -sh 命令是查看磁盘已使用空间的情况,这里的 “已使用的磁盘空间” 意思是指定的文件下的整个文件层次结构所使用的空间,在没给定参数的情况下,du 报告当前目录所使用的磁盘空间。其实就是显示文件或目录所占用的磁盘空间的情况
  • h:输出文件系统分区使用的情况,例如:10KB,10MB,10GB 等。
  • s:显示文件或整个目录的大小,默认单位是 KB。
du 的详细信息可以通过 man du 查看。

4.3 查看磁盘总体读写情况

iostat 查看磁盘总体的读写情况,每隔 2s 输出一次。
  • tps:该设备每秒的传输次数。
  • kB_read/s:每秒从设备(drive expressed)读取的数据量;
  • kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
  • kB_read: 读取的总数据量;
  • kB_wrtn:写入的总数量数据量;

4.4 查看磁盘详细读写情况

通过 iostat -x 1 3 可以看到磁盘详细读写情况,没隔一秒输出一次一共输出 3 次,当看到 I/O 等待时间所占 CPU 时间的比重很高的时候,首先要检查的就是机器是否正在大量使用交换空间,同时关注 iowait 占比 cpu 的消耗是否很大,如果大说明磁盘存在大的瓶颈,同时关注 await,表示磁盘的响应时间以便小于 5ms:
avg-cpu 表示总体 cpu 使用情况统计信息,对于多核 cpu,这里为所有 cpu 的平均值:
  • %user:CPU 处在用户模式下的时间百分比。
  • %nice:CPU 处在带 NICE 值的用户模式下的时间百分比。
  • %system:CPU 处在系统模式下的时间百分比。
  • %iowait:CPU 等待输入输出完成时间的百分比,如果 %iowait 的值过高,表示硬盘存在 I/O 瓶颈
  • %steal:管理程序维护另一个虚拟处理器时,虚拟 CPU 的无意识等待时间百分比。
  • %idle:CPU 空闲时间百分比,如果 % idle 值高,表示 CPU 较空闲;如果 % idle 值高但系统响应慢时,可能是 CPU 等待分配内存,应加大内存容量;如果 % idle 值持续低于 10,表明 CPU 处理能力相对较低,系统中最需要解决的资源是 CPU。
Device 表示设备信息:
  • rrqm/s:每秒对该设备的读请求被合并次数,文件系统会对读取同块 (block) 的请求进行合并
  • wrqm/s:每秒对该设备的写请求被合并次数
  • r/s:每秒完成的读次数
  • w/s:每秒完成的写次数
  • rkB/s:每秒读数据量 (kB 为单位)
  • wkB/s:每秒写数据量 (kB 为单位)
  • avgrq-sz:平均每次 IO 操作的数据量 (扇区数为单位)
  • avgqu-sz:平均等待处理的 IO 请求队列长度
  • await:平均每次 IO 请求等待时间 (包括等待时间和处理时间,毫秒为单位)
  • svctm:平均每次 IO 请求的处理时间 (毫秒为单位)
  • %util:一秒中有百分之多少的时间用于 I/O 如果 %util 接近 100%,说明产生的 I/O 请求太多,I/O 系统已经满负荷。idle 小于 70% IO 压力就较大了,一般读取速度有较多的 wait。
iostat -xmd 1 3:新增 m 选项可以在输出是使用 M 为单位。

4.5 查看最耗 IO 的进程

一般先通过 iostat 查看是否存在 io 瓶颈,再使用 iotop 命令来定位那个进程最耗费 IO:
通过 iotop -p pid 可以查看单个进程的 IO 情况:

5、应用瓶颈

5.1 查看某个进程的 PID

如查看 java 的进程的 pid,ps -ef | grep java:

5.2 查看特定进程的数量

如查看 java 进程的数量,ps -ef | grep java| wc -l

5.3 查看线程是否存在死锁

查看线程是否存在死锁,jstack -l pid

5.4 查看某个进程的线程数

ps -efL | grep [PID] | wc -l,如:
查看具体有哪些线程用 ps -Lp [PID] cu:

5.5 统计所有的 log 文件中,包含 Error 字符的行

find / -type f -name "*.log" | xargs grep "ERROR",这个在排查问题过程中比较有用:

6、总结

在使用 linux 命令时,如果想看帮助可以使用 --help 或者 man 查看帮助信息:
类别
监控命令
描述
备注
内存瓶颈
free
查看内存使用
vmstat 3 (间隔时间) 100 (监控次数)
查看 swap in/out 详细定位是否存在性能瓶颈
推荐使用
sar -r 3
和 free 命令类似,查看内存的使用情况,但是不包含 swap 的情况
cpu 瓶颈
top -H
按照 cpu 消耗高低进行排序
ps -Lp 进程号 cu
查看某个进程的 cpu 消耗排序
cat /proc/cpuinfo |grep 'processor'|wc -l
查看 cpu 核数
top
查看 cpu 总体消耗,包括分项消耗如 user,system,idle,nice 等消耗
top 然后 shift+h: 显示 java 线程,然后 shift+M: 按照内存使用进行排序;shift+P: 按照 cpu 时间排序;shift+T: 按照 cpu 累计使用时间排序多核 cpu,按 “1” 进入 top 视图
专项性能排查,多核 CPU 主要看 CUP 各个内核的负载情况
sar -u 3 (间隔时间)
查看 cpu 总体消耗占比
sar -q
查看 cpu load
top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}'
计算在 cpu load 里面的 uninterruptedsleep 的任务数量 uninterruptedsleep 的任务会被计入 cpu load,如磁盘堵塞
网络瓶颈
cat /var/log/messages
查看内核日志,查看是否丢包
watch more /proc/net/dev
用于定位丢包,错包情况,以便看网络瓶颈
重点关注 drop (包被丢弃) 和网络包传送的总量,不要超过网络上限
sar -n SOCK
查看网络流量
netstat -na|grep ESTABLISHED|wc -l
查看 tcp 连接成功状态的数量
此命令特别消耗 cpu,不适合进行长时间监控数据收集
netstat -na|awk'{print $6}'|sort |uniq -c |sort -nr
看 tcp 各个状态数量
netstat -i
查看网络错误
ss state ESTABLISHED| wc -l
更高效地统计 tcp 连接状态为 ESTABLISHED 的数量
cat /proc/net/snmp
查看和分析 240 秒内网络包量,流量,错包,丢包
用于计算重传率 tcpetr=RetransSegs/OutSegs
ping $ip
测试网络性能
traceroute $ip
查看路由经过的地址
常用于定位网络在各个路由区段的耗时
dig $ 域名
查看域名解析地址
dmesg
查看系统内核日志
磁盘瓶颈
iostat -x -k -d 1
详细列出磁盘的读写情况
当看到 I/O 等待时间所占 CPU 时间的比重很高的时候,首先要检查的就是机器是否正在大量使用交换空间,同时关注 iowait 占比 cpu 的消耗是否很大,如果大说明磁盘存在大的瓶颈,同时关注 await,表示磁盘的响应时间以便小于 5ms
iostat -x
查看系统各个磁盘的读写性能
重点关注 await 和 iowait 的 cpu 占比
iotop
查看哪个进程在大量读取 IO
一般先通过 iostat 查看是否存在 io 瓶颈,再定位哪个进程在大量读取 IO
df -hl
查看磁盘剩余空间
du -sh
查看磁盘使用了多少空间
应用瓶颈
ps -ef
grep java
查看某个进程的 id 号
ps -ef | grep httpd| wc -l
查看特定进程的数量
cat ***.log | grep ***Exception| wc -l
统计日志文件中包含特定异常数量
jstack -l pid
用于查看线程是否存在死锁
awk'{print $8}' 2017-05-22-access_log|egrep '301|302'| wc -l
统计 log 中 301、302 状态码的行数,$8 表示第八列是状态码,可以根据实际情况更改
常用于应用故障定位
grep 'wholesaleProductDetailNew' cookie_log | awk '{if($10=="200")}'print}' | awk 'print $12' | more
打印包含特定数据的 12 列数据
grep "2017:05:22" cookielog | awk '($12>0.3){print $12 "--" $8}' | sort > 目录地址
对 apache 或者 nginx 访问 log 进行响应时间排序,$12 表示 cookie log 中的 12 列表示响应时间 用于排查是否是由于是某些访问超长造成整体的 RT 变长
grep -v 'HTTP/1.1" 200'
取出非 200 响应码的 URL
pgm -A -f $ 应用集群名称 "grep"'301' log 文件地址 | wc -l"
查看整个集群的 log 中 301 状态码的数量
ps -efL | grep [PID] | wc -l
查看某个进程创建的线程数
find / -type f -name "*.log" | xargs grep "ERROR"
统计所有的 log 文件中,包含 Error 字符的行
这个在排查问题过程中比较有用
jstat -gc [pid]
查看 gc 情况
jstat -gcnew [pid]
查看 young 区的内存使用情况,包括 MTT (最大交互次数就被交换到 old 区),TT 是目前已经交换的次数
jstat -gcold
查看 old 区的内存使用情况
jmap -J-d64 -dump:format=b,file=dump.bin PID
dump 出内存快照
-J-d64 防止 jmap 导致虚拟机 crash (jdk6 有 bug)
-XX:+HeapDumpOnOutOfMemeryError
在 java 启动时加入,当出现内存溢出时,存储内存快照
jmap -histo [pid]
按照对象内存大小排序
注意会导致 full gc
gcore [pid]
导出完成的内存快照
通常和 jmap -permstat /opt/**/java gcore.bin 一起使用,将 core dump 转换成 heap dump
-XX:HeapDumpPath=/home/logs -Xloggc:/home/log/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
在 Java 启动参数中加入,打印 gc 日志
-server -Xms4000m -Xmx4000m -Xmn1500m -Xss256k -XX:PermSize=340m -XX:MaxPermSize=340m -XX:+UseConcMarkSweepGC
调整 JVM 堆大小
xss 是栈大小
Hexo+GitHub搭建个人博客教程JVM系列:JVM参数汇总
mcbilla
mcbilla
一个普通的干饭人🍚
Announcement
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎来到飙戈的博客🎉
-- 感谢您的支持 ---
👏欢迎学习交流👏