系统变慢,常用解决措施

top命令查看系统资源使用情况

简单介绍

显示系统当前的进程和其他状况;

top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止. 比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间 对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定.

  1. 用法
top [-] [d][u][p][n][b][q]

参数说明

  • d:指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
  • u:只查看指定用户名的进程
  • p:通过指定监控进程ID来仅仅监控某个进程的状态
  • n:设置退出前屏幕刷新的次数
  • b:将top输出编排成适合输出到文件的格式,可以使用这个选项创建进程日志
  • q:该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行
  • c:显示整个命令行而不只是显示命令名
  • S:指定累计模式
  • s:使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
  • i:使top不显示任何闲置或者僵死进程。
  1. 交互命令说明

这些命令都是单字母的,如果在命令行选项中使用了s选项,则可能其中一些命令会被屏蔽掉。

  • Shift+n:按PID排序
  • Shift+p:按CPU排序
  • Shift+m:按内存使用排序
  • Shift+t:按CPU用时排序
  • Shift+</Shift+>:按左边下一列排序/按右边下一列排序
  • u:输入用户名只显示指定用户的进程
  • n:键入数字可查看指定数量的进程,任意时刻按=即可回复最初的top显示
  • h:或者? 显示帮助画面,给出一些简短的命令总结说明
  • k:终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用 信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽
  • i:忽略闲置和僵死进程。这是一个开关式命令。
  • q:退出程序。
  • r:重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
  • S:切换到累计模式。
  • s:改变两次刷新之间的延迟时间。系统将提示用户输入新的时间, 单位为s。如果有小数,就换算成ms。输入0值则系统将不断刷新,默认值是5s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
  • d:功能同上
  • f或者F:从当前显示中添加或者删除项目。
  • o:或者O 改变显示项目的顺序。
  • l:切换显示平均负载和启动时间信息。
  • m:切换显示内存信息。
  • t:切换显示进程和CPU状态信息。
  • c:切换显示命令名称和完整命令行。
  • M:根据驻留内存大小进行排序。
  • P:根据CPU使用百分比大小进行排序。
  • T:根据时间/累计时间进行排序。
  • W:将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。
  1. 示例
[root@localhost temp]# top -d 5 # 更新延时设置为5秒(默认3秒)
[root@localhost temp]# top -u MySQL    只查看有效用户名为mysql的进程
[root@localhost temp]# top -p 200,2000    只查看进程200和2000
[root@localhost temp]# top -n 8    退出前屏幕再刷新10次
[root@localhost temp]# top -b    以非交互和非全屏模式运行
[root@localhost temp]# top -b -n 12000 > plog 运行top并记录命令输出,时长10小时,保存到plog文件

案例

在linux机器上输入命令top -H -b -d 1 -n 2 > top.txt表示每隔1秒统计一次,共2次,显示线程细节,并保存到top.txt中。可使用cat top.txt命令查看文件内容。

信息介绍如下,注意查看信息介绍的时候对比下结果信息:

结果信息:

top - 09:11:47 up 22 days, 18:17,  3 users,  load average: 0.78, 0.58, 0.29
Threads: 781 total,   1 running, 780 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.3 us,  5.5 sy,  0.0 ni, 91.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 24500236 total, 15533764 free,  4548268 used,  4418204 buff/cache
KiB Swap:  8257532 total,  8257532 free,        0 used. 18386908 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
14601 root      20   0  162512   2768   1532 R 15.8  0.0   0:00.07 top
    3 root      20   0       0      0      0 S  5.3  0.0   0:22.74 ksoftirqd/0
    1 root      20   0  191440   4336   2612 S  0.0  0.0   4:30.80 systemd
…………

前半部分是系统统计信息,后半部分是进程信息。

第一行分是系统统计信息:

从左到右依次表示:系统当前时间,系统运行时间,当前登录用户数。load average表示系统的平均负载,即任务队列的平均长度,这三个值分别表示1分钟,5分钟,15分钟到现在的平均值。

第二行是进程统计信息,

分别表示正在运行的进程数,睡眠进程数,停止的进程树,僵尸进程树。

第三行表示CPU统计信息

us表示用户空间CPU占用率,sy表示内核空间CPU占用率,ni表示用户进程空间改变过优先级的进程CPU的占用率,id表示空闲CPU占用率,wa表示等待输入输出的CPU时间百分比,hi表示硬件中断请求,si表示软件中断请求。

