Linux平台

以下总结常用的几个工具,tcpdump、nc、strace、lsof、netstat、vsmstat、ifstat、和mpstat

tcpdump

一款经典的抓包工具,给使用者提供了大量的选项,用以过滤数据包或者定制输出格式。常见的选项总结如下:

  • -n,使用IP地址表示主机,而不是主机名:使用数字表示端口号,而不是服务名称。

    在这里插入图片描述

  • -i,指定要监听的网卡接口。“iany”表示抓取所有网卡接口上的数据包。
    ifconfig查看网卡

tcpdump -i eth0
  • -v,输出一个稍微详细的信息,例如,显示IP数据包中的TTL和TOS信息。
    在这里插入图片描述
  • -e,显示以太网帧头部信息。
    在这里插入图片描述
  • -t,不打印时间戳。
  • -c,仅抓取指定数量的数据包。
  • -x,以十六进制数显示数据包的内容,但不显示包中以太网帧的头部信息
  • -X,与-x选项类似,不过还打印每个十六进制字节对应的ASCII字符。
  • -XX,与-X相同,不过还打印以太网帧的头部信息。
  • -s,设置抓包时的抓取长度。当数据包的长度超过抓取长度时,tcpdump抓取到的将
    是被截断的数据包。在4.0以及之前的版本中,默认的抓包长度是68字节。这对于
    IP、TCP和UDP等协议就已经足够了,但对于像DNS、NFS这样的协议,68字节
    通常不能容纳一个完整的数据包。比如我们在1.6.3小节抓取DNS数据包时,就使用
    了-S选项(测试机器cmcst-laptop上,tcpdump的版本是4.0.0)。不过4.0之后的版
    本,默认的抓包长度被修改为65535字节,因此我们不用再担心抓包长度的问题了。
  • -S,以绝对值来显示TCP报文段的序号,而不是相对值。
    在这里插入图片描述- -W,将tcpdump的输出以特殊的格式定向到某个文件。
  • -r,从文件读取数据包信息并显示之。这两个命令配套使用
    除了使用选项外,tepdump还支持用表达式来进一步过滤数据包,下面依次介绍之。

tepdump表达式的操作数分为3种:类型、方向、协议

  • 类型,解释其后面紧跟着的参数的含义。tepdump支持的类型包括host、net、port和
    portrange。它们分别指定主机名(或IP地址),用CIDR方法表示的网络地址,端口
    号以及端口范围。比如,要抓取整个1.2.3.0/255.255.255.0网络上的数据包,可以使
    用如下命令:
tcpdump net 1.2.3.0/24
  • 方向,src指定数据包的发送端,dst指定数据包的目的端。比如要抓取进入端口
    13579的数据包,可以使用如下命令:
tcpdump dst port 13579
  • 协议,指定目标协议。比如要抓取所有ICMP数据包,可以使用如下命令:
tcpdump icmp

当然,我们还可以使用逻辑操作符来组织上述操作数以创建更复杂的表达式。
tcpdump支持的逻辑操作符和编程语言中的逻辑操作符完全相同,
包括and(或者&&)、or(或者I)、not(或者!)。

  • 比如要抓取主机ernest-laptop和所有非Kongming20的主机之间交换的IP数据包
    可以使用如下命令:
tcpdump ip host ernest-laptop and not Kongming20
  • 如果表达式比较复杂,那么我们可以使用括号将它们分组。
  • 不过在使用括号时,我们要么使用反斜杠“\”对它转义,要么用单引号“ ’ ”将其括住,以避免它被shelI所解释。
  • 比如要抓取来自主机10.0.2.4,目标端口是3389或22的数据包,可以使用如下命令:
tcpdump src 10.0.2.4 and (dst port 3389 or 22)
  • 此外,tcpdump还允许直接使用数据包中的部分协议字段的内容来过滤数据包。
  • 比如仅抓取TCP同步报文段,可使用如下命令:
    tcpdump ‘tcp[13] & 2 !=0’
    这是因为TCP头部的第14个字节的第2个位正是同步标志。该命令也可以表示为:
    tcpdump ‘tcp[tcpflags] & tcp-syn!= 0’

