图片来自极客时间,如有版权问题,请联系我删除。
扫码加入学习!
平均负载
top或uptime命令
load average: 0.63, 0.83, 0.88
指的是系统可运行状态和不可中断状态的进程数。
- 可运行状态指的是正在使用cpu或正在等待cpu的进程。
- 不可中断状态指的是内核态关键流程中,比如说等待硬件设备I/O响应(ps命令D状态)。
一般平均负载大于cpu数量的70%需要关注性能问题。
平均负载高不一定CPU使用率高,等待I/O也会导致平均负载升高。
CPU上下文切换
概念
CPU的上下文切换就是把CPU寄存器和程序计数器保存起来,然后加载新任务的上下文。
系统调用
进程用户态到内核态需要系统调用完成,比如文件读写。一次系统调用会发生两次CPU上下文切换。
通过系统调用过程称为特权模式切换,并且不会涉及虚拟内存等进程用户态资源
进程上下文切换
进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态。
Linux通过TLB管理虚拟内存到物理内存,所以虚拟内存更新会导致TLB刷新。多核处理器共享缓存,所以会影响当前处理器的进程和共享缓存的其他处理器的进程。
时间片轮转调度、系统资源不足、进程sleep挂起和硬件中断都会导致进程上下文切换。
线程上下文切换
- 前后两个线程属于不同进程,和进程上下文切换相同;
- 属于同一进程,因为虚拟内存共享,所以只切换线程私有数据、寄存器等不共享数据。
中断上下文切换
中断会打断进程的正常调度和执行。上下文只包括内核态中断服务程序执行所必须的状态,CPU寄存器、内核堆栈、硬件中断参数等。
CPU上下文切换排查命令
$ vmstat
$ pidstat -w -u 1
//wt可以看线程上下文切换
$ pidstat -wt 1
// -d 参数表示高亮显示变化的区域
$ watch -d cat /proc/interrupts
CPU使用率
为了维护系统CPU时间,linux通过定义节拍率,触发事件中断。每次中断,jiffies的值+1。
//内核,每秒触发250次时间中断
$ grep 'CONFIG_HZ=' /boot/config-$(uname -r)
CONFIG_HZ=250
//用户空间节拍率
USER_HZ=100
jiffies统计值:
$ cat /proc/stat | grep ^cpu
$ cat /proc/[pid]/stat
cpu使用率 = 1 - (空闲时间/总cpu时间)
查看CPU使用率的命令
- top 默认统计3秒间隔;
- ps 统计进程的整个生命周期;
- pidstat [pid] 查看进程内核用户态CPU使用率。
CPU过高排查
- GDB调试;
- perf top命令,可以显示占用CPU时钟最多的函数或指令。
有时,会发现top命令%Cpu(s)使用率高,但进程cpu使用率总和达不到%Cpu(s)。
- 应用调用其他二进制程序,这些程序运行时间较短;
- 应用本身在不停奔溃重启。
不可中断和僵尸进程
$ ps aux | grep /app
- 不可中断(D),一般表示进程在和硬件交互,不允许中断;
- 僵尸进程(Z),表示进程实际已经结束,但父进程没有回收它的资源(比如进程的描述符、PID等)。
进程组和会话
- 进程组表示一组相互关联的进程,比如每个子进程都是父进程所在组的成员;
- 会话是指共享同一个控制终端的一个或多个进程组。
比如,SSH会打开一个控制终端(TTY),这个就对应一个会话(s)。我们在终端运行命令以及它们的子进程,构成了一个个进程组。前台运行构成前台进程组(+),后台运行构成后台进程组。
问题排查
如果进程长时间不可中断,通过dsta、pidstat查看是否磁盘I/O问题。但iowait高不一定代表I/O有瓶颈,当系统中只有I/O类型的进程运行时,iowait也会很高。
僵尸进程可以使用$ pstree -aps [pid]查看父进程。
软中断
Linux将中断分成上半部和下半部:
- 上半部快速处理中断,中断禁止模式下运行,主要处理与硬件相关或时间敏感工作(会打断CPU正在执行的任务);
- 下半部用来延迟处理上半部未完成的工作,以内核线程方式运行。
以网卡接受数据包为例
- 上半部把网卡数据读到内存中,然后更新硬件寄存器的状态,再发送一个软中断信号。
- 下半部被软中断信号唤醒,会从内存中找网络数据,按照网络协议栈,对数据进行逐层解析处理,直到把它送给应用程序。
查看软中断和内核线程
//提供了软中断的运行情况
$ /proc/softirqs
//提供了硬中断的运行情况
$ /proc/interrupts
//查看软中断对应的内核线程,ksoftirqd/CPU 编号
$ ps aux | grep softirq
root 7 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/0]
问题排查
使用watch命令数值变化
$ watch -d cat /proc/softirqs
网络收发软中断排查命令
$ sar -n DEV 1
//抓包命令
//-i eth0 只抓取 eth0 网卡,-n 不解析协议名和主机名
$ tcpdump -i eth0 -n tcp port 80
15:11:32.678966 IP 192.168.0.2.18238 > 192.168.0.30.80: Flags [S], seq 458303614, win 512, length 0