Mem行中依次表示

物理内存总量,已使用物理内存,空闲物理内存,内核缓冲使用量。

Swap行依次表示

交换区总量,空闲交换区大小,缓冲交换区大小。

第二部分是进程信息区,显示了系统内各个进程的资源使用情况,字段含义如下:

  • PID:进程id
  • USER:进程所有者的用户名
  • PR:优先级
  • NI:nice值,负值表示高优先级,正值表示低优先级
  • VIRT:进程使用的虚拟内存总量,单位kb,VIRT=SWAP+RES
  • RES:进程使用的,未被换出的物理内存大小,单位kb,RES=CODE+DATA
  • SHR:共享内存大小,单位kb
  • %CPU:上次更新到现在的CPU时间占用百分比
  • %MEM:进程使用的物理内存百分比
  • TIME+:进程使用的CPU时间总计,单位1/100秒
  • COMMAND:命令名/命令行

uptime命令查看系统运行了多长时间

基本使用

简单查看系统运行了多长时间

在linux机器输入命令,uptime

[root@localhost temp]# uptime
 09:25:28 up 22 days, 18:30,  3 users,  load average: 1.18, 1.14, 0.82

将显示,如下信息显示

  • 当前系统时间是09:25:28
  • 运行了22天
  • 正在登录用户数3
  • 依次是 1分钟,5分钟,15分钟的平均负载(load average)

什么是平均负载呢?

简单来说,平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和CPU使用率并没有直接关系。

最理想的平均活跃进程数是什么?

就是刚好每个CPU上都刚好运行着一个进程,这样每个CPU都得到了充分的利用。比如平均负载为4时意味着什么呢?

  • 在只有4个CPU的系统上,意味着所有的CPU都刚好被完全占用。
  • 在8个CPU的系统上,意味着CPU有50%的空闲。
  • 而在有2个CPU系统上,意味着有一半的进程竞争不到CPU。

平均负载为多少时合理?

平均负载比CPU个数大的时候,系统就已经出现了过载。

  • 如果1分钟,5分钟,15分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
  • 如果1分钟的值远小于15分钟的值,就说明系统最近1分钟负载在减少,而过去15分钟内却有很大负载。
  • 反之则相反,如果1分钟的值远大于15分钟的值,说明近1分钟负载在增加,这种情况可能是临时性的,也可能还会持续,要持续观察,一旦1分钟的平均负载超过了CPU的数量,意味着系统正在发生过载的问题。

例如:一个单核系统上,平均负载为1.78,0.60,6.56,说明1分钟内,系统有78%的超载,而在15分钟内有556%的超载。

实际生产中,平均负载多高时需要关注呢?

平均负载高于CPU数量70%时,就应该分析排查负载高问题了。(不绝对)

平均负载与CPU使用率

  • CPU密集型进程,使用大量CPU会导致平均负载升高,此时两者时一致的。
  • I/O密集型进程,等待I/O也会导致平均负载升高,但CPU使用率不一定很高。
  • 大量等待CPU的进程调度也会导致平均负载升高,此时的CPU使用率也会比较高。

vmstat命令监控系统内存使用情况

简单介绍

vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。

它能够对系统的整体情况进行统计,无法对某个进程进行深入分析。vmstat 工具提供了一种低开销的系统性能观察方式。

主要报告虚拟内存的统计信息,关于进程、内存、I/O等系统整体运行状态。

  1. 用法
    vmstat [选项参数] 或 vmstat [选项参数] [数字] [数字]
  2. 选项参数:
  • -d:显示磁盘相关统计信息
  • -a:显示活跃和非活跃内存
  • -f: 显示从系统启动至今的fork数量
  • -p:显示指定磁盘分区统计信息
  • -s:显示内存相关统计信息及多种系统活动数量。
  • -m:显示slabinfo

相关概念说明

物理内存和虚拟内存区别

物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概念。

物理内存就是系统硬件提供的内存大小,是真正的内存;在Linux系统下,虚拟内存就是为了满足物理内存的不足而提出的策略,它是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。作为物理内存的扩展,linux会在物理内存不足时,使用交换分区的虚拟内存。(更详细的说,就是内核会将暂时不用的内存块信息写到交换空间,这样以来,物理内存得到了释放,这块内存就可以用于其它目的,当需要用到原始的内容时,这些信息会被重新从交换空间读入物理内存。)