下面举一些常用的例子:

  • 抓取eth0接口,源IP主机为192.168.2.100,目的主机为:192.168.2.200
    tcpdump -i eth0 src host 192.168.2.100 and dst host 192.168.2.200
  • 抓取80端口
tcpdump port 80
  • 指明一个网络地址,抓包结果与用host指定值相同
tcpdump net 192.168.2.200
tcpdump host 192.168.2.200
  • 抓取主机网卡eth0接口 ip192.168.2.200在80端口接收到的所有数据包
tcpdump -i eth0 host 192.168.2.200 and dst port 80
  • tcpdump的具体输出格式除了与选项有关外,还与协议有关。 如:IP、TCP、ICMP、DNS等协议输出格式,关于其他协议的tcpdump输出格式,参考tcpdump的man手册。

lsof

lsof(listopenfile)是一个列出当前系统打开的文件描述符的工具。通过它我们可以了
解感兴趣的进程打开了哪些文件描述符,或者我们感兴趣的文件描述符被哪些进程打开了。

lsof命令常用的选项包括:

  • -i,显示socket文件描述符。该选项的使用方法是
lsof -i [46] [protocol] [@hostname | ipaddr] [:service | port]

其中,4表示IPv4协议,6表示IPv6协议:protocol指定传输层协议,可以是
TCP或者UDP:hostname指定主机名:ipaddr指定主机的IP地址:service指定服
务名;port指定端口号。

  • 比如,要显示所有连接到主机10.0.4.3的ssh服务的socket文件描述符,可以使用命令:
    lsof -i@10.0.0.4.3
    在这里插入图片描述

如果-i选项后不指定任何参数,则lsof命令将显示所有socket文件描述符。

  • -u,显示指定用户启动的所有进程打开的所有文件描述符。
  • -c,显示指定的命令打开的所有文件描述符。比如要查看websrv程序打开了哪些文
    件描述符,可以使用如下命令:
    lsof -c websrv
  • -p,显示指定进程打开的所有文件描述符。
  • -t,仅显示打开了目标文件描述符的进程的PID。
    我们还可以直接将文件名作为lsof命令的参数,以查看哪些进程打开了该文件。
    例如我运行了一个15-6程序 进程ID是2435350
    在这里插入图片描述
    lsof命令的输出内容相当丰富,其中每行内容都包含如下字段
  • COMMAND,执行程序所使用的终端命令(默认仅显示前9个字符)。
  • PID,文件描述符所属进程的PID。
  • USER,拥有该文件描述符的用户的用户名。
  • FD,文件描述符的描述。
  • 其中cwd表示进程的工作目录,rtd表示用户的根目录,txt表示进程运行的程序代码,
  • mem表示直接映射到内存中的文件(本例中都是动态库)。
    有的FD是以“数字+访问权限”表示的,其中数字是文件描述符的具体数值,
    访问权限包括r(可读)、w(可写)和u(可读可写)。
    在本例中,0u、1u、2u分别表示标准输入、标准输出和标准错误输出;
    3u表示处于LISTEN状态的监听socket:4u表示epoll内核事件表对应的文件描述符。
  • TYPE,文件描述符的类型。
    其中DIR是目录,REG是普通文件,CHR是字符设备文件,IPv4是IPv4类型的socket文件描述符,0000是未知类型。
    更多文件描述符的类型请参考Isof命令的man手册,这里不再整述。
  • DEVICE,文件所属设备。对于字符设备和块设备,其表示方法是“主设备号,次设备号”。
  • 由代码截图可见,测试机器上的程序文件和动态库都存放在设备“252.2”
    中。其中,“252”表示这是一个SCSI硬盘:“2”表示这是该硬盘上的第2个分区,即sda2。
    websrv程序的标准输入、标准输出和标准错误输出对应的设备是“136.4”。
    其中,“136”表示这是一个伪终端:“4”表示它是第4个伪终端,即/dev/pts/4。
    对于FIFO类型的文件,比如管道和socket,该字段将显示一个内核引用目标文件的地址,或者是其i节点号。
  • SIZE/OFF,文件大小或者偏移值。如果该字段显示为“0*”或者“0x*”,就表示这
    是一个偏移值,否则就表示这是一个文件大小。对字符设备或者FIFO类型的文件定
    义文件大小没有意义,所以该字段将显示一个偏移值。
  • NODE,文件的i节点号。对于socket,则显示为协议类型,比如“TCP”
  • NAME,文件的名字。
    如果我们使用telnet命令向15-6服务器发起一个连接,则再次执行代码的Isof命令时,其输出将多出如下一行:
    在这里插入图片描述
    该输出表示服务器打开了一个IPv4类型的socket,其值是5,且它处于ESTABLISHED
    状态。该socket对应的连接的本端socket地址是(127.0.0.1,12345),远端socket地址
    则是(127.0.0.1,57556)。

