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
- 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 资源紧张的时段已经过去了
Tasks: 106 total, 1 running, 105 sleeping, 0 stopped, 0 zombie
进程的运行情况:
分别是总进程数
106
, 正在运行的进程数 1, 睡眠的进程数
105
, 停止进程数 0, 僵尸进程数 0
%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): 被盗取的时间(通常是虚拟机)
KiB Mem: 4046976 total, 228196 used, 3818780 free, 32940 buffers
物理内存的情况:
total: 物理内存总量
used: 使用的物理内存总量
free: 空闲的物理内存总量
buffers: 用作内核缓存的内存量
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 下还可以安装命令 https://github.com/hishamhm/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 视角下的内存情况, 此时 buffers,cached 都属于被使用的, 已用内存的
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
- procs
r: 等待 CPU 资源的进程数, 包括正在运行的进程和等待运行的进程, 比 uptime 中的平均负载更能体现当前负载情况. 如果 r 的值大于 CPU 核数, 表明 CPU 资源已经饱和, 经常出现的话 CPU 资源可能存在瓶颈
b: 非中断睡眠状态下的进程数, 这些进程处于阻塞状态
memory
swpd: 虚拟内存的使用量. 如果这个值比较大, 则需要减少物理内存的使用; swpd 为 0 或 swpd 比较稳定且 si, so 为 0, 都是正常的
free: 系统可用内存数
swap
si, so: 交换区写入和读取的数量. 如果这个数据不为 0, 说明系统已经在使用交换区, 机器物理内存已经不足. 只有在 free 接近于 0, 并且 si, so 都较高时才能确定内存不够用
io
bi: 每秒从块设备接收到的块数
bo: 每秒发送到块设备的块数
system
in: 每秒的中断数, 包括时钟中断
cs: 每秒的上下文切换次数
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
查看网络设备的吞吐率, 判断网络设备是否已经饱和
- 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
查看 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 -u 和 sar -q 等来查看; 内存瓶颈, 可用 sar -B,sar -r 和 sar -W 等来查看; I/O 瓶颈, 可用 sar -b,sar -u 和 sar -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>
来源: https://juejin.im/entry/5b784f5ef265da43516a1ee1