linux内存运行机制:

linux的内存管理采取的是分页存取机制,为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不经常使用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。

  1. 首先,Linux系统会不时的进行页面交换操作,以保持尽可能多的空闲物理内存,即使并没有什么事情需要内存,Linux也会交换出暂时不用的内存页面。这可以避免等待交换所需的时间。
  2. 其次,linux进行页面交换是有条件的,不是所有页面在不用时都交换到虚拟内存,linux内核根据”最近最经常使用“算法,仅仅将一些不经常使用的页面文件交换到虚拟内存,有时我们会看到这么一个现象:linux物理内存还有很多,但是交换空间也使用了很多。其实,这并不奇怪,例如,一个占用很大内存的进程运行时,需要耗费很多内存资源,此时就会有一些不常用页面文件被交换到虚拟内存中,但后来这个占用很多内存资源的进程结束并释放了很多内存时,刚才被交换出去的页面文件并不会自动的交换进物理内存,除非有这个必要,那么此刻系统物理内存就会空闲很多,同时交换空间也在被使用,就出现了刚才所说的现象了。关于这点,不用担心什么,只要知道是怎么一回事就可以了。
  3. 最后,交换空间的页面在使用时会首先被交换到物理内存,如果此时没有足够的物理内存来容纳这些页面,它们又会被马上交换出去,如此以来,虚拟内存中可能没有足够空间来存储这些交换页面,最终会导致linux出现假死机、服务异常等问题,linux虽然可以在一段时间内自行恢复,但是恢复后的系统已经基本不可用了。

因此,合理规划和设计linux内存的使用,是非常重要的。

虚拟内存原理

在系统中运行的每个进程都需要使用到内存,但不是每个进程都需要每时每刻使用系统分配的内存空间。当系统运行所需内存超过实际的物理内存,内核会释放某些进程所占用但未使用的部分或所有物理内存,将这部分资料存储在磁盘上直到进程下一次调用,并将释放出的内存提供给有需要的进程使用。

在Linux内存管理中,主要是通过“调页Paging”和“交换Swapping”来完成上述的内存调度。调页算法是将内存中最近不常使用的页面换到磁盘上,把活动页面保留在内存中供进程使用。交换技术是将整个进程,而不是部分页面,全部交换到磁盘上。 分页(Page)写入磁盘的过程被称作Page-Out,分页(Page)从磁盘重新回到内存的过程被称作Page-In。当内核需要一个分页时,但发现此分页不在物理内存中(因为已经被Page-Out了),此时就发生了分页错误(Page Fault)。 当系统内核发现可运行内存变少时,就会通过Page-Out来释放一部分物理内存。经管Page-Out不是经常发生,但是如果Page-out频繁不断的发生,直到当内核管理分页的时间超过运行程式的时间时,系统效能会急剧下降。这时的系统已经运行非常慢或进入暂停状态,这种状态亦被称作thrashing(颠簸)。

buffer与cache的区别

buff和cache的主要区别是在控制和速度上。buff的控制相对简单,是对数据流缓冲,将需要的数据流临时缓冲在buff里,以降低低速设备对整体的影响。一般都是对大量的数据交换进行缓冲;cache是对高速交换进行缓冲,需要一些额外的算法来提高效率,比如读取命中之类的,一般相对较小,速度很快,大多是对指令的临时存储。

案例

显示虚拟内存使用情况

在linux机器输入命令vmstat 3 2(表示每隔3秒统计一次,共统计2次)显示虚拟内存使用情况,主要有进程、内存、swap、io、中断和进程切换、cpu 6个信息

[root@localhost temp]# vmstat 3 2
procs   ------------memory----------   -swap--    --io---- -system-- ------cpu-----
 r  b   swpd     free   buff   cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 15532124     20 4421504    0    0     1     8    5    4  3  3 93  0  0
 0  0      0 15532464     20 4421520    0    0     0    59 1319 1959  3  4 93  0  0

字段说明:

  • Procs(进程)
  • r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
  • b: 等待IO的进程数量。
  • Memory(内存)
  • swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
  • free: 空闲物理内存大小。
  • buff: 用作缓冲的内存大小。
  • cache: 用作缓存的内存大小,如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。
  • Swap(交换区)
  • si: 每秒从交换区写到内存的大小,由磁盘调入内存。
  • so: 每秒写入交换区的内存大小,由内存调入磁盘。

