## 1.uptime ``` $ uptime 02:34:03 up 2 days, 20:14, 1 user, load average: 0.63, 0.83, 0.88 ``` - 02:34:03 //当前时间 - up 2 days, 20:14 //系统运行时间 - 1 user //正在登录用户数 - 最后三个数字,依次则是过去 1 分钟、5 分钟、15 分钟的平均负载(Load Average)。 平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。 既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上都刚好运行着一个进程,这样每个 CPU 都得到了充分利用。比如当平均负载为 2 时,意味着: - 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。 - 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。 - 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。 当平均负载高于 CPU 数量 70% 的时候,你就应该分析排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。 ## 2.如何排查cpu升高原因 - mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。 - pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。 ``` mpstat -P ALL 5 ``` ``` pidstat -u 5 1 ``` ## 3. 上下文切换查看 **总体上** ``` # 每隔5秒输出1组数据 $ vmstat 5 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 7005360 91564 818900 0 0 0 0 25 33 0 0 100 0 0 ``` - cs(context switch)是每秒上下文切换的次数。 - in(interrupt)则是每秒中断的次数。 - r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。 - b(Blocked)则是处于不可中断睡眠状态的进程数。 **进程级别** ``` # 每隔5秒输出1组数据 $ pidstat -w -u -t 5 Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU) 08:18:26 UID PID cswch/s nvcswch/s Command 08:18:31 0 1 0.20 0.00 systemd 08:18:31 0 8 5.40 0.00 rcu_sched ... ``` 这个结果中有两列内容是我们的重点关注对象。 - 一个是 cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数, - 另一个则是 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。 这两个概念你一定要牢牢记住,因为它们意味着不同的性能问题: - 所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。 - 而非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。 ## 4. 查看中断 ``` # -d 参数表示高亮显示变化的区域 $ watch -d cat /proc/interrupts CPU0 CPU1 ... RES: 2450431 5279697 Rescheduling interrupts ... ``` ## 5. 查看进程内部消耗 ``` perf top ``` ## 6.top - R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正在等待运行。 - D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。 - Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进程的描述符、PID 等)。 - S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。 - I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高, I 状态的进程却不会。 - T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状态。 ## 6.总结 如果系统的上下文切换次数比较稳定,那么从数百到一万以内,都应该算是正常的。 但当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,就很可能已经出现了性能问题。 这时,你还需要根据上下文切换的类型,再做具体分析。比方说: - 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题; - 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈; - 中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。