← 返回信息流
AI 资讯Hacker News·3 小时前

详解Linux系统监控工具htop/top所有参数

原标题:Explanation of everything you can see in htop/top on Linux

速览

这是一篇详细教程,逐一解释了Linux系统中htop和top命令显示的CPU、内存、进程等各项指标的含义,帮助用户准确解读系统状态。通过了解这些参数,用户能更高效地进行性能监控和故障排查。该内容对系统管理员和开发者实用,但并非AI领域核心话题。

AI 深度解读

背景

对于使用 Linux 系统的用户来说,htoptop 是最常用的系统监控工具之一。然而,很多用户(包括经验丰富的开发者)并不完全理解屏幕上显示的所有指标的确切含义。例如,作者曾长期以为在双核机器上 load average 为 1.0 意味着 CPU 使用率是 50%——这个理解并不正确。本文作者决定系统地查阅资料、进行实验,并记录下 htop 中每一项数据的真正含义,同时分享通过 strace 查看系统调用、读取 /proc 文件系统来理解底层原理的方法。

核心内容

Uptime(运行时间)

htop 顶部显示的 Uptime 表示系统已经运行了多长时间。可以通过 uptime 命令获取相同信息:

$ uptime
12:17:58 up 111 days, 31 min, 1 user, load average: 0.00, 0.01, 0.05

uptime 命令从 /proc/uptime 文件中读取数据。该文件包含两个数字:

  • 第一个数字:系统自启动以来经过的总秒数。
  • 第二个数字:系统空闲的总秒数(在多核系统上,该值可能大于总运行时间,因为它是所有核心空闲时间的总和)。

通过 strace 可以验证 uptime 命令打开的文件:

$ strace uptime 2>&1 | grep open
open("/proc/uptime", O_RDONLY) = 3
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 4
open("/proc/loadavg", O_RDONLY) = 4

也可以直接使用 strace -e open uptime 简化输出。既然可以直接读取文件内容,为什么还需要 uptime 命令?因为 uptime 的输出对人类更友好,而秒数更适合在脚本或程序中直接使用。

Load average(负载均值)

uptime 输出中还有三个表示负载均值的数字,它们来自 /proc/loadavg 文件:

$ cat /proc/loadavg
0.00 0.01 0.03 1/120 1500
  • 前三列:分别表示最近 1 分钟、5 分钟、15 分钟的平均系统负载。
  • 第四列:当前正在运行的进程数 / 总进程数。
  • 第五列:最近一次使用的进程 ID。

进程 ID 与运行状态

每当启动一个新进程,系统会分配一个唯一的 ID(PID)。PID 通常是递增的,除非耗尽后重用。PID 1 通常属于 /sbin/init(在启动时启动)。

通过启动 sleep 10 & 并观察 /proc/loadavg 的变化,可以理解“运行中的进程”的含义:

$ cat /proc/loadavg
0.00 0.01 0.03 1/123 1566
$ sleep 10 &
[1] 1567

此时 1/123 表示当前有 1 个进程正在运行或准备运行(即 cat 本身),总共有 123 个进程。如果运行 sleep 30 后再看,仍然只有 1 个运行中的进程,因为 sleep 处于休眠状态(等待时间过去),并不占用 CPU。

运行中的进程(running process)是指当前正在物理 CPU 上执行或等待 CPU 调度执行的进程。如果启动一个消耗 CPU 的后台任务,比如 cat /dev/urandom > /dev/null &/proc/loadavg 会显示:

$ cat /proc/loadavg
1.00 0.69 0.35 2/124 1679

此时有 2 个运行中的进程(随机数生成进程和读取 /proc/loadavgcat 进程),负载均值也随之上升。

负载均值的计算方式

负载均值并不是简单的过去 1、5、15 分钟内运行进程数的算术平均,而是指数加权移动平均(exponentially damped moving average)。从数学上讲,三个值都从系统启动开始累积,以不同的速度指数衰减。1 分钟负载均值包含大约 63% 的最近 1 分钟负载,以及 37% 的之前负载。因此,严格来说,1 分钟负载均值不仅包含最近 60 秒的活动,但主要受最近一分钟影响。

负载均值与 CPU 使用率的关系

负载均值计算的是正在运行(或等待运行)以及不可中断状态(等待磁盘或网络 I/O)的进程数量。在单核 CPU 上,如果有一个 CPU 密集型进程,负载均值为 1.0 意味着 CPU 利用率为 100%。在双核机器上,负载均值为 2.0 才对应 100% CPU 利用率。但需要注意的是,由于负载均值也包含不可中断的进程(例如等待 I/O 的进程),这些进程并不消耗 CPU,因此从负载均值推断 CPU 使用率并不完全准确。这也就是为什么有时看到高负载均值但 CPU 并不繁忙的原因。

要查看瞬时 CPU 利用率,可以使用 mpstat 工具(需要安装 sysstat 包):

$ mpstat 1
Linux 4.4.0-47-generic (hostname) 12/03/2016 _x86_64_ (1 CPU)
10:16:20 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
10:16:21 PM all 0.00 0.00 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

那么为什么还要用负载均值?Linux 内核源码中的注释给出了答案:

/*
 * kernel/sched/loadavg.c
 *
 * This file contains the magic bits required to compute the global loadavg
 * figure. Its a silly number but people think its important. We go through
 * great pains to make it work on big machines and tickless kernels.
 */

可见,负载均值是一个“愚蠢的数字”,但人们认为它很重要,因此内核费尽心思使其在大机器和无 tick 内核上也能正常工作。

Processes(进程数)

htop 右上角,显示的是任务总数(Tasks)而非进程数(Processes)。这是因为 Linux 内核内部将进程称为“任务”(task)。htop 使用 Tasks 可能是为了节省屏幕空间。

htop 可以显示线程:按 Shift+H 切换线程可见性,如果看到 Tasks: 23, 10 thr 表示线程已显示。按 Shift+K 可以显示内核线程,此时会显示 Tasks: 23, 40 kthr

Process ID / PID(进程 ID)

每次启动新进程时,系统会分配一个标识号,即进程 ID(PID)。PID 通常从 1 开始递增(/sbin/init 的 PID 为 1),直到耗尽后重用。

关键要点

  • Uptime 是从 /proc/uptime 读取的,包含总运行秒数和总空闲秒数(多核下空闲秒数可能更大)。uptime 命令只是对人类友好的格式化输出。
  • Load average 来自 /proc/loadavg,前三列是 1、5、15 分钟的指数加权移动平均,并非简单的算术平均。它们反映的是处于运行或不可中断状态的进程数量,而不是 CPU 使用率。
  • 负载均值与 CPU 使用率的关系:在单核机器上,负载均值
查看原文 →peteris.rocks