注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

  • IO(现在的Linux版本块的大小为1kb)
  • bi: 每秒读取的块数
  • bo: 每秒写入的块数

注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

  • system(系统)
  • in: 每秒中断数,包括时钟中断。
  • cs: 每秒上下文切换数。

注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

  • CPU(以百分比表示)
  • us:用户进程执行时间百分比(user time) us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
  • sy:内核系统进程执行时间百分比(system time) sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
  • id:空闲时间百分比
  • wa:IO等待时间百分比 wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。
  • st:来自于一个虚拟机偷取的CPU时间的百分比
显示磁盘的信息
[root@localhost temp]# vmstat -d 3 2
disk- ------------reads------------ ------------writes----------- -----IO------
       total merged sectors      ms  total merged sectors      ms    cur    sec
sda   131289    406 15106820 1417748 5491358 194008 122300179 23968575      0   1600
sr0        0      0       0       0      0      0       0       0      0      0
dm-0  124887      0 14876996 1319085 5680658      0 122122239 24239458      0   1576
dm-1     142      0    6568    5935      0      0       0       0      0      5
dm-2    6349      0  171043   40949   4607      0  173175   29654      0     33
sda   131289    406 15106820 1417748 5491358 194008 122300179 23968575      0   1600
sr0        0      0       0       0      0      0       0       0      0      0
dm-0  124887      0 14876996 1319085 5680658      0 122122239 24239458      0   1576
dm-1     142      0    6568    5935      0      0       0       0      0      5
dm-2    6349      0  171043   40949   4607      0  173175   29654      0     33
  • merged:表示一次来自于合并的写/读请求,一般系统会把多个连接/邻近的读/写请求合并到一起来操作。
显示活跃内存与非活跃内存
[root@localhost temp]# vmstat -a 3 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 15530116 2159016 6170308    0    0     1     8    5    4  3  3 93  0  0
 0  0      0 15529880 2159016 6170340    0    0     0    49 1418 2020  4  4 92  0  0

使用-a选项显示活跃和非活跃内存时,所显示的内容除增加inact和active外,其他显示内容与例子1相同。

查看系统已经被fork多少次
[root@localhost temp]# vmstat -f
     45262245 forks
查看特定磁盘设备
[root@localhost temp]# df
文件系统                    1K-块     已用      可用 已用% 挂载点
/dev/mapper/centos-root  52403200 24265000  28138200   47% /
devtmpfs                 12232944        0  12232944    0% /dev
tmpfs                    12250116     1124  12248992    1% /dev/shm
tmpfs                    12250116  1124212  11125904   10% /run
tmpfs                    12250116        0  12250116    0% /sys/fs/cgroup
/dev/mapper/centos-home 425694120  2555488 423138632    1% /home
/dev/sda2                 1038336   165008    873328   16% /boot
/dev/sda1                  204580     9968    194612    5% /boot/efi
tmpfs                     2450024       44   2449980    1% /run/user/1000
tmpfs                     2450024        0   2450024    0% /run/user/0
[root@localhost temp]# vmstat -p /dev/sda1
sda1          reads   read sectors  writes    requested writes
                 380       4696          1          1

这些信息主要来自于/proc/diskstats。

  • reads:来自于这个分区的读的次数。
  • read sectors:来自于这个分区的读扇区的次数。
  • writes:来自于这个分区的写的次数。
  • requested writes:来自于这个分区的写请求次数。
显示slabinfo
[root@localhost temp]# vmstat -m
Cache                       Num  Total   Size  Pages
fuse_request                 80     80    400     40
fuse_inode                   42     42    768     42
nf_conntrack_ffff978b4a220000      0      0    320     51
nf_conntrack_ffffffff986fc900   1481   1734    320     51
rpc_inode_cache              51     51    640     51
fat_inode_cache             135    135    720     45
fat_cache                     0      0     40    102
kvm_vcpu                      0      0  12992      2
xfs_dqtrx                     0      0    528     31
xfs_dquot                     0      0    488     33
………………

pidstat命令查看磁盘使用情况

简单介绍

  1. 用法
