7)软中断与硬中断
假设现在一家公司就有一名客服人员,这个客服人员就有一台座机,这种情况下用户碰到问题只能打电话给这个客服人员,如果有多个用户同时打入只能凭运气,先打通电话的人得到回答,其他人只能依次等待。显然这种处理机制是非常低效的,小公司可能还可以,大一点的公司就不行了。于是现在共有4-5位客服人员,建立总分机架构,1位负责总机(也可以交给语音提示来操作),负责把问题分给4个分机,让4个分机人员来处理具体的问题,这样一来效率就明显提高了。如果客户来电,总机负责人接电话分给分机人员(或通过语音提示用户拨打分机号)叫做硬中断,而分机负责人处理具体问题叫做软中断。Linux的CPU正是采用硬中断与软中断结合的方式来处理问题的。比如现在网卡告诉CPU,有一批数据要从网络中过来,希望系统做好接收准备,CPU手头的工作被打断(中断),将网络上的数据存储在寄存器中,然后呼起一个进程来处理后续操作,就回头处理刚才中断之前的工作了。被呼起的进程可以在后台“慢慢地”地把寄存器中的数据按照规定格式写入数据库中。这里CPU处理的过程就为硬中断过程,而进程把数据写入数据库中过程为软中断过程。具体如图3-19所示。
图3-19 软中断与硬中断
硬中断可以用命令cat /proc/interrupts来查看,而软中断可以用cat /proc/softirqs来查看。由于硬中断比软中断过程短得多,所以作为性能监控往往需要监控软中断。
#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
其中。
•TIMER。
定时产生的软中断。
•NET_RX。
网络接收产生的软中断。
•NET_TX。
网络发送产生的软中断。
•SCHED。
内核调度产生的软中断。
•RCU。
RCU产生的软中断。
扩展阅读:RCU [32]RCU(Read-Copy Update),顾名思义就是读/拷贝/修改。对于被RCU保护的共享数据结构,不需要获得任何锁就可以访问它,但写者在访问它时首先拷贝一个副本,然后对副本进行修改,最后使用一个回调(callback)机制在适当的时机把指向原来数据的指针重新指向新的被修改的数据。这个时机就是所有引用该数据的CPU都退出对共享数据的操作 |
另外也经常使用ps aux | grep softirq命令来查看产生中断进程。
#ps aux | grep softirq root 7 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/0] root 16 0.0 0.0 0 0 ? S Oct10 0:01 [ksoftirqd/1]
注意:有[]为内核进程,可见软中断进程属于内核进程。
在top命令中也可以看到软中断进程。
#top top - 10:50:58 up 1 days, 22:10, 1 user, load average: 0.00, 0.00, 0.00 Tasks: 122 total, 1 running, 71 sleeping, 0 stopped, 0 zombie %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni, 96.7 id, 0.0 wa, 0.0 hi, 3.3 si, 0.0 st %Cpu1 : 0.0 us, 0.0 sy, 0.0 ni, 95.6 id, 0.0 wa, 0.0 hi, 4.4 si, 0.0 st ... PIDUSER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7 root 20 0 0 0 0 S 0.3 0.0 0:01.64 ksoftirqd/0 16 root 20 0 0 0 0 S 0.3 0.0 0:01.97 ksoftirqd/1 2663root 20 0 923480 28292 13996S 0.3 0.3 4:58.66 docker-containe 3699root 20 0 0 0 0 I 0.3 0.0 0:00.13 kworker/u4:0 3708root 20 0 44572 4176 3512 R 0.3 0.1 0:00.07 top 1root 20 0 225384 9136 6724 S 0.0 0.1 0:23.25 systemd 2root 20 0 0 0 0 S 0.0 0.0 0:00.03 kthreadd
除了可以使用cat /proc/softirqs查看当前软中断状态,在实际工作中也常常使用watch -d cat /proc/softirqs来动态显示实时软中断状态。
案例3-12:小包问题
#watch -d cat /proc/softirqs CPU0 CPU1 HI: 0 0 TIMER: 1083906 2368646 NET_TX: 53 9 NET_RX: 1550643 1916776 BLOCK: 0 0 IRQ_POLL:0 0 TASKLET: 333637 3930 SCHED: 963675 2293171 HRTIMER: 0 0 RCU: 1542111 1590625
上面结果中可以看出,网络发送产生了大量软中断。然后通过sar -n DEV 1命令来进一步分析。
#sar -n DEV 1 15:03:46 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil 15:03:47eth0 35645.00 6304.00 857.43 358.11 0.00 0.00 0.00 0.01 15:03:47docker0 6302.00 12604.00 270.79 664.66 0.00 0.00 0.00 0.00 15:03:47 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 15:03:47 veth9f6bbcd6302.00 12604.00 356.95 664.66 0.00 0.00 0.00 0.05
在这里。
•15:03:46。
表示报告的时间。
•IFACE。
表示网卡名。
•rxpck/s和txpck/s。
分别表示每秒接收、发送的网络帧数,也就是PPS。
•rxkB/s和txkB/s
分别表示每秒接收、发送的千字节数,也就是BPS。
在上面结果中,857(txpck/s)×1024/35645(rxpck/s)= 24字节,说明平均每个网络帧只有24字节,这显然是很小的网络帧,也就是通常所说的小包问题。确定是小包是问题后,就可以使用类似tcpdump工具进行进一步排查了。
8)CPU使用率
•CPU使用率=1-CPU空闲时间/CPU总时间。
•平均CPU使用率=1- (CPU空闲时间New- CPU空闲时间Old)/ (CPU总时间New- CPU总时间Old)。
top命令显示了系统总体的CPU和内存使用情况,以及各个进程的资源使用情况。而ps命令则只显示了每个进程的资源使用情况。
9)CPU节拍率
CPU节拍率指每秒钟CPU切换的次数,单位为HZ。一般为:100HZ、250HZ、1000HZ,如果CPU节拍率为250HZ,表示:每秒钟触发250次切换,即每次切换持续1/250s。CPU节拍率可以通过grep 'CONFIG_HZ='/boot/config-$(uname -r)命令得之。
#grep 'CONFIG_HZ=' /boot/config-$(uname -r) CONFIG_HZ=250
如图3-20所示,当前Memory中有“0”“1”“2”“3”“4”5个请求等待CPU处理。在当前时间段内CPU处理第“2” 号请求,过了1/250s(假设CPU节拍率为250),处理第“3”号请求,然后依次循环处理“4”“0”“1”…号请求。
图3-20 CPU节拍率
10)上下文切换
CPU依次处理上述任务的调度方法是切换。切换分为“进程切换”“线程切换”和“中断切换”。中断切换即在本节“软中断与硬中断”中提及的,当系统中有非常重要的请求来临,CPU停止手头工作,触发硬中断。“进程切换”和“线程切换”,在切换前都要调取上次保存的信息,在切换后都要保存当前的信息。“进程切换”和“线程切换”合在一起叫做上下文切换(context switches)。图3-21为当前仅有2个任务等待CPU处理下的进程下文切换。
图3-21 进程上下文切换
由此可见上下文切换的优点在于,每个进(线)程具有同等的CPU处理权利,缺点是进(线)程的保存和载入消耗资源。由于线程信息比进程信息要少,所以线程上下文切换优于进程上下文切换。等待的进(线)程,位于CPU的最外层Ring3,而当前正在处理的进(线)程位于CPU内核,即Ring0,如图3-22所示。
图3-22 等待CPU处理的进程和正在CPU处理的进程所处CPU位置
可以通过命令vmstat interval count来查看CPU的中断数和进线程上下文切换数。在这里interval为多长描述输出一次,count为总共输出的次数。比如:“vmstat5 3”表示每5s输出一次,总共输出3次。
#vmstat 1 1 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 1000 0
这里的输出含义见表3-6所示。
表3-6 vmstat命令输出详解
总标识 |
标识 |
意义 |
process |
r |
展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU个数,就会出现CPU瓶颈 |
b |
每秒VMM等待队列的核心线程平均数 |
|
system |
in |
在某一段时间间隔中观察到的每秒设备中断数 |
cs |
在某一段时间间隔中观察到的每秒上下文切换数 |
|
CPU |
us |
用户方式下花费的百分比 |
sy |
系统方式下执行一个进程花费的百分比 |
|
id |
没有使用本地磁盘I/O时CPU空闲或等待时间百分比 |
|
wa |
等待I/O CPU时间百分比 |
在System中cs就表述在某一段时间间隔内每秒上下文切换的个数。上下文切换又分为自愿上下文切换(voluntary context switches)和非自愿上下文切换(non voluntary context switches)两种。自愿上下文切换是指到了切换时间点,进(线)程由于所需的资源不足,比如没有获得进(线)程处理所需的数据而资源CPU让出去,去处理其他进(线)程;而非自愿上下文切换是指指到了切换时间点,没有数据资源不足的情形发生,此进(线)程不得不把CPU资源让出来去处理其他正在等待的进(线)程。所以当自愿上下文切换比较多,说明I/O或者内存存在瓶颈;而非自愿上下文切换比较多,说明目前有很多进(线)程需要CPU处理。可以通过命令pidstat(需要安装sysstat插件)查看自愿上下文切换和非自愿上下文切换。
#每隔 5 秒输出 1 组数据 #pidstat -w 5 Linux 4.15.0 (ubuntu) 09/23/18 _x86_64_ (2 CPU) 08:18:26 UID PID cswch/snvcswch/s Command 08:18:31 0 1 0.20 0.00 systemd 08:18:31 0 8 5.40 0.00 rcu_sched ...
这里的cswch/s和nvcswch/s就表示每秒自愿上下文切换和非自愿上下文切换个数。
11)perf top和perf record命令
perf top命令可以显示占用 CPU 时钟最多的函数或者指令,因此可以用来查找热点函数。如图3-23所示。
图3-23 perf top
perf top 虽然实时展示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续进行分析。
perf record 则提供了保存数据的功能,保存后的数据,需要用 perf report 解析展示。
注意:并不是所有的函数或指令都可以用perf top或perf record获得的。
12)短时进程
对于一些仅存在几毫秒的进程,当数量很大的时候也会给CPU带来很大的负载,而这些进程基本上用top或ps命令很难被获取到,这个时候就需要使用execsnoop命令了。这个命令工具可以通过https://github.com/brendangregg/perf-tools/blob/master/execsnoo获得。
13)显示10个消耗CPU最多的进程
可以通过ps aux|sort -rnk +3|head -10查看10个消耗CPU最多的进程。
#ps aux|sort -rnk +3|head -10 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 99 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_20] root 98 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_19] root 97 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_18] root 96 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_17] root 95 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_16] root 94 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_15] root 93 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_14] root 92 0.0 0.0 0 0? S 08:18 0:00 [scsi_eh_13] root 91 0.0 0.0 0 0? S 08:18
14)在多CPU的系统里,查看所有CPU的信息
可以使用mpstat查看多CPU的系统里中的信息。
#mpstat Linux 4.15.0-46-generic(ubuntu) 10/30/2019 _x86_64_(4 CPU) 02:59:04 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 02:59:04 AM all 15.29 4.91 17.24 2.76 0.00 1.08 0.00 0.00 0.00 58.71
15)小结
本节所涉及的概念有CPU负载、CPU使用率、不可中断的睡眠态进程、僵尸进程、CPU状态转换、软中断与硬中断、CPU节拍率和上下文切换。涉及到的命令有uptime、/proc/cpuinfo、top、dstat、pstree、/proc/softirqs、ps aux | grep softirq、watch、sar -n DEV 1、grep 'CONFIG_HZ=' /boot/config-$(uname -r)、vmstat、pidstat、perf top、perf record、execsnoop、ps aux|sort -rnk +3|head -10 和 mpstat。
—————————————————————————————————
软件安全测试
https://study.163.com/course/courseMain.htm?courseId=1209779852&share=2&shareId=480000002205486
接口自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209794815&share=2&shareId=480000002205486
DevOps 和Jenkins之DevOps
https://study.163.com/course/courseMain.htm?courseId=1209817844&share=2&shareId=480000002205486
DevOps与Jenkins 2.0之Jenkins
https://study.163.com/course/courseMain.htm?courseId=1209819843&share=2&shareId=480000002205486
Selenium自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209835807&share=2&shareId=480000002205486
性能测试第1季:性能测试基础知识
https://study.163.com/course/courseMain.htm?courseId=1209852815&share=2&shareId=480000002205486
性能测试第2季:LoadRunner12使用
https://study.163.com/course/courseMain.htm?courseId=1209980013&share=2&shareId=480000002205486
性能测试第3季:JMeter工具使用
https://study.163.com/course/courseMain.htm?courseId=1209903814&share=2&shareId=480000002205486
性能测试第4季:监控与调优
https://study.163.com/course/courseMain.htm?courseId=1209959801&share=2&shareId=480000002205486
Django入门
https://study.163.com/course/courseMain.htm?courseId=1210020806&share=2&shareId=480000002205486
啄木鸟顾老师漫谈软件测试
https://study.163.com/course/courseMain.htm?courseId=1209958326&share=2&shareId=480000002205486