nc

nc(neteat)命令短小精干、功能强大,有着“瑞士军刀”的美誉。它主要被用来快速构建网络连接。我们可以让它以服务器方式运行,监听某个端口并接收客户连接,因此它可用来调试客户端程序。我们也可以使之以客户端方式运行,向服务器发起连接并收发数据,因此它可以用来调试服务器程序,此时它有点像telnet程序。
nc命令常用的选项包括

  • -i,设置数据包传送的时间间隔。
  • -l,以服务器方式运行,监听指定的端口。nc命令默认以客户端方式运行。
  • -k,重复接受并处理某个端口上的所有连接,必须与-1选项一起使用。
  • -n,使用IP地址表示主机,而不是主机名:使用数字表示端口号,而不是服务名称。
  • -p,当nc命令以客户端方式运行时,强制其使用指定的端口号。
  • -s,设置本地主机发送出的数据包的IP地址。
  • -C,将CR和LF两个字符作为行结束符。
  • -U,使用UNIX本地域协议通信。
  • -u,使用UDP协议。nc命令默认使用的传输层协议是TCP协议
  • -W,如果nc客户端在指定的时间内未检测到任何输入,则退出。
  • -X,当nc客户端和代理服务器通信时,该选项指定它们之间使用的通信协议。
  • 目前nc支持的代理协议包括“4”(SOCKSv.4),“5”(SOCKSv.5)和“connect”(HTTPS proxy)。
    nc默认使用的代理协议是SOCKSv.5。
  • -x,指定目标代理服务器的IP地址和端口号。比如,要从主机连接到ernest-laptop上的squid代理服务器,
    并通过它来访问www.baidu.com的Web服务,可以使用如下命令:
nc -x ernest-laptop:1080 -X connect www.baidu.com 80
  • -z,扫描目标机器上的某个或某些服务是否开启(端口扫描)
    比如,要扫描机器ernestlaptop上端口号在20~50之间的服务,可以使用如下命令:
nc -z ernest-laptop 20-50

举例来说,我们可以使用如下方式来连接15-6服务器并向它发送数据:
(服务界监听端口12345)

先运行服务器
./15-6 127.0.0.1 12345
nc -C 127.0.0.1 12345
返回的显示结果,nc存在一个问题因为代码中writev发送完就直接close了,nc会收不到结果,
可以再发送完后,加个延时时间再关闭连接或者打断点都能正常收到结果,而telnet连接服务器则不会,可以直接收到结果。
这里我们使用了-C选项,这样每次我们按下回车键向服务器发送一行数据时,nc客户
端程序都会给服务器额外发送一个<CR><LF>,而这正是websrv服务器期望的HTTP行结
```bash
GET http://localhost/a.html HTTP/1.1(回车)
Host:localhost(回车)
(回车)

在这里插入图片描述

GET http://localhost/a.txt HTTP/1.1(回车)
Host:localhost(回车)
(回车)

返回的显示结果,因为我自己在目录下创建了a.txt文件内容是 test yi xia
在这里插入图片描述

Strace

strace是测试服务器性能的重要工具。它跟踪程序运行过程中执行的系统调用和接收到的信号,
并将系统调用名、参数、返回值及信号名输出到标准输出或者指定的文件。
strace命令常用的选项包括:

  • -c,统计每个系统调用执行时间、执行次数和出错次数。
  • -f,跟踪由fork调用生成的子进程。
  • -t,在输出的每一行信息前加上时间信息。
  • -c,指定一个表达式,用来控制如何跟踪系统调用(或接收到的信号,下同)。
    其格式是:[qualifier=][!]value1[,value2]…
    qualifier可以是trace、abbrev、verbose、raw、signal、read和write中之一,默认是trace。
    value是用于进一步限制被跟踪的系统调用的符号或数值。
    它的两个特殊取值是all和none,分别表示跟踪所有由qualifier指定类型的系统调用和不跟踪任何该类型的系统调用。
    关于value的其他取值,我们简单地列举一些:
  • -c trace=set,只跟踪指定的系统调用。
  • 例如,-c trace=open,close,read,write表示只跟踪open、close、read和write这四种系统调用。
  • -c trace=file,只跟踪与文件操作相关的系统调用。
  • -c tracc=proccss,只跟踪与进程控制相关的系统调用。
  • -e trace=network,只跟踪与网络相关的系统调用。
  • -c tracc=signal,只跟踪与信号相关的系统调用。
  • -e trace=ipc,只跟踪与进程间通信相关的系统调用。
  • -c signal=set,只跟踪指定的信号。比如,-esignal=ISIGIO表示跟踪除SIGIO之外的
    所有信号。
  • -e read=set,输出从指定文件中读入的数据。例如,-e read=3,5表示输出所有从文
    件描述符3和5读入的数据。
  • -o,将strace的输出写入指定的文件。
    strace命令的每一行输出都包含这些字段:系统调用名称、参数和返回值。比如下面的示例:
strace cat /dev/null

open("/dev/null",O_RDONLYIO_LARGEFILE)=3
这行输出表示:程序“cat /dev/null”在运行过程中执行了open系统调用。open调用以只读的方式打开了大文件/dev/null,
然后返回了一个值为3的文件描述符。需要注意的是,该示例命令将输出很多内容,这里我们省略了很多次要的信息。
在后面的实例中,我们也仅显示主题相关的内容。
在这里插入图片描述

当系统调用发生错误时,strace命令将输出错误标识和描述,比如下面的示例:

strace cat /foo/bar

open("/foo/bar”,ORDONLYIO_LARGEFILE) =-1 BNOENT (NO such fle or directory)
strace命令对不同的参数类型将有不同的输出方式,
比如:口对于C风格的字符串,strace将输出字符串的内容。
默认的最大输出长度是32字节,过长的部分stracc会使用“…”省略。
比如,ls -l命令在运行过程中将读取/etc/passwd文件:

strace ls -l

read(4,“root❌0:0:root:/root:/bin/bash\n"…,4096)=2342
需要注意的是,文件名并不被strace当作C风格的字符串,其内容总是被完整地输出。
口对于结构体,strace将用“”输出该结构体的每个字段,并用“.”将每个字段隔开。
对于字段较多的结构体,strace将用“.·”省略部分输出。比如:

strace ls-l /dev/null

lstat64("/dev/null",{st_mode=S_IFCHR10666,st_rdev=makedev(1,3),…})= 0
上面的strace输出显示,lstat64系统调用的第1个参数是字符串输入参数“/dev/null”;
第二个参数则是stat结构体类型的输出参数(指针),strace仅显示了该结构体
参数的两个字段:st_mode和st_rdev。需要注意的是,当系统调用失败时,输出参数
将显示为传入前的值。

  • 对于位集合参数(比如信号集类型sigset_t),strace将用“[]”输出该集合中所有被
    置1的位,并用空格将每一项隔开。假设某个程序中有如下代码:
sigsettset;
sigemptyset(sset);
sigaddset(gset,SIGQUIT);
sigaddset(eset,SIGUSRI)
sigprocmask(SIG BLOCK,sset,NULL);

则针对该程序的strace命令将输出如下内容:
rt_sigprocmask(SIG_BLOCK,[QUIT USR1],NULL,8)=0
针对其他参数类型的输出方式,参考strace的man手册。
对于程序接收到的信号,stracc将输出该信号的值及其描述。
比如,我们在一个终端上运行“sleep100”命令,然后在另一个终端上使用strace命令跟踪该进程,
接着用“Ctrl+C”终止“sleep100”进程以观察strace的输出。具体操作如下:

sleep 100
ps -ef | grep sleep
sleep 100

在这里插入图片描述

在这里插入图片描述
可见,服务器当前正在执行epollwait系统调用以等待客户请求。值得注意的是,epoll_wait的第一个参数
(标识epoll内核事件表的文件描述符)的值是4,这和前面Isof命令的输出一致。
接下来使用上面nc或者telnet连接的方式对服务器发起一个连接并发送HTTP请求,
此时strace命令的输出如下
在这里插入图片描述
上面的输出分为五个部分,我们用空行将每个部分隔开。

  1. 第一部分从第一次epoll_wait系统调用开始。此次epoll_wait调用检测到了文件描述符3上的EPOLLIN事件。从显示结果中lsof的输出来看,文件描述符3正是服务器的监听socket。
    因此,这个事件表示有新客户连接到来,于是15-6服务器对监听socket执行了acccpt调用,accept返回一个新的连接socket,其值为6。
    接着,服务器清除这个新socket上的错误,设置其SOREUSEADDR属性,然后往cpoll内核事件表中注册该socket上的EPOLLRDHUP和EPOLLONESHOT两个事件,最后设置新socket为非阻塞的。
    2. 第二部分从第二次cpollwait系统调用开始。
    此次epollwait调用检测到了文件描述符5上的EPOLLIN事件,这表示客户端的第一行数据到达了,
    于是服务器执行了两次recv系统 调用来接收数据。
    第一次recv调用读取到42字节的客户数据,即“GET http//llocalhost/index.html HTTP/1.1\r\n”。
    第二次recv调用则失败了,errno是EAGAIN,这表示目前没有更多的客户数据可读。
    此后,服务器调用了futex函数对互斥锁解锁,以唤醒等待互斥锁的线程。
    可见,POSIX线程库中的pthread_mutex_unlock函数在内部调用了futex函数。
    3. 第三、四部分的内容和第二部分类似,我们不再整述。
    4. 第五部分中,epoll_wait调用检测到了文件描述符5上的EPOLLOUT事件,这表示工作线程正确地处理了客户请求,并准备好了待发送的数据,因此主线程开始执行writev系统调用往客户端写入HTTP应答。
    最后,服务器从epoll内核事件表中移除文件描述符5上的所有注册事件,并关闭该文件描述符。
    由此可见,strace命令使我们能够清楚地查看每次系统调用发生的时机,以及相关参数的值,这比用gdb调试更方便。

netstat

nctstat是一个功能很强大的网络信息统计工具。它可以打印本地网卡接口上的全部连
接、路由表信息、网卡接口信息等。对本书而言,我们主要利用的是上述功能中的第一个,
即显示TCP连接及其状态信息。毕竟,要获得路由表信息和网卡接口信息,我们可以使用输
出内容更丰富的route和ifconfig命令。

netstat命令常用的选项包括:

  • -n,使用IP地址表示主机,而不是主机名:使用数字表示端口号,而不是服务名称
  • -a,显示结果中也包含监听socket。
  • -t,仅显示TCP连接。
  • -r,显示路由信息。
  • -i,显示网卡接口的数据流量。
  • -c,每隔1s输出一次。
  • -0,显示socket定时器(比如保活定时器)的信息。
  • -p,显示socket所属的进程的PID和名字。
    下面我们运行wcbsrv服务器,并执行telnet命令对它发起一个连接请求
终端1:./15-6main 127.0.0.1 12345
终端2:telenet 127.0.01 12345
终端3:netstat -nat|grep 127.0.0.1:12345

在这里插入图片描述

然后执行命令netstat-natigrep127.0.0.1:13579查看连接状态,结果如下:

由以上结果可见,netstat的每行输出都包含如下6个字段(默认情况)

  • Proto,协议名。
  • Recv-Q,socket内核接收缓冲区中尚未被应用程序读取的数据量。
  • Send-Q,未被对方确认的数据量。
  • LocalAddress,本端的IP地址和端口号。
  • ForeignAddress,对方的IP地址和端口号。
  • State,socket的状态。对于无状态协议,比如UDP协议,这一字段将显示为空。
    -而对面向连接的协议而言,netstat支持的State包括ESTABLISHED、SYN_SENT、
    -SYN RCVD、FINWAIT1、FIN_WAIT2、TIME_WAIT、CLOSE、CLOSE_WAIT、
    LASTACK、LISTEN、CLOSING、UNKNOWN。

在这里插入图片描述
上面的输出中,第1行表示本地socket地址127.0.0.1:42915处于LISTEN状态,并等待任何远端socket(用0.0.0.0:*表示)对它发起连接。
第6行表示服务器和远端地址127.0.0.1:38964建立了一个连接。
第3行只是从客户端的角度重复输出第9行信息表示的这
个连接,因为我们是在同一台机器上运行服务器程序(websrv)和客户端程序(telnet)的。
在服务器程序开发过程中,我们一定要确保每个连接在任一时刻都处于我们期望的状
态。因此我们应该习惯于使用netstat命令。

vmstat

vmstat是virtualmemorystatistics的缩写,它能实时输出系统的各种资源的使用情况,
比如进程信息、内存使用、CPU使用率以及IO使用情况。

vmstat命令常用的选项和参数包括:

  • -f,显示系统自启动以来执行的fork次数。
  • -s,显示内存相关的统计信息以及多种系统活动的数量(比如CPU上下文切换次数)。
  • -d,显示磁盘相关的统计信息。
  • -p,显示指定磁盘分区的统计信息。
  • -S,使用指定的单位来显示。参数k、K、m、M分别代表1000、1024、1000000和
    1048576字节。
  • delay,采样间隔(单位是s),即每隔delay的时间输出一次统计信息。
  • count,采样次数,即共输出count次统计信息。
    默认情况下,vmstat输出的内容相当丰富。请看下面的示例:
#每5秒输出一次结果,共输出3次
vmstat 5 3

在这里插入图片描述
注意,第1行输出是自系统启动以来的平均结果,而后面的输出则是采样间隔内的平均结果。
vmstat的每条输出都包含6个字段,它们的含义分别是;

  • procs,进程信息。“r”表示等待运行的进程数目:“b”表示处于不可中断睡眠状态的进程数目。
  • memory,内存信息,各项的单位都是千字节(KB)。“swpd”表示虚拟内存的使用数量。
  • “free”表示空闲内存的数量。“buff”表示作为“buffercache”的内存数量。
    从磁盘读入的数据可能被保持在“buffercache”中,以便下一次快速访问。“cachc”表示作为“pagecache”的内存数量。
    待写入磁盘的数据将首先被放到“pagecache”中,然后由磁盘中断程序写入磁盘。
  • swap,交换分区(虚拟内存)的使用信息,各项的单位都是KB/s。“
    “si”表示数据由磁盘交换至内存的速率:“so”表示数据由内存交换至磁盘的速率。
    如果这两个值经常发生变化,则说明内存不足。
  • io,块设备的使用信息,单位是block/s。“bi”表示从块设备读入块的速率;“bo”表示向块设备写入块的速率。
  • system,系统信息。“in”表示每秒发生的中断次数;“cs”表示每秒发生的上下文切换(进程切换)次数。
  • cpu,CPU使用信息
    “us”表示系统所有进程运行在用户空间的时间占CPU总运行时间的比例:
    “sy”表示系统所有进程运行在内核空间的时间占CPU总运行时间的比例:
    “id”表示CPU处于空闲状态的时间占CPU总运行时间的比例:
    “wa”表示CPU等待IO事件的时间占CPU总运行时间的比例。
    不过,我们可以使用iostat命令获得磁盘使用情况的更多信息,也可以使用mpstat获得
    CPU使用情况的更多信息。vmstat命令主要用于查看系统内存的使用情况。

ifstat

iftat是interface statistics的缩写,它是一个简单的网络流量监测工具。其常用的选项和参数包括:

  • -a,监测系统上的所有网卡接口。
  • -i,指定要监测的网卡接口。
  • -t,在每行输出信息前加上时间截。
  • -b,以Kbits为单位显示数据,而不是默认的KB/s。
  • delay,采样间隔(单位是s),即每隔dclay的时间输出一次统计信息。
  • count,采样次数,即共输出count次统计信息。
    举例来说,我们在测试机器erest-laptop上执行如下命令:
#每个2秒输出一次结果,共输出5次
ifstat -a 2 5

在这里插入图片描述

从输出来看,VM-4-3-ubuntu拥有两个网卡接口:虚拟的回路接口io以及以太网网卡接口eth0。
ifstat的每条输出都以KB/s为单位显示各网卡接口上接收和发送数据的速率。
因此,使用ifstat命令就可以大概估计各个时段服务器的总输入、输出流量。

mpstat

mpstat是multi-processorstatistics的缩写,它能实时监测多处理器系统上每个CPU的使
用情况。

mpstat命令和iostat命令通常都集成在包sysstat中,安装sysstat即可获得这两个命今。

sudo apt-get install sysstat

mpstat命令的典型用法是(mpstat命令的选项不多,这里不再专门介绍)

mpstat [-P {|ALL}] [interval [count]]

选项P指定要监控的CPU号(0~CPU个数-1),其值“ALL”表示监听所有的CPU。
interval参数是采样间隔(单位是s),即每隔interval的时间输出一次统计信息。
count参数是采样次数,即共输出count次统计信息,但mpstat最后还会输出这count次采样结果的平
均值。与vmstat命令一样,mpstat命令输出的第一次结果是自系统启动以来的平均结果,而
后面(count-1)次输出结果则是采样间隔内的平均结果。
举例来说,我们在测试机器本机上执行如下命令:

#每隔5秒输出一次结果,共输出两次
mpstat -P ALL 5 2

在这里插入图片描述

为了显示的方便,我们省略了每行输出前导的时间截。
每次采样的输出都包含3条信息,每条信息都包含如下几个字段:

  • CPU,指示该条信息是哪个CPU的数据。“0”表示是第1个CPU的数据,“1”表示
    是第2个CPU的数据,“all”则表示是这两个CPU数据的平均值。
  • %usr,除了nice值为负的进程,系统上其他进程运行在用户空间的时间占CPU总运行时间的比例。
  • %nice,nice值为负的进程运行在用户空间的时间占CPU总运行时间的比例。
  • %sys,系统上所有进程运行在内核空间的时间占CPU总运行时间的比例, 但不包括硬件和软件中断消耗的CPU时间
  • %iowait,CPU等待磁盘操作的时间占CPU总运行时间的比例。
  • %irq,CPU用于处理硬件中断的时间占CPU总运行时间的比例。
  • %soft,CPU用于处理软件中断的时间占CPU总运行时间的比例。
  • %steal,一个物理CPU可以包含一对虚拟CPU,这一对虚拟CPU由超级管理程序管
    理。当超级管理程序在处理某个虚拟CPU时,另外一个虚拟CPU则必须等待它处理
    完成才能运行。这部分等待时间就是所谓的steal时间。该字段表示steal时间占CPU
    总运行时间的比例。
  • %guest,运行虚拟CPU的时间占CPU总运行时间的比例。
  • %idle,系统空闲的时间占CPU总运行时间的比例
    在所有这些输出字段中,我们最关心的是%user、%sys和%idle。
    它们基本上反映了我们的代码中业务逻辑代码和系统调用所占的比例,以及系统还能承受多大的负载。
    在这里插入图片描述
    很显然,在图2上面的输出中,执行系统调用占用的CPU时间比执行用户业务逻辑占用的CPU时间要多。
    这是因为我们在该机器上运行了压力测试工具,它在不停地执行recv/send系统调用来收发数据。
Logo

更多推荐