[root@localhost temp]# pidstat --help
用法: pidstat [ 选项 ] [ <时间间隔> [ <次数> ] ]
Options are:
[ -d ] [ -h ] [ -I ] [ -l ] [ -r ] [ -s ] [ -t ] [ -U [ <username> ] ] [ -u ]
[ -V ] [ -w ] [ -C <command> ] [ -p { <pid> [,...] | SELF | ALL } ]
[ -T { TASK | CHILD | ALL } ]
  1. 常用参数
  • -u:默认参数,显示各个进程的cpu使用情况;
  • -r:显示各个进程的内存使用情况;
  • -d:显示各个进程的I/O使用情况;
  • -w:显示每个进程的上下文切换情况;
  • -p:指定进程号;
  • -t:显示进程中线程的统计信息

案例

查看所有进程的I/O使用情况
[root@localhost temp]# pidstat -p ALL -d
Linux 3.10.0-862.el7.x86_64 (localhost.localdomain) 	2020年10月13日 	_x86_64_	(4 CPU)

10时26分02秒   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
10时26分02秒     0         1      0.34      2.53      0.89  systemd
10时26分02秒     0         2      0.00      0.00      0.00  kthreadd
10时26分02秒     0         3      0.00      0.00      0.00  ksoftirqd/0
10时26分02秒     0         5      0.00      0.00      0.00  kworker/0:0H
10时26分02秒     0         7      0.00      0.00      0.00  migration/0
10时26分02秒     0         8      0.00      0.00      0.00  rcu_bh
  • kB_rd/s: 每秒进程从磁盘读取的数据量(以kB为单位)。
  • kB_wr/s: 每秒进程向磁盘写的数据量(以kB为单位)。
  • kB_ccwr/s:每秒进程被取消向磁盘写的数据量(以kB为单位)。
  • Command: 拉起进程对应的命令。
查看进程的上下文切换情况
[root@localhost temp]# pidstat -w -p 7033
Linux 3.10.0-862.el7.x86_64 (localhost.localdomain) 	2020年10月13日 	_x86_64_	(4 CPU)

10时29分51秒   UID       PID   cswch/s nvcswch/s  Command
10时29分51秒  1001      7033      0.28      0.00  nginx
[root@localhost temp]# pidstat -w -p 7033 -t
Linux 3.10.0-862.el7.x86_64 (localhost.localdomain) 	2020年10月13日 	_x86_64_	(4 CPU)

10时30分47秒   UID      TGID       TID   cswch/s nvcswch/s  Command
10时30分47秒  1001      7033         -      0.28      0.00  nginx
10时30分47秒  1001         -      7033      0.28      0.00  |__nginx
  • cswch/s:每秒主动任务(自愿)上下文切换数量

指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。

  • nvcswch/s:每秒被动任务(非自愿)上下文切换数量

指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU时,就容易发生非自愿上下文切换。

Q/A
  1. 每秒上下文切换多少次才算正常呢?

这个数值其实取决于系统本身的 CPU 性能。如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的。但当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,就很可能已经出现了性能问题。

需要根据上下文切换的类型,再做具体分析。比方说:

  • 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
  • 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;
  • 中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。

常用监控命令

nc命令进行网络交互

作用

  • 实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口
  • 端口的扫描,nc可以作为client发起TCP或UDP连接
  • 机器之间传输文件
  • 机器之间网络测速

常用参数

  • -l:用于指定nc将处于侦听模式。指定该参数,则意味着nc被当作server,侦听并接受连接,而非向其它地址发起连接。
  • -p:暂未用到(老版本的nc可能需要在端口号前加-p参数,下面测试环境是centos6.6,nc版本是nc-1.84,未用到-p参数)
  • -s:指定发送数据的源IP地址,适用于多网卡机
  • -u:指定nc使用UDP协议,默认为TCP
  • -v:输出交互或出错信息,新手调试时尤为有用
  • -w:超时秒数,后面跟数字

案例

测试端口连通性

使用nc -w 1 ip地址 端口号 < /dev/null && echo "tcp port ok",如果tcp三次握手成功就输出ok,失败就输出connection refused。

[root@localhost temp]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:796             0.0.0.0:*               LISTEN      7032/nginx: master  
tcp        0      0 0.0.0.0:797             0.0.0.0:*               LISTEN      7032/nginx: master  
tcp        0      0 0.0.0.0:798             0.0.0.0:*               LISTEN      7032/nginx: master  
tcp        0      0 0.0.0.0:799             0.0.0.0:*               LISTEN      7032/nginx: master  
tcp        0      0 0.0.0.0:800             0.0.0.0:*               LISTEN      7032/nginx: master 
[root@localhost temp]# nc -w 1 0.0.0.0 790 < /dev/null && echo "tcp port ok"
tcp port ok
[root@localhost temp]# nc -w 1 0.0.0.0 991 < /dev/null && echo "tcp port ok"
Ncat: Connection refused.
常用案例
# 开启一个本地9999的TCP协议端口,由客户端主动发起连接,一旦连接必须由服务端发起关闭
[root@localhost temp]# nc -l 9999

# 通过nc去访问192.168.21.248主机的11111端口,确认是否存活;可不加参数
[root@localhost temp]# nc -vw 2 192.168.21.248 11111

# 开启一个本地9999的UDP协议端口,客户端不需要由服务端主动发起关闭
[root@localhost temp]# nc -ul 9999

# 通过192.168.21.248的9999TCP端口发送数据文件
[root@localhost temp]# nc 192.168.21.248 9999 < test

# 开启一个本地9999的TCP端口,用来接收文件内容
[root@localhost temp]# nc -l 9999 > zabbix.file 

# 进行网络监控
[root@localhost temp]# dstat

netstat查看端口命令

介绍

Netstat是控制台命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。

  1. 用法
[root@localhost temp]# netstat help
usage: netstat [-vWeenNcCF] [<Af>] -r         netstat {-V|--version|-h|--help}
       netstat [-vWnNcaeol] [<Socket> ...]
       netstat { [-vWeenNac] -I[<Iface>] | [-veenNac] -i | [-cnNe] -M | -s [-6tuw] } [delay]
………………
  1. 常见参数
  • -a (all):显示所有选项,默认不显示LISTEN相关。
  • -t (tcp):仅显示tcp相关选项。
  • -u (udp):仅显示udp相关选项。
  • -n:拒绝显示别名,能显示IP的全部转化成IP。
  • -l:仅列出有在 Listen (监听) 的服务状态(使应用程序能够读写与收发通讯协议(protocol)与资料的程序)。
  • -p:显示进程标识符和程序名称,每一个套接字/端口都属于一个程序。
  • -r:显示路由信息,路由表
  • -e:显示扩展信息,例如uid等
  • -s:按各个协议进行统计
  • -c:每隔一个固定时间,执行该netstat命令。

LISTEN和LISTENING的状态只有用-a或者-l才能看到。

netstat网络状态详解

一个正常的TCP连接,都会有三个阶段:

  1. TCP三次握手
  2. 数据传送
  3. TCP四次挥手

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UQnQSluk-1678763321831)(/assets/img/linux/011_01.jpg)]

  • SYN:(同步序列编号,Synchronize Sequence Numbers)该标志仅在三次握手建立TCP连接时有效。表示一个新的TCP连接请求。
  • ACK:(确认编号,Acknowledgement Number)是对TCP请求的确认标志,同时提示对端系统已经成功接收所有数据。
  • FIN:(结束标志,FINish)用来结束一个TCP回话.但对应端口仍处于开放状态,准备接收后续数据。
  • LISTEN:首先服务端需要打开一个socket进行监听,状态为LISTEN,侦听来自远方TCP端口的连接请求 。
  • SYN_SENT:客户端通过应用程序调用connect进行active open.于是客户端tcp发送一个SYN以请求建立一个连接,之后状态置为SYN_SENT,随后进入"在发送连接请求后等待匹配的连接请求"状态。
  • SYN_RECV:服务端应发出ACK确认客户端的SYN,同时自己向客户端发送一个SYN, 之后状态置为SYN_RECV 。随后进入“在收到和发送一个连接请求后等待对连接请求的确认 ”状态。
  • ESTABLISHED:代表一个打开的连接,双方可以进行或已经在数据交互了,随后进入“代表一个打开的连接,数据可以传送给用户”状态。
  • FIN_WAIT1:主动关闭(active close)端应用程序调用close,于是其TCP发出FIN请求主动关闭连接,之后进入FIN_WAIT1状态。 随后进入“等待远程TCP的连接中断请求,或先前的连接中断请求的确认”状态。
  • CLOSE_WAIT:被动关闭(passive close)端TCP接到FIN后,就发出ACK以回应FIN请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT, 随后等待从本地用户发来的连接中断请求
  • FIN_WAIT2:主动关闭端接到ACK后,就进入了FIN-WAIT-2 ,随后进入“从远程TCP等待连接中断请求”状态
  • LAST_ACK:被动关闭端一段时间后,接收到文件结束符的应用程序将调用CLOSE关闭连接。这导致它的TCP也发送一个 FIN,等待对方的ACK.就进入了LAST-ACK ,随后进入“等待原来发向远程TCP的连接中断请求的确认”状态
  • TIME_WAIT:在主动关闭端接收到FIN后,TCP就发送ACK包,并进入TIME-WAIT状态。随后进入“等待足够的时间以确保远程TCP接收到连接中断请求的确认。”状态
  • CLOSING:比较少见, 随后进入“等待远程TCP对连接中断的确认。”状态
  • CLOSED: 被动关闭端在接受到ACK包后,就进入了closed的状态。连接结束,随后进入“没有任何连接状态。”

TIME_WAIT状态的形成只发生在主动关闭连接的一方。
主动关闭方在接收到被动关闭方的FIN请求后,发送成功给对方一个ACK后,将自己的状态由FIN_WAIT2修改为TIME_WAIT,而必须再等2倍 的MSL(Maximum Segment Lifetime,MSL是一个数据报在internetwork中能存在的时间)时间之后双方才能把状态 都改为CLOSED以关闭连接。目前RHEL里保持TIME_WAIT状态的时间为60秒。

Linux的相关keepalive参数

  1. tcp_keepalive_time – INTEGER

How often TCP sends out keepalive messages when keepalive is enabled.(Default: 2hours)

一个连接需要TCP开始发送keepalive探测数据包之前的空闲时间,以秒为单位。

  1. tcp_keepalive_probes – INTEGER

How many keepalive probes TCP sends out, until it decides that the connection is broken. (Default value: 9)

发送TCP keepalive探测数据包的最大数量,默认是9.如果发送9个keepalive探测包后对端仍然没有响应,就关掉这个连接。

  1. tcp_keepalive_intvl – INTEGER

How frequently the probes are send out. Multiplied by tcp_keepalive_probes it is time to kill not responding connection,
after probes started. Default value: 75sec i.e. connection will be aborted after ~11 minutes of retries.

发送两个TCP keepalive探测数据包的间隔时间,默认是75秒。

常用netstat相关命令

列出所有端口
netstat -a
列出所有 tcp 端口
netstat -at
netstat -ntlp
列出所有 udp 端口
netstat -au
只显示监听端口
netstat -l
只列出所有监听 tcp 端口
netstat -lt
只列出所有监听 udp 端口
netstat -lu
列出所有监听 UNIX 端口
netstat -lx

#### 查看一台服务器上面哪些服务及端口

netstat  -lanp
查看一个服务有几个端口
ps -ef |grep mysqld
显示所有端口的统计信息
netstat -s
显示 TCP 或 UDP 端口的统计信息
netstat -st 或 -su
输出中显示 PID 和进程名称
netstat -p
netstat 输出中不显示主机,端口和用户名 (host, port or user)

当你不想让主机,端口和用户名显示,使用 netstat -n。将会使用数字代替那些名称。

同样可以加速输出,因为不用进行比对查询。netstat -an

如果只是不想让这三个名称中的一个被显示,使用以下命令

netsat -a --numeric-ports
netsat -a --numeric-hosts
netsat -a --numeric-users
持续输出 netstat 信息
netstat -c
找出程序运行的端口
netstat  -ap | grep ':80'
查看所有80端口使用情况
netstat -ntulp |grep 80
netstat -an | grep 80
看连接某服务端口最多的的IP地址(前20个)
netstat -nat | grep "10.1.62.23:443" |awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -20
TCP各种状态列表
netstat -nat |awk '{print $6}'

统计数量

netstat -nat |awk '{print $6}'|sort|uniq -c

排序

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
直接统计tcp数量监听的数量
netstat -ant | wc -l
查看某一端口的连接数量
netstat -pnt |grep :3306 |wc
查看某一端口的连接客户端IP
netstat -anp |grep 3306