一、Linux 基础命令
-
grep:在文件中执行关键词搜索,并显示匹配的结果。
-c 仅显示找到的行数 -i 忽略大小写 -n 显示行号 -v 反向选择: 仅列出没有关键词的行 (invert) -r 递归搜索文件目录 -C n 打印匹配行的前后 n 行
grep login user.cpp # 在指定文件查找 login 关键词 grep login user.cpp conn.cpp # 在多个文件查找 login 关键词 grep login *.cpp # 多文件搜索的时候,可以使用通配符 grep login -r server/ # 递归搜索目录下所有文件 grep -v user user.cpp # 反向查找,查找文件中不包含 user 的行 grep -n login user.cpp # 打印行号 grep -C 3 -n login user.cpp # 打印行号并显示前后 3 行 grep -C 3 -i -n login user.cpp # 打印行号并显示前后 3 行,忽略大小写
- find:通过文件名查找文件的所在位置,文件名查找支持模糊匹配。
find [指定查找目录] [查找规则] [查找完后执行的 action] find . -name FILE_NAME find . -iname FILE_NAME # 忽略文件名称大小写 find /mnt -size 20 # 查找 /mnt 下文件大小近似 20K 的文件 find /mnt -size +20 # 查找 /mnt 下文件大小大于 20K 的文件 find /mnt -size -20 # 查找 /mnt 下文件大小小于 20K 的文件 find /mnt -type d # 按 type 查找 /mnt 中的目录 find /mnt -type f # 按 type 查找 /mnt 中的文件 find /mnt -cmin 10 # 查找 /mnt 中十分钟左右修改的 find /mnt -cmin -10 # 查找 /mnt 中十分钟以内修改的 find /mnt -cmin +10 # 查找 /mnt 中十分钟以上修改的 find /mnt -ctime 10 # 查找 /mnt 中十天左右修改的
- ls:显示文件。
-a 显示所有文件,包括隐藏文件 -l 显示详细信息:文件权限、所有者、大小和最后修改时间 ls -lh # 以单位显示文件大小
-
wc:计算文件的字节数、字数、或是行数,若不指定文件名称,或是所给予的文件名为 “-”,则 wc 会从标准输入设备读取数据。
wc [-clw] [--help] [--version] [文件...] -c 或 --bytes 或 --chars 只显示字节数 -l 或 --lines 只显示行数 -w 或 --words 只显示字数 --help 在线帮助 --version 显示版本信息
wc testfile # testfile 文件的统计信息, 包括行数、单词数、字节数 wc -l testfile
- ulimit:Linux 系统对每个登录的用户都限制其最大进程数和打开的最大文件句柄数。为了提高性能,可以根据硬件资源的具体情况设置各个用户的最大进程数和打开的最大文件句柄数。
ulimit -a # 显示当前的各种系统对用户使用资源的显示。 ulimit -u 1024 # 设置用户的最大进程数量 ulimit -n 65530 # 设置用户可以打开的最大文件句柄数
- curl http:测试 HTTP 调用,查看返回结果是否符合预期。
curl -i "http://www.zcoder.com" # 打印请求响应头信息 curl -I "http://www.zcoder.com" # 仅返回 http 头 curl -v "http://www.zcoder.com" # 打印更多的调试信息 curl -verbose "http://www.zcoder.com" # 打印更多的调试信息 curl -d 'abc=def' "http://www.zcoder.com" # 使用 post 方法提交 http 请求 curl -sw '%{http_code}' "http://www.zcoder.com" # 打印 http 响应码
- scp:远程拷贝,基于 ssh 登录进行安全的远程文件拷贝命令。
sudo apt-get install openssh-server scp zcoder@1.1.1.1:/home/zcoder/test.txt . # 下载 1.1.1.1 的文件 scp video.mp4 zcoder@1.1.1.1:/home/zcoder/ # 上传文件到 1.1.1.1 scp -r zcoder@1.1.1.1:/home/zcoder/test . # 下载 test 整个目录到本地 scp -r test zcoder@1.1.1.1:/home/zcoder/ # 上传本地 test 整个目录到 1.1.1.1
- sed:行处理,用来批量修改文本内容。
sed [options] 'command' file -i 直接修改文件内容,而不是输出到标准输出 -n 默认情况下,会输出所有行,此选项使其只输出经过脚本处理的行 s 替换 d 删除行,如果行匹配了,则该行会被删除 p 打印
sed 's/原字符串/新字符串/' 文件 # 只替换第一个匹配到的字符串 sed 's/原字符串/新字符串/g' 文件 # 替换所有能匹配到的字符串 sed '/pattern/d' 文件 # 删除所有匹配的行
- awk:列处理。
awk [options] 'program' input-file(s)
# awk 自动将每行分割成字段,通常以空格为分隔符,并将这些字段存储在内建变量 $1, $2, …中 # 其中 $0 表示整行 awk '{print $0}' filename.txt # 打印文件的每一行 awk '{print $1, $3}' filename.txt # 打印特定字段 awk '$1 == "specificText" {print $2}' filename.txt # 根据条件打印行 awk 'END {print NR}' filename.txt # 计算文件的总行数 # 修改字段分隔符,指定逗号为字段分隔符 awk -F, '{print $1, $2}' filename.csv
二、CPU 性能监控
平均负载
- 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
- 可运行状态的进程是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用
ps
命令看到的,处于R
状态(Running
或Runnable
)的进程。 - 不可中断状态的进程是指正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的
I/O
响应,也就是我们在ps
命令中看到的D
状态(Uninterruptible
Sleep
,也称为Disk
Sleep
)的进程。
- 可运行状态的进程是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用
- 平均负载其实就是平均活跃进程数。平均活跃进程数,直观上的理解就是单位时间内的活跃进程数。
使用 uptime 命令分析平均负载
- 查看机器的启动时间、登录用户、平均负载等情况,通常用于在线上应急或者技术攻关中,确定操作系统的重启时间。
[root@ubuntusrc]# uptime 13:01:52 up 46 days, 22:03, 4 users, load average: 0.13, 0.08, 0.05 当前时间: 13:01:52 系统已经运行的时间:46天22小时3分钟。 前在线用户:4 个用户,是总连接数量,不是不同用户数量(开一个终端连接就算一个用户)。 系统平均负载: 0.13, 0.08, 0.05,为最近 1 分钟、5 分钟、15 分钟的系统负载情况。
- 比如当前平均负载为 2 时,意味着什么 ?
- 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
- 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
- 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。
- 负载说明(现针对单核情况,不是单核时则乘以核数):
load < 1
:没有等待。load == 1
:系统已无额外的资源跑更多的进程了。load > 1
:进程都堵着等待资源。- 注意:
load < 0.7
时:系统很闲,要考虑多部署一些服务。0.7 < load < 1
时:系统状态不错。load == 1
时:系统马上要处理不过来了,赶紧找一下原因。load > 5
时:系统已经非常繁忙了。
平均负载与 CPU 使用率
- 平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。
- CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的。
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高。
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
CPU 使用率监测命令
top
、htop
:查询进程的 CPU、内存信息。ps
:查找进程信息。ps -ef | grep nginx
mpstat
:用于实时监控系统 CPU 的一些统计信息,包括用户态的 CPU 时间,内核态的 CPU 时间,硬中断时间、软中断时间,磁盘 IO 等待时间等。apt install sysstat mpstat -P ALL
三、CPU 上下文切换
- 把上一个任务的寄存器和计数器保存起来,然后加载新任务的寄存器和计数器,最后跳转到新任务的位置开始执行新任务。
- 根据任务的不同,CPU 的上下文切换可以分为几个不同的场景。
系统调用上下文切换
- Linux 进程既可以在用户空间运行,又可以在内核空间中运行。
- 当它在用户空间运行时,被称为进程的用户态;当它进入进入内核空间的时候,被称为进程的内核态。
- 从用户态到内核态的转变过程,需要通过系统调用来完成。
- CPU 寄存器里原来的指令位置是在用户态。但是为了执行内核态代码,需要先把用户态的位置保存起来,然后寄存器更新为内核态指令的新位置。最后跳转到内核态运行内核任务。
- 当系统调用结束后,CPU 寄存器需要恢复原来保存的用户态位置,然后再切换到用户空间,继续运行进程。一次系统调用发生了两次 CPU 上下文切换。
- 系统调用过程中对用户态的资源没有任何影响,也不会切换进程,所以也称为特权模式切换。
进程上下文切换
- 进程是由内核来管理和调度的,所以进程的切换只发生在内核态。
- 进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态。
- 在进行进程的上下文切换时,首先需要保存当前进程的内核状态和 CPU 寄存器。在此之前,必须将该进程的虚拟内存、栈等数据进行保存。接着,系统会加载下一个进程的内核状态,并刷新该进程的虚拟内存映射关系及用户栈。刷新虚拟内存映射涉及到
TLB(Translation Lookaside Buffer,即虚拟地址缓存)
的更新,这个过程对内存访问速度有显著影响。 - 单次进程上下文切换的 CPU 时间在几十纳秒到数微秒之间。特别是在进程上下文切换次数较多的情况下,很容易导致 CPU 将大量时间耗费在寄存器、内核栈以及虚拟内存等资源的保存和恢复上,进而影响 CPU 的实际使用率。
- 进程上下文切换的原因:
- 为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其它正在等待 CPU 的进程运行。(被动切换)
- 当系统资源不足的时候,进程也会被挂起,并由系统调度其他进程运行。(主动切换)
- 当进程通过睡眠函数
sleep
这样的方法将自己主动挂起时,自然也会重新调度。 - 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行。
- 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序。
线程上下文切换
- 线程与进程的区别在于:线程是调度的基本单位,而进程是资源分配基本单位。内核中的任务调度,实际调度的是线程,而进程只是给线程提供了虚拟内存、全局变量等资源。
- 当进程只有一个线程时,可以认为进程就等于线程。
- 当进程拥有多个线程时,这些线程共享虚拟内存和全局变量等资源。这些资源在上下文切换时不需要修改。
- 线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时需要保存。
- 线程的上下文切换分为两种:
- 前后两个线程属于不同进程。此时,因为资源不共享,所以切换过程就跟进程上下文切换是一样的。
- 前后两个线程属于同一个进程。此时,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据即可。
中断上下文切换
- 为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断结束后,进程仍然可以从原来的状态恢复运行。
- 跟进程上下文切换不同,中断上下文切换并不涉及到进程的用户态。中断上下文只包括内核态中断服务程序执行所必需的状态,包括 CPU 寄存器、内核堆栈、硬件中断参数等。
IO 处理能力:
1. 协程方案 => 批量读写数据,CPU 占用率比较低,减少了用户态和内核态之间的切换
(1) 发送数据,累计 100 ms 再发送
(2) 接收数据,休眠 100 ms 再去读取数据
任务是 CPU 密集型的时候,不适合使用协程方案
3. epoll_wait(10 ms)
四、查看上下文切换
- 过多的上下文切换,会把 CPU 时间消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行的时间,成了系统性能大幅下降的一个元凶。
- 可以使用 vmstat 工具查询系统的上下文切换情况。此命令显示关于内核线程、虚拟内存、磁盘 I/O 、陷阱和 CPU 占用率的统计信息。
r(Running or Runnable)
:就绪队列的长度,也就是正在运行和等待 CPU 的进程数。b(Blocked)
:处于不可中断睡眠状态的进程数。buff
:I/O 系统存储的磁盘块文件的元数据的统计信息。cache
:操作系统用来缓存磁盘数据的缓冲区,操作系统会自动调节这个参数,在内存紧张时操作系统会减少cache
的占用空间来保证其他进程可用。si
和so
较大时,说明系统频繁使用交换区,应该查看操作系统的内存是否够用。bi
和bo
代表 I/O 活动,根据其大小可以知道磁盘 I/O 的负载情况。in(interrupt)
:每秒中断的次数。cs
:表示线程环境的切换次数,此数据太大时表明线程的同步机制有问题。
lqf@ubuntu:~$ vmstat 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 0 370452 8324 525448 0 0 495 481 273 597 3 1 96 0 0
五、内存性能监控
虚拟内存和物理内存
- 操作系统有虚拟内存与物理内存的概念。
- 在很久以前,还没有虚拟内存概念的时候,程序寻址用的都是物理地址。程序能寻址的范围是有限的,这取决于 CPU 的地址线条数。比如在 32 位平台下,寻址的范围
是 2 32 2^{32} 232 也就是 4G,并且这是固定的,如果没有虚拟内存,且每次开启一个进程都给 4G 的物理内存,就可能会出现很多问题:- 因为我的物理内存是有限的,当有多个进程要执行的时候,都要给 4G 内存,这很快就分配完了,于是没有得到分配资源的进程就只能等待。当一个进程执行完了以后,再将等待的进程装入内存。这种频繁的装入内存的操作是很没效率的。
- 由于指令都是直接访问物理内存的,那么我这个进程就可以修改其他进程的数据,甚至会修改内核地址空间的数据,这是我们不想看到的。
- 因为内存是随机分配的,所以程序运行的地址也是不正确的。
- 每一个进程运行时都会得到 4G 的虚拟内存。这个虚拟内存你可以认为是每个进程都认为自己拥有 4G 的空间,这只是每个进程认为的,但是实际上,在虚拟内存对应的物理内存上,可能只对应的一点点的物理内存,实际用了多少内存,就会对应多少物理内存。
- 进程得到的这 4G 虚拟内存是一个连续的地址空间(这也只是进程认为),而实际上,它通常是被分隔成多个物理内存碎片,还有一部分存储在外部磁盘存储器上,在需要时进行数据交换。
- 进程开始要访问一个地址,它可能会经历下面的过程:
- 每次我要访问地址空间上的某一个地址,都需要把地址翻译为实际物理内存地址。
- 所有进程共享这一整块物理内存,每个进程只把自己目前需要的虚拟地址空间映射到物理内存上。
- 进程需要知道哪些地址空间上的数据在物理内存上,哪些不在(可能这部分存储在磁盘上),还有在物理内存上的哪里,这就需要通过页表来记录。
- 页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址(如果在的话)
- 当进程访问某个虚拟地址的时候,就会先去看页表,如果发现对应的数据不在物理内存上,就会发生缺页异常。
- 缺页异常的处理过程,操作系统立即阻塞该进程,并将硬盘里对应的页换入内存,然后使该进程就绪,如果内存已经满了,没有空地方了,那就找一个页覆盖,至于具体覆盖的哪个页,就需要看操作系统的页面置换算法是怎么设计的了。
页表的工作原理
- CPU 访问
VP3
时,先根据页表,找出页表中第三条的值,然后判断有效位,发现有效位为 1,DRAM
缓存命中,根据物理页号,找到物理页中的内容,返回。 - 若有效位为 0,参数缺页异常,调用内核缺页异常处理程序。内核通过页面置换算法选择一个页面作为被覆盖的页面,将该页的内容刷新到磁盘空间中。然后把
VP3
映射的磁盘文件缓存到该物理页上面,最后将页表中第三条的有效位变成 1。 - 缺页异常处理完毕后,返回中断前的指令,重新执行,此时
DRAM
缓存命中。 - 将找到的内容映射到高速缓存中,CPU 从高速缓存中获取该值,结束。
- 在创建每个进程时,内核会为进程分配 4G 的虚拟内存,当进程还没有开始运行时,这只是一个内存布局。实际上并不立即就把虚拟内存对应位置的程序数据和代码拷贝到物理内存中,只是建立好虚拟内存和磁盘文件之间的映射(存储器映射),这种映射通常通过 mmap 实现,并且这个时候数据和代码还是在磁盘上的。
- 当运行到对应的程序时,进程去寻找页表,发现页表中地址没有存放在物理内存上,而是在磁盘上,于是发生缺页异常,将磁盘上的数据拷贝到物理内存中。
- 另外在进程运行过程中,要通过
malloc
来动态分配内存时,也只是分配了虚拟内存,即为这块虚拟内存对应的页表项做相应设置,当进程真正访问到此数据时,才引发缺页异常。
内存中的 buffer 和 cache
root@ubuntu:/home/lqf# free -h
total used free shared buff/cache available
Mem: 5.9G 1.2G 1.1G 36M 3.6G 4.3G
Swap: 974M 12K 974M
- 缓存是 buffer 和 cache 两部分的总和。
- Mem 行是内存的使用情况。
- Swap 行是交换空间的使用情况。
- total 列显示系统总的可用物理内存和交换空间大小。
- used 列显示已经被使用的物理内存和交换空间。
- free 列显示还有多少物理内存和交换空间可用。
- shared 列显示被共享使用的物理内存大小。
- buff/cache 列显示被 buffer 和 cache 使用的物理内存大小。
- available 列显示还可以被应用程序使用的物理内存大小。
- buffer 和 cache 的区别:
- Buffer 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。
- Buffer 既可以用作 “将要写入磁盘数据的缓存”,也可以用作 “从磁盘读取数据的缓存”。
- Cache 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
- Cache 既可以用作 “从文件读取数据的页缓存”,也可以用作 “写文件的页缓存”。
- Buffer 是对磁盘数据的缓存,而 Cache 是对文件数据的缓存,它们既会用在读请求中,也会用在写请求中。
- 在读写普通文件时,会经过文件系统,由文件系统负责与磁盘交互;而读写磁盘或者分区时,就会跳过文件系统,也就是所谓的 “裸 I/O”。这两种读写方式所使用的缓存是不同的,也就是文中所讲的 Cache 和 Buffer 区别。
- buffer 和 cache 的作用:
- 从写的角度来说,不仅可以优化磁盘和文件的写入,对应用程序也有好处,应用程序可以在数据真正落盘前,就返回去做其他工作。
- 从读的角度来说,不仅可以提高那些频繁访问数据的读取速度,也降低了频繁 I/O 对磁盘的压力。
六、文件 IO 性能监控
- Linux 内核在用户进程和文件系统的中间,又引入了一个抽象层,也就是虚拟文件系统
VFS(Virtual FileSystem)
。 - I/O 指的是相对内存而言的 input 和 output。从文件、数据库、网络向内存中写入数据叫做 input;从内存向文件、数据库、网络中输出数据叫做 output。
- Linux 系统 I/O 分为内核准备数据和将数据从内核拷贝到用户空间两个阶段。
缓存 I/O
- 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。
- 在 Linux 的缓存 I/O 机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址空间(用户空间)。
- 读操作:操作系统检查内核空间的缓冲区有没有需要的数据,如果已经缓存了,那么就直接从缓存中返回,也就是将数据复制到应用程序的用户空间;否则从磁盘中读取数据至内核空间的缓冲区,再将内核空间缓冲区的数据返回。
- 写操作:将数据从用户空间复制到内核空间的缓冲区,这时对用户程序来说写操作就已经完成。至于什么时候将数据从内核空间写到磁盘中,这步由操作系统决定,除非显示地调用了
sync
同步命令。 - 缓存 I/O 的优点:
- 在一定程度上分离了内核空间和用户空间,保护系统本身的运行安全。
- 可以减少读盘的次数,从而提高性能。
- 缓存 I/O 的缺点:
- 在缓存 I/O 机制中,
DMA
方式可以将数据直接从磁盘读到内核空间的页缓存中,或者将数据从内核空间的页缓存中直接写回到磁盘上,而不能直接在应用程序的地址空间(用户空间)和磁盘之间进行数据传输。这样,数据在传输过程中需要在应用程序地址的空间(用户空间)和页缓存(内核空间)之间进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是比较大的。
- 在缓存 I/O 机制中,
直接 I/O
- 直接 IO 就是应用程序直接访问磁盘,而不经过内核缓冲区,这样做的目的是减少一次从内核缓冲区到用户程序地址空间的数据复制操作。
- 例如数据库管理系统这类应用,它们更倾向于选择自己的缓存机制,因为数据库管理系统往往比操作系统更了解数据库中存放的数据。数据库管理系统可以提供一种更加高效的缓存机制来提高数据库中存取数据的性能。
监控磁盘 I/O 的命令
# 用于监控 CPU 占用率、平均负载值、I/O 读写速度等。
iostat -k -x 1
-c: 输出 cpu 统计信息
-d: 输出磁盘统计信息 注:默认是两个都输出
-k|-m: 以 kb/s| mb/s 输出
-t: 输出时打印收集信息时刻的时间 注:时间的打印格式和系统变量 S_TIME_FORMAT 相关
-x: 输出详细的拓展统计数据,比如各种等待时间,队列,利用率等信息。
interval [count] : interval 是统计的时间间隔单位是 s,count 则是统计次数
swap
是一块特殊的硬盘空间,当实际内存不够用的时候,操作系统会从内存中取出一部分暂时不用的数据,放在swap
交换分区中,从而为当前运行的程序腾出足够的内存空间。 也就是说,当内存不够用时,使用 swap 分区来临时顶替。# 查看 swap 交换分区的使用情况 swapon -s
- 查看硬盘使用情况。
# 查看文件系统的硬盘挂载点和空间使用情况 df -h
七、网络 IO 性能监控
性能指标
- 带宽:链路的最大传输速率,单位通常为
b/s(比特/秒)
。 - 吞吐量:单位时间内成功传输的数据量,单位通常为
b/s(比特/秒)
或者B/s(字节/秒)
。吞吐量受带宽限制,而吞吐量 / 带宽,也就是该网络的使用率。 - 延时:从网络请求发出后,一直到收到远端响应,所需要的时间延迟。在不同场景中,这一指标可能会有不同含义。比如,它可以表示建立连接需要的时间(比如
TCP
握手延时),或一个数据包往返所需的时间(比如RTT
)。 - PPS:
Packet Per Second(包/秒)
的缩写,表示以网络包为单位的传输速率。PPS 通常用来评估网络的转发能力,比如硬件交换机,通常可以达到线性转发(即 PPS 可以达到或者接近理论最大值)。而基于 Linux 服务器的转发,则容易受网络包大小的影响。 - 除了这些指标,网络的可用性(网络能否正常通信)、并发连接数(TCP 连接数量)、丢包率(丢包百分比)、重传率(重新传输的网络包比例) 等也是常用的性能指标。
网络信息
# 使用 ifconfig 命令来查看网络的配置
ifconfig
ifconfig eth0
套接字信息
# 查看套接字、网络栈、网络接口以及路由表的信息
netstat -nlp
netstat -nlp | head -n 3
-n 拒绝显示别名,能显示数字的全部转化成数字。
-l 仅列出有在 Listen (监听) 的服务状态
-p 显示建立相关链接的程序名
-t 表示只显示 TCP 套接字
-s 按各个协议进行统计
netstat
展示了套接字的状态、接收队列、发送队列、本地地址、远端地址、进程 PID 和进程名称等。其中,接收队列(Recv-Q)和发送队列(Send-Q) 需要特别关注,它们通常应该是 0。当你发现它们不是 0 时,说明有网络包的堆积发生。当然还要注意,在不同套接字状态下,它们的含义不同。- 当套接字处于连接状态(Established) 时:
- Recv-Q 表示套接字缓冲还没有被应用程序取走的字节数(即接收队列长度)。
- Send-Q 表示还没有被远端主机确认的字节数(即发送队列长度)。
- 当套接字处于监听状态(Listening) 时:
- Recv-Q 表示全连接队列的长度。
- Send-Q 表示全连接队列的最大长度。
- 所谓全连接,是指服务器收到了客户端的
ACK
,完成了TCP 三次握手
,然后就会把这个连接挪到全连接队列中。这些全连接中的套接字,还需要被accept()
系统调用取走,服务器才可以开始真正处理客户端的请求。 - 与全连接队列相对应的,还有一个半连接队列。所谓半连接是指还没有完成
TCP 三次握手
的连接,连接只进行了一半。服务器收到了客户端的SYN
包后,就会把这个连接放到半连接队列中,然后再向客户端发送SYN + ACK
包。
网络统计信息
# 查看网络接口(DEV)、网络接口错误(EDEV)、TCP、UDP 统计信息
sar -n DEV 1
连通性
# 使用 ping 来测试远程主机的连通性和延时
ping xx
-c 指定 ping 的次数
-q 只显示结果
验证服务器端口有没有开放
# 开启一个本地 9999 的 TCP 协议端口,由客户端主动发起连接,一旦连接必须由服务端发起关闭
nc -l 9999
# 尝试建立一个 TCP 连接到 IP 地址为 123.249.112.139 的服务器上的 9999 端口
# 如果 2 秒内连接未成功,就会超时。
# -v 表示详细输出,-w 表示超时时间
nc -vw 2 123.249.112.139 9999