Linux Performance
前言
侵入式分析工具:
C++ 性能分析的实战指南(gperftools工具)[建议收藏]
CPU篇
CPU性能指标
CPU使用率
- 用户CPU使用率:CPU使用率高,通常说明有应用程序比较繁忙。
- 系统CPU使用率:CPU使用率高,说明内核比较繁忙。
- 等待I/O的CPU使用率:iowait,表示等待I/O的时间百分比,iowait高通常说明系统与硬件设备I/O交互时间比较长。
- iowait指的是CPU等待硬盘I/O(输入/输出)操作完成的时间百分比。在这种状态下,CPU没有执行任何代码,因为它正在等待硬盘的I/O操作完成。
- 软中断和硬中断的CPU使用率,内核调用软中断处理程序,硬中断处理程序的百分比。
- 软中断和硬中断的发起者不同。
平均负载
平均负载其实就是平均活跃进程数。平均负载大于CPU数量表示CPU不足以服务线程,有些线程在等待;如果平均负载小于CPU数量,这代表还有一些余量。
主要包括三个数值,分别值过去1分钟,5分钟,15分钟的平均负载。
平均负载与 CPU 使用率关系:平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。【可运行状态是指正在使用或等待使用 CPU,而不可中断状态是指进程正执行某种 I/O 操作,比如读写磁盘】。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
上下文切换
频繁上下文切换,将时间消耗在寄存器、内核栈以及虚拟内存等数据保持与恢复上。切换分为以下两类:
-
无法获取资源而导致的自愿上下文切换。
-
被系统强制调度导致的非自愿上下文切换。
CPU缓存命中率
CPU速度比内存访问速度快得多,协调这两者巨大性能差距,使用CPU缓存。缓存的是热点的内存数据。L1 L2 L3到缓存。L1 L2常用在单核中,L3则用在多核中。L1->L3三级缓存大小依次增大,相应性能依次降低。命中率衡量的是CPU缓存的复用情况,命中率越高,则性能越好。
常用命令
命令 | 描述 |
---|---|
uptime | 平均负载 |
vmstat | 包括系统范围的CPU平均负载,上下文切换次数、中断次数、还包括处于运行和不可中断状态的进程数量 |
mpstat | 单个CPU统计信息和软中断次数 |
sar | 统计历史信息 |
ps | 进程状态和CPU使用率 |
top | 监控平均负载,运行队列、整体CPU使用率,以及每个进程/线程CPU用量 |
pidstat | 每个进程/线程CPU用量分解 |
time | 给一个命令计时,带CPU用量分解 |
Dtrace,perf | CPU剖析和跟踪 |
perf | CPU性能计数器分析,CPU缓存,cpu调度 |
uptime
功能:打印平均负载,系统运行时间
1 | (base) sv@sv-NF5280M5:/home/sv$ uptime |
最后三个数字是1,5,15分钟内的平均负载。通过这三个值可以判断系统负载在此段时间内上升,下降还是平稳。
如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势,一般当平均负载高于 CPU 数量 70% 的时候,应该分析排查负载高的问题。
查看几个 CPU数量【lscpu】
1 | (base) sv@sv-NF5280M5:/home/sv$ grep 'model name' /proc/cpuinfo | wc -l |
vmstat
(Vitual Memory Static)
功能:报告虚拟内存统计信息
具体使用vmstat --help
查看详细用法。
选项 | 功能 |
---|---|
-a | 显示活跃和非活跃内存 |
-f | 显示从系统启动至今的fork数量 |
-m | 显示slabinfo |
-s | 显示内存相关统计信息及多种系统活动数量 |
-d | 显示磁盘相关的统计信息 |
-S | 使用指定单位显示。参数有 k 、K 、m 、M ,分别代表1000、1024、1000000、1048576字节(Byte),默认单位为K(1024 Bytes) |
delay | 刷新时间间隔,如果不指定,只显示一条结果 |
count | 刷新次数,如果不指定刷新次数,但指定了刷新时间间隔,这时刷新次数为无穷 |
1 | # 间隔 1 秒后输出 1 组数据 |
类别 | 参数 | 含义 | 说明 |
---|---|---|---|
Procs | r | (Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。 | 当这个值超过了cpu个数,就会出现cpu瓶颈。如果运行队列过大,表示你的CPU很繁忙,一般会造成CPU使用率很高 |
b | 等待IO的进程数量,阻塞的进程 | ||
system | in | 每秒中断数,包括时钟中断 | 这两个值越大,会看到由内核消耗的cpu时间sy会越多这个值要越小越好,太大了,要考虑调低线程或者进程的数目 |
cs | 每秒上下文切换数 | 同上,当进行线程的切换,进行上下文切换,这个值越小越好。 | |
CPU | us | 用户进程执行消耗cpu时间 | us的值比较高时,说明用户进程消耗的cpu时间多 |
sy | 系统进程消耗cpu时间 | sys的值过高时,说明系统内核消耗的cpu资源多,例如I/O频繁操作。 | |
Id | 空闲时间(包括IO等待时间) | 一般来说 us+sy+id=100 | |
wa | 等待IO时间 | wa过高时,说明io等待比较严重,可能由于磁盘大量随机访问造成,也有可能是磁盘的带宽出现瓶颈。 | |
st | 来自于虚拟机偷取的CPU所占的百分比 | ||
io | bi | 每秒从文件系统或SWAP读入到RAM(blocks in)的块数,block(1KB磁盘块)为单位 | 随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。 |
bo | 每秒从RAM写出到文件系统或SWAP(blocks out)的块数,block(1KB磁盘块)为单位 | ||
swap | si | 每秒从SWAP(交换分区)读入到RAM(swap in)的大小,单位是KB | 内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响。 |
so | 每秒从RAM写出到SWAP(swap out)的大小,单位是KB | ||
memory | swpd | 使用的虚拟内存的大小,单位是KB | |
free | 可用的物理内存大小,单位是KB | ||
buff | 物理内存用来缓存读写操作的buffer大小,单位是KB | ||
cache | 物理内存用来缓存进程地址空间的cache大小,单位是KB |
mpstat
(Multiprocessor Statistics)
功能:报告处理器相关的统计信息。
报告每个CPU的统计信息,-p ALL 用来打印CPU的报告,默认只打印系统级别的总结信息。
参数 | 解释 |
---|---|
-P {|ALL} | 表示监控哪个CPU,例如mpstat -P 0 mpstat -P 7 mpstat -P ALL |
internal | 相邻的两次采样的间隔时间 |
count | 采样的次数,count只能和delay一起使用 |
各个字段含义
字段 | 含义 |
---|---|
%usr | 用户态占用CPU的时间(%),不包含nice值为正的进程时间,但包括了 guest 时间。 |
%nice | 代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。 |
%sys | 内核态占用CPU的时间(%) |
%iowait | 等待IO占用CPU的时间(%) |
%irq | 硬中断占用CPU的时间(%) |
%soft | 软中断占用CPU的时间(%) |
%guest | CPU处理虚拟进程花费的时间开销 |
%idle | 空闲CPU的时间(%) |
%steal | 代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。 |
top
功能:显示最消耗CPU的任务,并且有百分百。
top的使用方式 top [-d number] | top [-bnp]
参数 | 含义 |
---|---|
-d number | number代表秒数,表示top命令显示的页面更新一次的间隔 (default=5s) |
-b | 以批次的方式执行top |
-n | 与-b配合使用,表示需要进行几次top命令的输出结果 |
-p | 指定特定的pid进程号进行观察 |
top命令显示的页面还可以输入以下按键执行相应的功能(注意大小写区分的)
参数 | 含义 |
---|---|
? | 显示在top当中可以输入的命令 |
P | 以CPU的使用资源排序显示 |
M | 以内存的使用资源排序显示 |
N | 以pid排序显示 |
T | 由进程使用的时间累计排序显示 |
k | 给某一个pid一个信号,可以用来杀死进程(9) |
r | 给某个pid重新定制一个nice值(即优先级) |
q | 退出top(用ctrl+c也可以退出top) |
top各输出参数含义
一、top前五条信息解释
top - 14:49:28 up 1:33, 1 user, load average: 0.00, 0.00, 0.00
内容 | 含义 |
---|---|
14:49:28 | 表示当前时间 |
up 1:33 | 系统远行时间,格式为时:分 |
1 user | 当前登陆用户数 |
load average: 0.00, 0.00, 0.00 | 系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值 |
Tasks: 80 total, 2 running, 78 sleeping, 0 stopped, 0 zombie
内容 | 含义 |
---|---|
Tasks: 80 total | 进程总数 |
2 running | 正在运行的进程数 |
78 sleeping | 睡眠的进程数 |
0 stopped | 停止的进程数 |
0 zombie | 僵尸进程数 |
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
内容 | 含义 |
---|---|
0.0%us | 用户空间占用CPU百分比 |
0.0%sy | 内核空间占用CPU百分比 |
0.0%ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
100.0%id | 空闲CPU百分比 |
0.0%wa | 等待输入输出的CPU时间百分比 |
0.0%hi | 硬中断(Hardware IRQ)占用CPU的百分比 |
0.0%si | 软中断(Software Interrupts)占用CPU的百分比 |
0.0 st | 用于有虚拟cpu的情况,用来指示被虚拟机偷掉的cpu时间 |
Mem: 1922488k total, 406936k used, 1515552k free, 11940k buffers
内容 | 含义 |
---|---|
1922488k total | 物理内存总量 |
406936k used | 使用的物理内存总量 |
1515552k free | 空闲内存总量 |
11940k buffers | 用作内核缓存的内存量 |
Swap: 835576k total, 0k used, 835576k free, 111596k cached
内容 | 含义 |
---|---|
835576k total | 交换区总量 |
0k used | 使用的交换区总量 |
835576k free | 空闲交换区总量 |
111596k cached | 缓冲的交换区总量 |
二、进程信息
列名 | 含义 |
---|---|
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 | 命令名/命令行 |
Note:
- VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。
- RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享内存。
- SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。
- %MEM 是进程使用物理内存占系统总内存的百分比。
默认进入top时,各进程是按照CPU的占用量来排序的。
sar
功能:收集、报告或保存系统活动信息
sar是一个非常全面的一个分析工具,可以比较瑞士军刀,对文件的读写,系统调用的使用情况,磁盘IO,CPU相关使用情况,内存使用情况,进程活动等都可以进行有效的分析。
1 | -A:所有报告的总和 |
1.统计CPU使用情况
1 | (base) sv@sv-NF5280M5:/home/sv$ sar -u 1 3# 统计CPU的使用情况,每间隔1秒钟统计一次总共统计三次 |
1 | (base) sv@sv-NF5280M5:/home/sv$ sar -o test.txt -u 1 3 |
2.查看磁盘IO
查看I/O和传递速率的统计信息,每间隔1秒钟统计一次总共统计三次
1 | (base) sv@sv-NF5280M5:/home/sv$ sar -b 1 3 |
pidstat
pidstat 是sysstat软件套件的一部分,sysstat包含很多监控linux系统状态的工具,它能够从大多数linux发行版的软件源中获得。
1 | apt-get install sysstat |
功能:pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
按进程或线程打印CPU用量,包括用户态和系统态时间的分解。
cpu使用情况统计(-u),针对特定进程统计(-p)
- UID:一列代表了进程的用户标识符(User Identifier)
- PID: 进程pid
- %usr: 进程在用户态运行所占cpu时间比率
- %system: 进程在内核态运行所占cpu时间比率
- %guest :任务花费在虚拟机上的cpu使用率(运行在虚拟处理器)
- %CPU: 进程运行所占cpu时间比率
- CPU: 指示进程在哪个核运行
- Command: 拉起进程对应的命令
1 | (base) sv@sv-NF5280M5:/home/sv$ pidstat |
分析CPU性能瓶颈方法
《速查表》
通常先运行几个支持指标较多的工具,top,vmstat和pidstat
- 从 top 的输出可以得到各种 CPU 使用率以及僵尸进程和平均负载等信息。
- 从 vmstat 的输出可以得到上下文切换次数、中断次数、运行状态和不可中断状态的进程数。
- 从 pidstat 的输出可以得到进程的用户 CPU 使用率、系统 CPU 使用率、以及自愿上下文切换和非自愿上下文切换情况。
分析问题待填坑。
系统优化
- CPU 绑定:一个进程可以被设置为只在一个或者多个特定的CPU上运行,而不是在所有的CPU上随机调度。这种技术被称为CPU亲和性(CPU Affinity)。通过设置CPU亲和性,可以提高缓存命中率和内存访问性能,从而提高整体性能。
- CPU 独占:跟 CPU 绑定类似,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程。这样,这些 CPU 就由指定的进程独占,换句话说,不允许其他进程再来使用这些 CPU。
- 优先级调整:使用 nice 调整进程的优先级,正值调低优先级,负值调高优先级
- 为进程设置资源限制:使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源。
- NUMA(Non-Uniform Memory Access)优化:支持 NUMA 的处理器会被划分为多个 node,每个 node 都有自己的本地内存空间。NUMA 优化,其实就是让 CPU 尽可能只访问本地内存。
- 中断负载均衡:无论是软中断还是硬中断,它们的中断处理程序都可能会耗费大量的 CPU。开启 irqbalance 服务或者配置 smp_affinity,就可以把中断处理过程自动负载均衡到多个 CPU 上。
内存篇
内存信息
查看内存信息命令
1 | (base) sv@sv-NF5280M5:/home/sv$ cat /proc/meminfo |
查看红框信息
- MemTotal:系统总内存,由于 BIOS、内核等会占用一些内存,所以这里和配置声称的内存会有一些出入,比如我这里配置有 2G,但其实只有 1.95G 可用。
- MemFree:系统空闲内存。
- MemAvailable:应用程序可用内存。有人会比较奇怪和 MemFree 的区别,可以从两个层面来区分,MemFree 是系统层面的,而 MemAvailable 是应用程序层面的。系统中有些内存虽然被使用了但是有一部分是可以回收的,比如 Buffers、Cached 及 Slab 这些内存,这部分可以回收的内存加上 MemFree 才是 MemAvailable 的内存值,这是内核通过特定算法算出来的,是一个估算值。
- Buffers:缓冲区内存
- Cached:缓存
常用命令
free
查看内存使用
1 | (base) sv@sv-NF5280M5:/home/sv$ free |
我们观察到free 很小,buff/cache 却很大。这是由于Linux设计思想:内存闲着反正也是闲着,不如拿出来做系统缓存和缓冲区,提高数据读写的速率。
- Buffers 是内核缓冲区用到的内存,对应的是 /proc/meminfo 中的 Buffers 值。
- Cache 是内核页缓存和 Slab 用到的内存,对应的是 /proc/meminfo 中的 Cached 与 SReclaimable 之和。
Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。
Swap
交换空间是硬盘上的一块区域,它被操作系统用作虚拟内存,用来在物理内存(RAM)不足时,存放暂时不需要的内存数据。
详细来说,当系统的物理内存不足以支持当前的所有进程时,操作系统会选择一些暂时不活跃的内存页,把它们从物理内存移动到交换空间,从而释放出物理内存给当前活跃的进程使用。这个过程被称为“交换出”(Swap Out)。
反过来,当这些被交换出的内存页再次被需要时,操作系统会把它们从交换空间移回到物理内存,这个过程被称为“交换入”(Swap In)。
pmap
这个命令用于查看进程的内存映像信息,能够查看进程在哪些地方用了多少内存。常用 pmap -x pid 来查看。
可以看到该进程内存被哪些库、哪些文件所占用,据此我们定位程序对内存的使用。
几个字段介绍一下:
-
Address:占用内存的文件的内存起始地址。
-
Kbytes:占用内存的字节数。
-
RSS:实际占用内存大小。
-
Dirty:脏页大小。
-
Mapping:占用内存的文件,[anon] 为已分配的内存,[stack] 为程序堆栈
-
最后的 total 为统计的总值。我们可以使用 pmap -x pid | tail -1 这样只显示最后一行,循环显示最后一行,达到监控该进程的目的。使用:
while true; do pmap -x pid | tail -1; sleep 1; done
IO 篇
IO 和 存储密切相关,存储可以概括为磁盘,内存,缓存,三者读写的性能差距非常大,磁盘读写是毫秒级的(一般 0.1-10ms),内存读写是微妙级的(一般 0.1-10us),cache 是纳秒级的(一般 1-10ns)。
磁盘性能指标
五个常见指标
- 使用率,是指磁盘处理 I/O 的时间百分比。过高的使用率(比如超过 80%),通常意味着磁盘 I/O 存在性能瓶颈。
- 饱和度,是指磁盘处理 I/O 的繁忙程度。过高的饱和度,意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时,磁盘无法接受新的 I/O 请求。
- IOPS(Input/Output Per Second),是指每秒的 I/O 请求数(每秒读写的次数)。
- 吞吐量,是指每秒的 I/O 请求大小(每秒读写的数据量)。
- 响应时间,是指 I/O 请求从发出到收到响应的间隔时间。
常用命令
fdisk
查看磁盘信息,包括磁盘容量,扇区大小,IO 大小等信息,常用 fdisk -l 查看:
1 | (base) sv@sv-NF5280M5:/home/sv$ sudo fdisk -l |
df
查看磁盘使用情况,通常看磁盘使用率:
1 | (base) sv@sv-NF5280M5:/home/sv$ df -h |
vmstat
常用的还是这个万能的 vmstat:
1 | (base) sv@sv-NF5280M5:/home/sv$ vmstat |
对于 IO,我们常关注三个部分:
- b 值:表示因为 IO 阻塞排队的任务数
- bi 和 bo 值:表示每秒读写磁盘的块数,bi(block in)是写磁盘,bo(block out)是读磁盘。
- wa 值:表示因为 IO 等待(wait)而消耗的 CPU 比例。
一般这几个值偏大,都意味着系统 IO 的消耗较大,对于读请求较大的服务器,b、bo、wa 的值偏大,而写请求较大的服务器,b、bi、wa 的值偏大。
iostat
vmstat 虽然万能,但是它分析的东西有限,iostat 是专业分析 IO 性能的工具,可以方便查看 CPU、网卡、tty 设备、磁盘、CD-ROM 等等设备的信息,非常强大,总结下来,共有以下几种用法:
1)iostat -c 查看部分 CPU 使用情况:
1 | (base) sv@sv-NF5280M5:/home/sv$ iostat -c |
这里显示的是多个 CPU 的平均值,每个字段的含义我就不多解释了,我一般会重点关注 %iowait 和 %idle,分别表示 CPU 等待 IO 完成时间的百分比和 CPU 空闲时间百分比。
如果 %iowait 较高,则表明磁盘存在 IO 瓶颈,如果 %idle 较高,则 CPU 比较空闲,如果两个值都比较高,则有可能 CPU 在等待分配内存,瓶颈在内存,此时应该加大内存,如果 %idle 较低,则此时瓶颈在 CPU,应该增加 CPU 资源。
2)iostat -d 查看磁盘使用情况,主要是显示 IOPS 和吞吐量信息(-k : 以 KB 为单位显示,-m:以 M 为单位显示):
1 | (base) sv@sv-NF5280M5:/home/sv$ iostat -d -k |
其中,几个参数分别解释如下:
- tps:设备每秒的传输次数(transfers per second),也就是读写次数。
- kB_read/s 和 kB_wrtn/s:每秒读写磁盘的数据量。
- kB_read 和 kB_wrtn:读取磁盘的数据总量。
3)iostat -x 查看磁盘详细信息:
1 | avg-cpu: %user %nice %system %iowait %steal %idle |
其中,几个参数解释如下;
- rrqm/s 和 wrqm/s:分别每秒进行合并的读操作数和写操作数,这是什么意思呢,合并就是说把多次 IO 请求合并成少量的几次,这样可以减小 IO 开销,buffer 存在的意义就是为了解决这个问题的。
- r/s 和 w/s:每秒磁盘读写的次数。这两个值相加就是 tps。
- rkB/s 和 wkB/s:每秒磁盘读写的数据量,这两个值和上面的 kB_read/s、kB_wrnt/s 是一样的。
- avgrq-sz:平均每次读写磁盘扇区的大小。
- avgqu-sze:平均 IO 队列长度。队列长度越短越好。
- await:平均每次磁盘读写的等待时间(ms)。
- svctm:平均每次磁盘读写的服务时间(ms)。
- %util:一秒钟有百分之多少的时间用于磁盘读写操作。
以上这些参数太多了,我们并不需要每个都关注,可以重点关注两个:
a. %util:衡量 IO 的繁忙程度
这个值越大,说明产生的 IO 请求较多,IO 压力较大,我们可以结合 %idle 参数来看,如果 %idle < 70% 就说明 IO 比较繁忙了。也可以结合 vmstat 的 b 参数(等待 IO 的进程数)和 wa 参数(IO 等待所占 CPU 时间百分比)来看,如果 wa > 30% 也说明 IO 较为繁忙。
b. await:衡量 IO 的响应速度
通俗理解,await 就像我们去医院看病排队等待的时间,这个值和医生的服务速度(svctm)和你前面排队的人数(avgqu-size)有关。如果 svctm 和 await 接近,说明磁盘 IO 响应时间较快,排队较少,如果 await 远大于 svctm,说明此时队列太长,响应较慢,这时可以考虑换性能更好的磁盘或升级 CPU。
4)iostat 1 2 默认显示 cpu 和 吞吐量信息,1 定时 1s 显示,2 显示 2 条信息
iotop
用于查看每个进程的 IO 情况,有了这个命令,就可以定位具体哪个进程的 IO 开销比较大了。
总结:fdisk -l 和 df 查看磁盘基本信息,iostat -d 查看磁盘 IOPS 和吞吐量,iostat -x 结合 vmstat 查看磁盘的繁忙程度和处理效率。
网络篇
ping
ping 发送 ICMP echo 数据包来探测网络的连通性,除了能直观地看出网络的连通状况外,还能获得本次连接的往返时间(RTT 时间),丢包情况,以及访问的域名所对应的 IP 地址(使用 DNS 域名解析),比如:
1 | (base) sv@sv-NF5280M5:/home/sv/pengeHome/webbench-c$ ping www.baidu.com |
我们 ping baidu.com,-c
参数指定发包数。可以看到,解析到了 baidu 的一台服务器 IP 地址为 183.2.172.42。RTT 时间的最小、平均、最大和算术平均差分别是32.677/32.833/32.946/0.103 ms
ifconfig
ifconfig 命令被用于配置和显示 Linux 内核中网络接口的统计信息。通过这些统计信息,我们也能够进行一定的网络性能调优。
1 | (base) sv@sv-NF5280M5:/home/sv/pengeHome/webbench-c$ ifconfig |
这是关于Linux下的网络接口信息的输出。让我们逐行解释一下:
eno4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
:这是网络接口eno4的状态信息。"UP"表示接口正在运行;"BROADCAST"表示接口有广播能力;"RUNNING"表示接口是活动的;"MULTICAST"表示接口支持多播。"mtu 1500"表示最大传输单元(MTU)是1500字节,这是以太网的标准MTU。inet 10.168.157.251 netmask 255.255.255.0 broadcast 10.168.157.255
:这是IPv4的地址信息。"inet 10.168.157.251"表示IPv4地址是10.168.157.251;"netmask 255.255.255.0"表示子网掩码是255.255.255.0;"broadcast 10.168.157.255"表示广播地址是10.168.157.255。inet6 fe80::9ec2:c4ff:fe04:8a7b prefixlen 64 scopeid 0x20<link>
:这是IPv6的地址信息。"inet6 fe80::9ec2:c4ff:fe04:8a7b"表示IPv6地址是fe80::9ec2:c4ff:fe04:8a7b;"prefixlen 64"表示前缀长度是64位;"scopeid 0x20< link >"表示这是一个链路本地地址。ether 9c:c2:c4:04:8a:7b txqueuelen 1000 (以太网)
:这是物理地址信息。"ether 9c:c2:c4:04:8a:7b"表示MAC地址是9c:c2:c4:04:8a:7b;"txqueuelen 1000"表示发送队列的长度是1000。RX packets 469211354 bytes 68619885994 (68.6 GB)
:这是接收(Receive)的数据信息。"RX packets 469211354"表示接收了469211354个数据包;"bytes 68619885994 (68.6 GB)"表示接收的数据总量是68.6 GB。TX packets 101656642 bytes 33416911871 (33.4 GB)
:这是发送(Transmit)的数据信息。"TX packets 101656642"表示发送了101656642个数据包;"bytes 33416911871 (33.4 GB)"表示发送的数据总量是33.4 GB。RX errors 0 dropped 56877 overruns 0 frame 0
和TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
:这些是网络错误的统计信息。包括错误的数据包数量、丢弃的数据包数量、overruns(数据包过多,接口处理不过来)的数量等。
IP
ip 命令用来显示或设置 Linux 主机的网络接口、路由、网络设备、策略路由和隧道等信息,是 Linux 下功能强大的网络配置工具,旨在替代 ifconfig 命令,如下显示 IP 命令的强大之处,功能涵盖到 ifconfig、netstat、route 三个命令。
netstat
netstat 可以查看整个 Linux 系统关于网络的情况,是一个集多钟网络工具于一身的组合工具。
常用的选项包括以下几个:
- 默认:列出连接的套接字
- -a:列出所有套接字的信息
- -s:各种网络协议栈统计信息
- -i:网络接口信息
- -r:列出路由表
- -l:仅列出有在 Listen 的服务状态
- -p:显示 PID 和进程名称
各参数组合使用实例如下:
- netstat -at 列出所有 TCP 端口
- netstat -au 列出所有 UDP 端口
- netstat -lt 列出所有监听 TCP 端口的 socket
- netstat -lu 列出所有监听 UDP 端口的 socket
- netstat -lx 列出所有监听 UNIX 端口的 socket
- netstat -ap | grep ssh 找出程序运行的端口
- netstat -an | grep ‘:80’ 找出运行在指定端口的进程
1)netstat 默认显示连接的套接字数据
1 | (base) sv@sv-NF5280M5:/home/sv/pengeHome/webbench-c$ netstat |
2)netstat -i 显示网络接口信息
1 | ^C |
接口信息包括网络接口名称(Iface)、MTU,以及一系列接收(RX-)和传输(TX-)的指标。其中 OK 表示传输成功的包,ERR 是错误包,DRP 是丢包,OVR 是超限包。
这些参数有助于我们对网络收包情况进行分析,从而判断瓶颈所在。
3)netstat -s 显示所有网络协议栈的信息
4)netstat -r 显示路由表信息
1 | (base) sv@sv-NF5280M5:/home/sv/pengeHome/webbench-c$ netstat -r |
ifstat
ifstat 主要用来监测主机网口的网络流量,常用的选项包括:
- -a:监测主机所有网口
- -i:指定要监测的网口
- -t:在每行输出信息前加上时间戳
- -b:以 Kbit/s 显示流量数据,而不是默认的 KB/s
- -delay:采样间隔(单位是 s),即每隔 delay 的时间输出一次统计信息
- -count:采样次数,即共输出 count 次统计信息
netcat
netcat,简称 nc,命令简单,但功能强大,在排查网络故障时非常有用,因此它也在众多网络工具中有着“瑞士军刀”的美誉。
它主要被用来构建网络连接。可以以客户端和服务端的方式运行,当以服务端方式运行时,它负责监听某个端口并接受客户端的连接,因此可以用它来调试客户端程序;当以客户端方式运行时,它负责向服务端发起连接并收发数据,因此也可以用它来调试服务端程序,此时它有点像 Telnet 程序。
常用的选项包括以下几种:
- -l:以服务端的方式运行,监听指定的端口。默认是以客户端的方式运行。
- -k:重复接受并处理某个端口上的所有连接,必须与 -l 一起使用。
- -n:使用 IP 地址表示主机,而不是主机名,使用数字表示端口号,而不是服务名称。
- -p:当以客户端运行时,指定端口号。
- -s:设置本地主机发出的数据包的 IP 地址。
- -C:将 CR 和 LF 两个字符作为结束符。
- -U:使用 UNIX 本地域套接字通信。
- -u:使用 UDP 协议通信,默认使用的是 TCP 协议。
- -w:如果 nc 客户端在指定的时间内未检测到任何输入,则退出。
- -X:当 nc 客户端与代理服务器通信时,该选项指定它们之间的通信协议,目前支持的代理协议包括 “4”(SOCKS v.4),“5”(SOCKS v.5)和 “connect” (HTTPs Proxy),默认使用 SOCKS v.5。
- -x:指定目标代理服务器的 IP 地址和端口号。
下面举一个简单的例子,使用 nc 命令发送消息:
首先,启动服务端,用 nc -l 0.0.0.0 12345
监听端口 12345 上的所有连接。
1 | (base) sv@sv-NF5280M5:/home/sv$ nc -l 127.0.0.1 12345 |
然后,启动客户端,用 nc -p 1234 127.0.0.1 12345
使用 1234 端口连接服务器 127.0.0.1::12345。
1 | (base) sv@sv-NF5280M5:/home/sv$ nc -p 1234 127.0.0.1 12345 |
着就可以在两端互发数据了。
tcpdump
最后是 tcpdump,强大的网络抓包工具。虽然有 wireshark 这样更易使用的图形化抓包工具,但 tcpdump 仍然是网络排错的必备利器。
tcpdump 选项很多,我就不一一列举了,大家可以看文章末尾的引用来进一步了解。这里列举几种 tcpdump 常用的用法。
1)捕获某主机的数据包
比如想要捕获主机 200.200.200.100 上所有收到和发出的所有数据包,使用:
1 | tcpdump host 200.200.200.100 |
2)捕获多个主机的数据包
比如要捕获主机 200.200.200.1 和主机 200.200.200.2 或 200.200.200.3 的通信,使用:
1 | tcpdump host 200.200.200.1 and \(200.200.200.2 or \) |
同样要捕获主机 200.200.200.1 除了和主机 200.200.200.2 之外所有主机通信的 IP 包。使用:
1 | tcpdump ip host 200.200.200.1 and ! 200.200.200.2 |
3)捕获某主机接收或发出的某种协议类型的包
比如要捕获主机 200.200.200.1 接收或发出的 Telnet 包,使用:
1 | tcpdump tcp port 23 host 200.200.200.1 |
4)捕获某端口相关的数据包
比如捕获在端口 6666 上通过的包,使用:
1 | tcpdump port 6666 |
5)捕获某网口的数据包
比如捕获在网口 eth0 上通过的包,使用:
1 | tcpdump -i eth0 |
面试题目
Pro1:CPU 飙高 100%怎么排查
学习自:面试官:在开发过程中遇到过 CPU 100% 的情况吗?怎么排查的?
整体思路:
- 首先使用
top -c
找到 CPU 占用最高的进程; - 然后使用
top -Hp PID
找到进程下 CPU 占用最高的线程 PID,并且将十进制 PID 转换成十六进制; - 之后使用
jstack
命令导出进程快照; - 最后用
cat
命令结合grep
命令对十六进制线程 PID 进行过滤,可以定位到出现问题的代码。
详细过程:
1)找到 CPU 占用最高的进程
- 使用
top -c
命令得到进程运行列表,然后按P
按照 CPU 占用率排序; - 得到排在第一的进程的
PID:18412
。
2)找到 CPU 占用最高的线程
- 使用
top -Hp 18412
命令得到这个进程下的线程列表,然后按P
按照 CPU 占用率排序; - 得到排在第一的线程的
PID:18413
;
将十进制 PID 转换为十六进制得到47ED
。
3)导出进程快照并定位问题
- 使用
jstack
命令导出进程快照;
1 | jstack -l 18412 > ./18412.stack |
- 根据第二部得到的小写的十六进制线程 PID 使用 grep 命令进行查找;
1 | cat 18412.stack | grep '47ed' -C 8 |
- 从查询得到的堆栈信息中即可定位到有问题的代码;
cat和less命令
查看文本文件常用的命令。
1. cat
命令
cat
命令用于将文件内容全部显示在终端上,适合查看小文件。
示例:
1 | cat example.txt |
假设 example.txt
文件包含以下内容:
1 | This is line 1. |
执行 cat example.txt
后,终端会直接输出文件的所有内容。如果文件内容很长,可能会迅速滚动,导致你无法看到全部内容。
适用场景:
- 查看小型文本文件(例如配置文件)。
- 连接多个文件内容并输出,例如
cat file1.txt file2.txt > combined.txt
。
缺点:
- 如果文件非常大,内容会一次性显示完,用户难以阅读和控制输出。
2. less
命令
less
命令用于分页浏览文件内容,适合查看大型文件或需要浏览和搜索的场景。
示例:
1 | less example.txt |
假设 example.txt
也是上面的那个文件,执行 less example.txt
后,less
命令会以分页的方式打开文件,你可以使用以下操作来浏览文件内容:
- 使用箭头键上下滚动查看内容。
- 使用
Page Up
和Page Down
键来翻页。 - 按
q
键退出less
。
适用场景:
- 查看大型日志文件或长篇文本。
- 需要在文件中搜索特定内容(在
less
中可以按/
键后输入搜索关键词)。
优点:
- 对于大文件,可以分段加载,节省内存,并且可以轻松滚动和搜索。
- 提供了多种浏览文件的操作方式,使得查看文件更灵活。
举例说明
假设你有一个 log.txt
文件,里面包含成千上万行日志信息。
-
使用
cat
:1
cat log.txt
输出会直接将整个文件内容在终端中显示,内容可能会飞速滚动,难以跟踪和阅读特定部分。
-
使用
less
:1
less log.txt
你可以使用
less
逐页查看内容,并在文件中搜索感兴趣的日志信息(按/
后输入关键词)。
总结
cat
适用于快速查看文件的整体内容,尤其是小文件;less
适用于大文件的浏览和操作,提供了更多的控制和便利。
参考资料: