检查服务器性能的7个命令

1,463 阅读7分钟

top

示例:

kasheemlew@ubuntu-14:~$ top
top - 17:27:11 up 33 min,  1 user,  load average: 0.00, 0.00, 0.00
Tasks: 106 total,   1 running, 105 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.3 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   4046976 total,   228196 used,  3818780 free,    32940 buffers
KiB Swap:  4190204 total,        0 used,  4190204 free.   105652 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  822 root      20   0  333184  13156   7380 S  0.3  0.3   0:01.13 docker-containe
 1461 kasheem+  20   0  105804   3584   2508 S  0.3  0.1   0:00.05 sshd
 1530 kasheem+  20   0   24972   3040   2540 R  0.3  0.1   0:00.01 top
    1 root      20   0   33512   3992   2668 S  0.0  0.1   0:00.86 init
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd
...
...
...

top包含了很多内容,分为两个板块,中间由一个空行隔开。第一个板块是Summary Display的内容包括总任务数、CPU、内存的占用,第二个板块是Fields/Columns。下面分行介绍其中每个参数的意思

Summary Display

  1. top - 17:27:11 up 33 min, 1 user, load average: 0.00, 0.00, 0.00

    系统的运行情况和负载情况,通过uptime也可以查询:

    • top - 17:27:11 up 33 min: 当前系统时间是 17:27:11,已经运行了33 min,这里的时间会随时间变化,可见top的输出值也当前时刻的值,如果要具体研究某一时刻的情况,需要先停止top命令
    • 1 user: 当前有1个用户登录
    • load average: 0.00, 0.00, 0.00: 输出分别表示1分钟、5分钟、15分钟的平均负载情况,是等待CPU资源的进程和阻塞在不可中断IO进程的数量,也就是任务队列的长度。如果1分钟负载高,而15分钟负载低,则现在正处于CPU资源紧张时,如果1分钟负载低,而15分钟负载高,则说明CPU资源紧张的时段已经过去了
  2. Tasks: 106 total, 1 running, 105 sleeping, 0 stopped, 0 zombie

    进程的运行情况:

    • 分别是总进程数106,正在运行的进程数1,睡眠的进程数105,停止进程数0,僵尸进程数0
  3. %Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

    CPU的占用情况:

    • us(user): 用户空间占CPU的百分比
    • sy(system): 系统内核空间占CPU的百分比
    • ni(niced): 用户进程空间内改变过优先级的进程占用CPU百分比
    • id(idle): 空闲CPU百分比
    • wa(wait): 等待输入输出的CPU时间百分比
    • hi(hardware interrupt): 处理硬件中断的时间所占百分比
    • si(software interrupt): 处理软件中断的时间所占百分比
    • st(stolen): 被盗取的时间(通常是虚拟机)
  4. KiB Mem: 4046976 total, 228196 used, 3818780 free, 32940 buffers

    物理内存的情况:

    • total: 物理内存总量
    • used: 使用的物理内存总量
    • free: 空闲的物理内存总量
    • buffers: 用作内核缓存的内存量
  5. KiB Swap: 4190204 total, 0 used, 4190204 free. 105652 cached Mem

    大多数虚拟内存的情况:

    • total: 交换区总量
    • used: 交换区使用量
    • free: 交换区空闲量
    • cached: 缓冲的交换区总量

Fields/Columns

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
进程ID 任务拥有者 优先级,越小越早被执行 nice值【PR(new)=PR(old)+nice】 占用的虚拟内存大小 常驻内存,非交换的物理内存大小 共享内存大小 进程状态 CPU占用百分比 内存占用百分比 进程在1/100秒内使用的CPU时间 命令名或命令行

Unix下还可以安装命令htop用来代替top

free

free可以用来显示物理内存、交换分区、内核是用的缓冲区的情况。默认的单位是KB,可以使用标志位 -b(字节),-k(KB),-m(MB),-g(GB),--tera(TB)指定单位,也可以使用-h给每一项设定为最接近的单位。free的输出值是执行命令瞬间的值,如果要获取实时的值可以通过-s指定间隔的秒数

kasheemlew@ubuntu-14:~$ free
             total       used       free     shared    buffers     cached
Mem:       4046976     228840    3818136        512      32948     105772
-/+ buffers/cache:      90120    3956856
Swap:      4190204          0    4190204

第一行表头分别表示总计物理内存的大小、已使用多大、可用有多少、多个进程共享的内存总额、磁盘缓存的大小。

第二行Mem:是OS视角下的内存情况,此时bufferscached都属于被使用的,已用内存的3818136里包含了内核(OS)使用 + Application使用的 + buffers + cached

第三行-/+ buffers/cache的意思是:

  • -buffers/cache 等于第1行的 used - buffers - cached,是被程序使用的内存
  • +buffers/cache 等于第1行的 free + buffers + cached,是可以挪用的内存

    与第二行不同的是,这里是从应用程序角度来看,buffers/cached 是属于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。所以从应用程序的角度来说,可用内存 = 系统free memory + buffers + cached

    buffers是指 Buffer Cache, 是针对磁盘块的缓存,而cache是 Page Cache, 针对文件inode的读写。在有文件系统的情况下直接对文件操作的数据会缓存到 Page Cache,而直接对磁盘读写的数据会缓存到 Buffer Cache。如果

第四行是交换分区SWAP的,也就是虚拟内存。如果swap经常使用很多的话需要考虑增加物理内存

free命令获得的具体数据来源于文件/proc/meminfo, 通过cat /proc/meminfo可以得到:

kasheemlew@ubuntu-14:~$ cat /proc/meminfo
MemTotal:        4046976 kB
MemFree:         3818108 kB
MemAvailable:    3775616 kB
Buffers:           32948 kB
Cached:           105776 kB
SwapCached:            0 kB
Active:            89800 kB
Inactive:          90448 kB
Active(anon):      41772 kB
Inactive(anon):      260 kB
Active(file):      48028 kB
Inactive(file):    90188 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4190204 kB
SwapFree:        4190204 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         41520 kB
Mapped:            45504 kB
Shmem:               512 kB
Slab:              24448 kB
SReclaimable:      14124 kB
SUnreclaim:        10324 kB
KernelStack:        2096 kB
PageTables:         2392 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6213692 kB
Committed_AS:     227244 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
HardwareCorrupted:     0 kB
AnonHugePages:     12288 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       57280 kB
DirectMap2M:     4136960 kB

vmstat

vmstat输出一些系统的核心指标,包括内核线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息。后面添加时间参数可以设定每隔几秒输出一行,单位:KB

kasheemlew@ubuntu-14:~$ vmstat
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 3817976  32948 105780    0    0    4     0  19   77   0  0 100  0  0
  1. procs

    • r:等待CPU资源的进程数,包括正在运行的进程和等待运行的进程,比uptime中的平均负载更能体现当前负载情况。如果r的值大于CPU核数,表明CPU资源已经饱和,经常出现的话CPU资源可能存在瓶颈
    • b:非中断睡眠状态下的进程数,这些进程处于阻塞状态
  2. memory

    • swpd:虚拟内存的使用量。如果这个值比较大,则需要减少物理内存的使用;swpd为0或swpd比较稳定且si, so为0,都是正常的
    • free:系统可用内存数
  3. swap

    • si, so:交换区写入和读取的数量。如果这个数据不为0,说明系统已经在使用交换区,机器物理内存已经不足。只有在 free接近于0,并且si, so都较高时才能确定内存不够用
  4. io

    • bi: 每秒从块设备接收到的块数
    • bo: 每秒发送到块设备的块数
  5. system

    • in: 每秒的中断数,包括时钟中断
    • cs: 每秒的上下文切换次数
  6. cpu

    • us, sy, id, wa, st:消耗CPU的时间,同 top 的 Summary Display 第 3 点

mpstat

mpstat输出了CPU相关的数据,可以通过-P指定CPU,也可以通过mpstat 2 5这种形式指定每2秒输出1次,共输出5次。 用lscpu可以了解CPU的总体情况

kasheemlew@ubuntu-14:~$ mpstat
Linux 4.4.0-31-generic (ubuntu-14) 	03/07/2018 	_x86_64_	(1 CPU)

04:52:14 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:52:14 PM  all    0.02    0.00    0.03    0.01    0.00    0.00    0.00    0.00    0.00   99.94

第一行输出了操作系统的版本、内核版本、当前日期、系统架构和CPU的数量。由于这里只有单核,所以只显示了all。在多核情况下如果某一个CPU占用率特别高,很可能是某个线程引起的

%usr 用户态的CPU时间(%),不包含nice值为负的进程
%nice nice值为负进程的CPU时间(%)
%sys 内核时间(%)
%iowait 硬盘IO等待时间(%)
%irq 硬中断时间(%)
%soft 软中断时间(%)
%idle CPU除去等待磁盘IO操作外闲置时间(%)

iostat

iostat主要用于查看机器磁盘IO情况, 也可以指定输出的间隔时间和输出的次数,默认情况下的输出是这样:

kasheemlew@ubuntu-14:~$ iostat
Linux 4.4.0-31-generic (ubuntu-14) 	03/07/2018 	_x86_64_	(1 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.02    0.00    0.03    0.00    0.00   99.94

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda               0.24         6.49         1.70     272210      71238
dm-0              0.29         6.03         1.70     253165      71224
dm-1              0.00         0.02         0.00        896          0

这里按空行分成了三个板块,前两个板块中的参数都已经在前面的命令中出现过了。第三个板块主要是各个设备的读写情况,上面的例子中可以看到磁盘sda和它的各个分区的情况

  • tps:该设备每秒的传输次数。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。

  • kB_read/s:每秒从设备读取的数据量

  • kB_wrtn/s:每秒向设备写入的数据量
  • kB_read:读取的总数据量
  • kB_wrtn:写入的总数量数据量

添加-x输出更多详细信息,这些数据有:

  • rrqm/s(wrqm/s):每秒这个设备相关的读取(写入)请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)
  • rsec/s(wsec/s):每秒读取(写入)的扇区数
  • r/s(w/s):每秒向设备发起的读取(写入)请求的数量
  • await:每一个IO请求的处理的平均时间(单位:ms)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
  • %util:处理IO时间所占百分比例如,该参数暗示了设备的繁忙程度。如果该参数是100%表示设备已经接近满负荷运行了(多磁盘时即使%util是100%,因为磁盘的并发,磁盘未必到了瓶颈)。

sar

使用sar(System Activity Reporter系统活动情况报告)也可以获取文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。

-A输出所有报告的总和, -u输出CPU使用情况的统计信息, -v输出inode、文件和其他内核表的统计信息,-d输出每一个块设备的活动信息, -r输出内存和交换空间的统计信息, -b显示I/O和传送速率的统计信息, -a文件读写情况, -c输出进程统计信息,每秒创建的进程数, -R输出内存页面的统计信息, -y输出终端设备活动情况, -w输出系统交换活动信息。

有一些报告的内容前面已经提到过了,下面主要介绍两个网络性能方面的应用,通过-n指定相关的数据,可选的参数有DEV, EDEV, NFS, NFSD, SOCK, IP, EIP, ICMP, EICMP, TCP, ETCP, UDP, SOCK6, IP6, EIP6, ICMP6, EICMP6, UDP6

  1. 查看网络设备的吞吐率, 判断网络设备是否已经饱和

    kasheemlew@ubuntu-14:~$ sar -n DEV 1
    Linux 4.4.0-31-generic (ubuntu-14) 	03/07/2018 	_x86_64_	(1 CPU)
    
    07:36:29 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
    07:36:30 PM        lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    07:36:30 PM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    07:36:30 PM      eth0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
    
  2. 查看TCP连接状态

    kasheemlew@ubuntu-14:~$ sar -n TCP,ETCP 1
    Linux 4.4.0-31-generic (ubuntu-14) 	03/07/2018 	_x86_64_	(1 CPU)
    
    07:37:52 PM  active/s passive/s    iseg/s    oseg/s
    07:37:53 PM      0.00      0.00      1.00      0.00
    
    07:37:52 PM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
    07:37:53 PM      0.00      0.00      0.00      0.00      0.00
    
  • active/s:每秒本地发起的TCP连接数,既通过connect调用创建的TCP连接;
  • passive/s:每秒远程发起的TCP连接数,即通过accept调用创建的TCP连接;
  • retrans/s:每秒TCP重传数量;

TCP连接数可以用来判断性能问题是否由于建立了过多的连接,进一步可以判断是主动发起的连接,还是被动接受的连接。TCP重传可能是因为网络环境恶劣,或者服务器压力过大导致丢包。

要判断系统瓶颈问题,有时需几个 sar 命令选项结合起来。CPU瓶颈可用 sar -usar -q 等来查看;内存瓶颈,可用 sar -Bsar -rsar -W 等来查看;I/O瓶颈,可用 sar -bsar -usar -d 等来查看

strace

strace用来查看内核态的函数调用情况(用户态的函数调用情况用ltrace查看)

使用strace -p可以指定相应进程的PID,对其进行跟踪,加上-c标记之后可以对跟踪的情况进行统计,例如下面是指定的PID为1383的sshd进行跟踪

kasheemlew@ubuntu-14:~$ sudo strace -cp 1583
Process 1583 attached

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         6           read
  0.00    0.000000           0         6           write
  0.00    0.000000           0        24           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0        11           select
------ ----------- ----------- --------- --------- ----------------
100.00    0.000000                    49           total

到了这里,如果还要继续跟踪某一个具体操作可以加上-T,统计每一次调用的时间可以用-e指定某一操作,如下:

kasheemlew@ubuntu-14:~$ sudo strace -T -e read -p 1583
read(11, "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\"..., 16384) = 105 <0.000004>
read(11, "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\"..., 16384) = 105 <0.000004>
read(3, "r\360\235\260\330\3\177|\217\265\327\351\275\36\210\241\266\247C\257!;\225\17[hz\365\216\27\341\363"..., 16384) = 36 <0.000006>