CPU问题场景分析

进程的状态

通过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 的缩写,表示进程处于暂停或者跟踪状态。
  •  X,也就是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令中看到它。

向某个进程发送SIGSTOP信号,进程会响应这个信号编程Stop状态。再发送SIGCONT信号,进程会恢复运行。

系统中出现大量僵尸进程

什么情况下会出现僵尸进程?

首先,子进程由父进程fork而来,父进程fork子进程后,会通过两种方式回收子进程的资源。

  1.   一种是注册SIGCHLD信号处理函数,在子进程退出时会发送SIGCHLD信号给父进程,父进程收到信号后执行钩子函数回收子进程的资源。
  2.   一种是在fork子进程后,调用wait()或waitpid()等待子进程执行完毕,子进程执行完毕后回收子进程的资源。

如果父进程没有通过以上两种方式处理,或者子进程执行得非常快导致父进程还没来得及调用wait()或者waitpid()函数,子进程就结束了,就会产生僵尸进程。

如果系统出现大量僵尸进程,可以用pstree命令查看进程树,找出是什么进程fork的子进程。进而使用perf对进程的运行进行采样,看看是什么地方fork的子进程,再结合代码分析,找出没有父进程没有回收子进程的原因进行修复。

iowait过高

什么情况下会出现iowait过高?

一种是应用是属于IO密集型应用,本身会频繁进行数据读写,对于此类应用我们需要性能较高的IO设备。如果IO设备本身没有问题,我们需要分析应用什么问题导致了iowait过高。首先通过dstat命令检查下磁盘读写,是不是真的有大量的磁盘IO。

如果有,则需要找出进行IO读写的进程,进而使用perf 或者 strace进行分析。

CPU软中断过高

Linux 将中断处理过程分成了两个阶段,也就是上半部和下半部:

  • 上半部由硬件触发,直接处理硬件请求,它在中断屏蔽模式下运行,主要处理跟硬件紧密相关的或时间敏感的工作。

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

上半部分即为硬中断或者硬件中断,下半部分为软中断。上半部会打断 CPU 正在执行的任务,然后立即执行中断处理程序。而下半部以内核线程的方式执行,并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU 编号”,比如说, 0 号 CPU 对应的软中断内核线程的名字就是 ksoftirqd/0。proc 文件系统中记录了中断情况:

  • /proc/softirqs 提供了软中断的运行情况;

  • /proc/interrupts 提供了硬中断的运行情况。

通过如下命令可以查看CPU软中断的变化:

watch -d "cat /proc/softirqs | awk 'NR == 1{printf \"%-15s %-15s %-15s %-15s %-15s\n\",\" \",\$1,\$2,\$3,\$4}; NR > 1{printf \"%-15s %-15s %-15s %-15s %-15s\n\",\$1,\$2,\$3,\$4,\$5}'"

进而观察

  HI: 处理高优先级的任务 
  TIMER: 用于处理定时器中断,例如周期性的系统定时器
  NET_TX: 网络发送
  NET_RX: 网络接收
  BLOCK: 块设备IO操作引起的软中断
  IRQ_POLL: 0 0
  TASKLET: 用于处理轻量级的任务,通过tasklet机制实现
  SCHED: 内核调度
  HRTIMER: 0 0
  RCU: RCU锁引起的中断
哪个类型的中断变化速率过快,找到分析的方向。

 

 

 

posted @ 2023-08-25 16:26  小张同学哈  阅读(81)  评论(0)    收藏  举报