• 05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?笔记


    1.CPU 使用率

    为了维护 CPU 时间,Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值就加 1。

    节拍率 HZ 是内核的可配选项,可以设置为 100、250、1000 等。不同的系统可能设置不同数值,你可以通过查询 /boot/config 内核选项来查看它的配置值。比如在我的系统中,节拍率设置成了 250,也就是每秒钟触发 250 次时间中断。

    查看节拍率:

     grep 'CONFIG_HZ=' /boot/config-$(uname -r)
    
    • 1

    为了方便用户空间程序,内核还提供了一个用户空间节拍率 USER_HZ,它总是固定为 100,也就是 1/100 秒。这样,用户空间程序并不需要关心内核中 HZ 被设置成了多少,因为它看到的总是固定值 USER_HZ。

    2.查看CPU统计信息

    Linux 通过 /proc 虚拟文件系统,向用户空间提供了系统内部状态的信息,而 /proc/stat 提供的就是系统的 CPU 和任务统计信息。比方说,如果你只关注 CPU 的话,可以执行下面的命令:

    cat /proc/stat | grep ^cpu
    
    • 1

    在这里插入图片描述

    第一列表示的是 CPU 编号,如 cpu0、cpu1 ,而第一行没有编号的 cpu ,表示的是所有 CPU 的累加。其他列则表示不同场景下 CPU 的累加节拍数,它的单位是 USER_HZ,也就是 10 ms(1/100 秒),所以这其实就是不同场景下的 CPU 时间。

    • user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。
    • nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。
    • system(通常缩写为 sys),代表内核态 CPU 时间。
    • idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
    • iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
    • irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
    • softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
    • steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。
    • guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。
    • guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。
      在这里插入图片描述

    在这里插入图片描述

    3.系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?

    碰到常规问题无法解释的 CPU 使用率情况时,首先要想到有可能是短时应用导致的问题,比如有可能是下面这两种情况。

    第一,应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过 top 等工具也不容易发现。
    第二,应用本身在不停地崩溃重启,而启动过程的资源初始化,很可能会占用相当多的 CPU。对于这类进程,

    我们可以用 pstree 或者 execsnoop 找到它们的父进程,再从父进程所在的应用入手,排查问题的根源。

    4 .系统中出现大量不可中断进程和僵尸进程怎么办?

    今天我们主要通过简单的操作,熟悉了几个必备的进程状态。用我们最熟悉的 ps 或者 top ,可以查看进程的状态,这些状态包括运行(R)、空闲(I)、不可中断睡眠(D)、可中断睡眠(S)、僵尸(Z)以及暂停(T)等。其中,不可中断状态和僵尸状态,是我们今天学习的重点。

    • 不可中断状态,表示进程正在跟硬件交互,为了保护进程数据和硬件的一致性,系统不允许其他进程或中断打断这个进程。进程长时间处于不可中断状态,通常表示系统有
      I/O 性能问题。

    • 僵尸进程表示进程已经退出,但它的父进程还没有回收子进程占用的资源。短暂的僵尸状态我们通常不必理会,但进程长时间处于僵尸状态,就应该注意了,可能有应用程序没有正常处理子进程的退出。

    5. 怎么理解Linux软中断

    从“取外卖”看中断

    比如说你订了一份外卖,但是不确定外卖什么时候送到,也没有别的方法了解外卖的进度,但是,配送员送外卖是不等人的,到了你这儿没人取的话,就直接走人了。所以你只能苦苦等着,时不时去门口看看外卖送到没,而不能干其他事情。不过呢,如果在订外卖的时候,你就跟配送员约定好,让他送到后给你打个电话,那你就不用苦苦等待了,就可以去忙别的事情,直到电话一响,接电话、取外卖就可以了。这里的“打电话”,其实就是一个中断。没接到电话的时候,你可以做其他的事情;只有接到了电话(也就是发生中断),你才要进行另一个动作:取外卖。

    软中断

    如果你弄清楚了“取外卖”的模式,那对系统的中断机制就很容易理解了。事实上,为了解决中断处理程序执行过长和中断丢失的问题,Linux 将中断处理过程分成了两个阶段,

    也就是上半部和下半部:

    上半部用来快速处理中断,它在中断禁止模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。

    下半部用来延迟处理上半部未完成的工作,通常以内核线程的方式运行。

    网卡接收到数据包后,会通过硬件中断的方式,通知内核有新的数据到了。这时,内核就应该调用中断处理程序来响应它。你可以自己先想一下,这种情况下的上半部和下半部分别负责什么工作呢?

    对上半部来说,既然是快速处理,其实就是要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态(表示数据已经读好了),最后再发送一个软中断信号,通知下半部做进一步的处理。而下半部被软中断信号唤醒后,需要从内存中找到网络数据,再按照网络协议栈,对数据进行逐层解析和处理,直到把它送给应用程序。

    所以,这两个阶段你也可以这样理解:
    上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
    而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行。

    查看软中断和内核线程

    
    $ cat /proc/softirqs
                        CPU0       CPU1
              HI:          0          0
           TIMER:     811613    1972736
          NET_TX:         49          7
          NET_RX:    1136736    1506885
           BLOCK:          0          0
        IRQ_POLL:          0          0
         TASKLET:     304787       3691
           SCHED:     689718    1897539
         HRTIMER:          0          0
             RCU:    1330771    1354737
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    Android如何管理多进程
    Redis 缓存穿透、缓存击穿、缓存雪崩
    JVM及GC
    异步编排 Spring(线程池)
    【微机接口】汇编指令集:常用运算符
    MySQL Cluster
    vue3中的route和router
    WebAPI中使用WebService后发布注意要点
    基于python的23种设计模式
    【尚硅谷Java版】Flink1.13 转换算子之物理分区
  • 原文地址:https://blog.csdn.net/shandian534/article/details/125522941