性能观察工具top

top 命令用于显示Linux进程,提供了一个动态实时观察运行系统的功能。通常,这个命令可以显示系统的综合信息,并且显示出由Linux内核管理的进程和线程。 top 通过交互命令模式,提供了进程状态和使用资源。

备注

虽然 top 命令(另一个命令是 ps进程检查工具 )是我们使用Linux最常用的工具,浅显明了。但是,实际上这个工具提供了极其强大的多种观察角度,可以帮助我们分析系统。相应,我们需要掌握一些使用技巧。

top解读

  • 一个简单的案例:

    top - 22:48:55 up 51 days,  8:47,  1 user,  load average: 10.79, 10.45, 16.44
    Tasks: 5971 total,  20 running, 5948 sleeping,   0 stopped,   3 zombie
    Cpu(s):  8.8%us,  7.4%sy,  0.0%ni, 82.9%id,  0.3%wa,  0.0%hi,  0.6%si,  0.0%st
    Mem:  263819896k total, 100621984k used, 163197912k free,  1986536k buffers
    Swap:        0k total,        0k used,        0k free, 30298168k cached
    
      PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
    20855 root      20   0 1308m 1.1g 6276 S 100.6  0.4 852:57.14 qemu-kvm
     9830 root      20   0 8770m 8.3g 5544 S 58.3  3.3   2471:14 qemu-kvm
     2955 root      20   0 1321m 1.1g 5340 S 42.0  0.4   5627:29 qemu-kvm
    

解析:

  • 第一行 top - 22:48:55 up 51 days,  8:47,  1 user,  load average: 10.79, 10.45, 16.44

    当前时间( ``22:48:55`` ),系统启动时间( ``up 51 days, 8:47`` ),当前用户数量( ``1 user`` ),以及1分钟,5分钟和15分钟的 :ref:`` ``10.79, 10.45, 16.44``
    

top检查线程数量

top 命令提供了一个 nTH 字段来显示进程的线程数量:

  • 按下 f 进入 field 选择页面

  • 使用上下键在字段上找到 nTH (Number of Threads),然后按下 空格键 表示选择显示

  • 再按一下 s 键表示以 nTH 排序

  • 再按一下 q 退出 field 选择页面

此时 top 就会完整输出每个进程的线程数量并且方便观察哪个进程的线程过多

举例:

通过 nTH 字段在 top 中显示每个进程的线程数量
top - 15:54:58 up 1 day,  4:53, 11 users,  load average: 0.54, 0.63, 0.60
Tasks: 629 total,   1 running, 628 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.3 us,  0.2 sy,  0.0 ni, 99.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem : 386813.0 total, 329241.6 free,  52052.1 used,   5519.3 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used. 332442.0 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                   nTH
   2001 grafana   20   0 5025464 144876  66116 S   0.0   0.0   3:46.33 grafana                    57
  46488 root      20   0 4700380  66800  48436 S   0.0   0.0   1:34.33 dockerd                    54
   2020 prometh+  20   0 2214844 113796  55460 S   0.0   0.0   4:12.47 prometheus                 53
   2014 prometh+  20   0  726728  21224  11968 S   0.0   0.0  14:22.54 node_exporter              52
   2007 ipmi-ex+  20   0  716884  17480   8512 S   0.0   0.0   0:41.42 ipmi_exporter              29
  81266 huatai    20   0 2001676  10292   5252 S   0.0   0.0   0:02.28 apache2                    27
  81267 huatai    20   0 2001676  10644   5384 S   0.0   0.0   0:02.40 apache2                    27
  37897 root      20   0 2467684  50008  33528 S   0.0   0.0   1:43.43 containerd                 24
  57113 root      20   0 2018900  49400  33808 S   0.0   0.0   0:00.84 libvirtd                   22
   4012 grafana   20   0  718192  13124  10008 S   0.0   0.0   0:00.09 pcp_redis_datas             9
   7300 libvirt+  20   0   16.7g  16.0g  19668 S   7.3   4.2 131:08.50 qemu-system-x86             9
...

不过,实践也发现一个问题,如果一个进程的线程数量实在太多,超过了3位数值(999+)就无法完整在 nTH 显示,例如我在排查线上的一个线程数量过多告警:

topnTH 字段无法显示超过3位数值
top - 16:02:21 up 405 days,  5:56,  1 user,  load average: 100.40, 94.44, 95.02
Tasks: 1654 total,   2 running, 1017 sleeping,   0 stopped,  19 zombie
%Cpu(s): 57.6 us, 15.1 sy,  0.0 ni, 27.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 79093344+total, 22562152 free, 34725468 used, 73364582+buff/cache
KiB Swap:        0 total,        0 free,        0 used. 52038676 avail Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                              nTH
378199 root      20   0  355.1g   6.5g   5.6g S  66.5  0.9 343573:12 rund-c8fe00be                                                                        14+
413302 root      20   0  375.5g 350.1g 350.0g S  2654 46.4 262097,00 rund-10930310                                                                        352
423338 root      20   0   10.7g 166248  53324 S  13.0  0.0   4787:05 containerd                                                                           236
198370 root      20   0   31.2g   7.3g   7.2g S 110.8  1.0 470711:52 rund-822bb8d1                                                                        205
405808 root      20   0  168512  45700  10036 S   0.0  0.0 813:53.55 node_agent_k8s                                                                       168
...

那么这个 378199 PID实际有多少线程呢?

可以使用 ls 检查 /proc/<PID>/task 数量:

$ls /proc/378199/task | wc -l
149642

或者直接查看进程 status 中的 Threads 计数:

$cat /proc/378199/status | grep Threads
Threads:149705

可以看到这个 378199 进程的线程数量不断增加,这可能存在线程泄漏

参考