Linux系统上的中断小结
Contents
一什么是中断
操作系统为了快速响应并处理硬件的请求,不得不中断当前正在执行的任务,转而优先去处理硬件的请求。比如,中断当前执行的任务(浏览网页),去处理打印机的打印请求。
二为什么要有中断
生活中点外卖的场景,你点完外卖该干嘛干嘛,配送员到了call你,你停下手中的工作,去取外卖。这个过程中,配送员给你打电话,你停下手中工作来响应取外卖,这其实就是一个中断。否则的话,你点完外卖,需要在门口一直候着,其它啥工作也不做,这种方式显然太低效不可取了。从某种意义上理解,中断是一种异步处理机制,提升了系统的并发处理能力。
三中断的特征和分类
1中断的特征
由于系统是中断当前正在执行的程序,转而去响应并处理中断程序的执行。那么就要求,中断处理程序要在尽可能短的时间内执行完成。
2为什么要分类
假如你定了2份儿外卖,由两个配送员配送,第一个到了,他call你,跟你沟通关于发票等相关事宜,持续几分钟时间。期间,第二个配送员也到了,此时他是无法call你的(智能电话可以切换接听新进电话不在讨论之中)。这不就麻烦了嘛,你一直处于占线状态,无法处理第2份外卖送达的请求。
为了解决这种问题,于是,你接到第一个电话就说,我知道外卖到了,马上来取,发票的事情,咱见面再谈。等第二个外卖员call你时,你依然可以正常响应。
于是,中断也是类似的,对于那些需要紧急马上短时间内可以处理并响应的事件,称为硬中断。它在中断禁止模式下运行,处理跟硬件紧密相关或事件敏感的工作。
那些可以异步的处理的事件,完成硬中断并没有全部完成的工作,就称为软中断。
我知道外卖到了(硬中断),发票的事情(软中断)咱见面再聊。
3软中断:
查看方式:cat /proc/softirqs
4硬中断:
查看方式:cat /proc/interrupts
硬中断,通常执行快速,会打断CPU当前正在执行的任务,让CPU快速响应中断处理程序发起的请求;
软中断,通常是延迟执行,以内核线程的方式来执行,并且每个CPU都有一个软中断的内核线程,“ksoftirqd/cpu编号”。ps -ef|grep soft可以查看到。软中断包括网络收发、定时、调度、Read-Copy Update 锁等各种类型。
[root@ppasdev ~]# ps -ef|grep soft root 4 2 0 2018 ? 00:26:59 [ksoftirqd/0] root 9 2 0 2018 ? 00:21:04 [ksoftirqd/1] root 13 2 0 2018 ? 00:15:14 [ksoftirqd/2] root 17 2 0 2018 ? 00:13:26 [ksoftirqd/3] root 21 2 0 2018 ? 00:14:25 [ksoftirqd/4] root 25 2 0 2018 ? 00:09:39 [ksoftirqd/5] root 29 2 0 2018 ? 00:12:32 [ksoftirqd/6] root 33 2 0 2018 ? 00:07:54 [ksoftirqd/7] root 37 2 0 2018 ? 00:10:39 [ksoftirqd/8] root 41 2 0 2018 ? 00:06:48 [ksoftirqd/9] root 45 2 0 2018 ? 00:09:35 [ksoftirqd/10] root 49 2 0 2018 ? 00:06:19 [ksoftirqd/11] root 53 2 0 2018 ? 00:14:43 [ksoftirqd/12] root 57 2 0 2018 ? 00:07:18 [ksoftirqd/13] root 61 2 0 2018 ? 00:10:57 [ksoftirqd/14] root 65 2 0 2018 ? 00:05:56 [ksoftirqd/15] root 69 2 0 2018 ? 00:08:11 [ksoftirqd/16] root 73 2 0 2018 ? 00:05:19 [ksoftirqd/17] root 77 2 0 2018 ? 00:07:42 [ksoftirqd/18] root 81 2 0 2018 ? 00:05:04 [ksoftirqd/19] root 85 2 0 2018 ? 00:07:21 [ksoftirqd/20] root 89 2 0 2018 ? 00:04:58 [ksoftirqd/21] root 93 2 0 2018 ? 00:07:26 [ksoftirqd/22] root 97 2 0 2018 ? 00:04:41 [ksoftirqd/23] root 16182 9301 0 09:02 pts/2 00:00:00 grep soft You have new mail in /var/spool/mail/root [root@ppasdev ~]#
补充:ps或者是top看到的进程,进程名被[]包裹的,通常都是内核线程,无法查看其完整的执行命令名。
另外,我们也可以看到每个CPU对应的软中断的内核线程,其父进程都是2号进程,该进程是【kthreadd】。
[root@node-1 ~]# ps -ef|grep 2 root 1 0 0 3月29 ? 00:09:13 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 root 2 0 0 3月29 ? 00:00:01 [kthreadd] root 3 2 0 3月29 ? 00:07:23 [ksoftirqd/0] root 5 2 0 3月29 ? 00:00:00 [kworker/0:0H]
四网络收发数据场景的中断
网卡的请求处理,既包含硬中断也有软中断。数据包来了,立即通知CPU,这是硬中断,然后才是接收和处理数据包,这便是软中断。进而,可以解释,为什么大量的体积小的网络数据包,会带来性能问题呢,就是这个原因。频繁的中断打断CPU,然后开始执行接收处理数据包的工作。
简单理解,中断,其实是内核对进程的一种保护机制。
0 准备工作
两台Linux机器, 172.16.11.168作为server端,172.16.11.148作为客户端。都安装Docker、tcpdump、sysstat工具包。
1 server端启动NGINX容器
[root@master-node ~]# docker run -itd --name=nginx -p 80:80 nginx Unable to find image 'nginx:latest' locally Trying to pull repository docker.io/library/nginx ... latest: Pulling from docker.io/library/nginx 1fe172e4850f: Pull complete 35c195f487df: Pull complete 213b9b16f495: Pull complete a8172d9e19b9: Pull complete f5eee2cb2150: Pull complete 93e404ba8667: Pull complete Digest: sha256:859ab6768a6f26a79bc42b231664111317d095a4f04e4b6fe79ce37b3d199097 Status: Downloaded newer image for docker.io/nginx:latest 30bad7a0219ad738aa512c4c131ce45de6f22e8d7b80dd771e50e6452830e651 [root@master-node ~]
2 client通过hping3向server发送大量的小包网络数据
[root@node-1 ~]# curl http://172.16.11.168 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ... [root@node-1 ~]# hping3 -S -p 80 u100 172.16.11.168 ...
其中: -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80, -i u100表示每隔100微秒发送一个网络帧,具体可以通过hping3 -h来查看使用帮助。
3 查看服务端性能指标
[root@master-node ~]# top top - 08:51:28 up 626 days, 21:30, 3 users, load average: 0.55, 0.36, 0.31 Tasks: 218 total, 2 running, 214 sleeping, 0 stopped, 2 zombie %Cpu(s): 5.0 us, 2.3 sy, 0.0 ni, 71.7 id, 0.1 wa, 0.0 hi, 21.0 si, 0.0 st KiB Mem : 8175440 total, 225444 free, 5852896 used, 2097100 buff/cache KiB Swap: 0 total, 0 free, 0 used. 1473044 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2737 root 20 0 1190756 386880 29116 S 14.0 4.7 14901:25 kube-apiserver 14711 root 20 0 1991604 88336 19576 S 6.3 1.1 9937:31 kubelet 2132 root 20 0 10.697g 64292 12972 S 5.0 0.8 4907:48 etcd 8728 root 20 0 827324 67544 15348 S 3.7 0.8 1194:07 kube-controller 12929 root 20 0 1651168 63284 9616 S 3.0 0.8 3488:49 dockerd-current 23 root 20 0 0 0 0 S 2.7 0.0 70:42.55 ksoftirqd/3 3 root 20 0 0 0 0 R 1.3 0.0 8:38.06 ksoftirqd/0 13 root 20 0 0 0 0 S 1.3 0.0 8:29.64 ksoftirqd/1
此时,可以看到系统的软中断CPU使用率涨上来了,达到20%多,同时看到进程列表里有软中断进程(ksoftirqd/0、ksoftirqd/1、ksoftirqd/3)占有系统资源。
4 dstat查看系统性能指标
[root@master-node ~]# dstat You did not select any stats, using -cdngy by default. ----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 2 4 94 0 0 0|2865k 27k| 0 0 | 22B 22B| 409 1526 4 2 80 0 0 15| 0 30k|1408k 1734k| 0 0 | 22k 6120 4 1 81 0 0 14| 0 12k|1385k 1716k| 0 0 | 22k 5918 6 2 78 0 0 13| 0 28k|1371k 1688k| 0 0 | 22k 6217 2 1 83 0 0 14| 0 0 |1340k 1658k| 0 0 | 22k 6247 4 2 79 0 0 15| 0 82k|1409k 1735k| 0 0 | 23k 7273 9 4 69 0 0 17| 0 0 |1395k 1718k| 0 0 | 22k 8308 9 4 66 0 0 21| 0 91k|1376k 1693k| 0 0 | 20k 8564 9 1 69 0 0 20| 0 0 |1380k 1699k| 0 0 | 19k 5851 11 4 61 0 0 24| 32k 448k|1382k 1702k| 0 0 | 20k 9391 10 3 67 0 0 19| 0 52k|1405k 1733k| 0 0 | 20k 8145 4 1 78 0 0 16| 0 28k|1412k 1739k| 0 0 | 23k 7339 4 2 74 0 0 19| 0 46k|1357k 1681k| 0 0 | 21k 7587 3 1 81 0 0 14| 0 0 |1389k 1710k| 0 0 | 23k 6308 ^C[root@master-node ~]#
同样,此时看到系统软中断的CPU使用率维持17%左右,同时,可以看到网络的流入流出量比较大。
我们判断出系统的软中断占用了比较明显的CPU资源,那么到底是哪一类软中断占用了CPU资源呢?我们可以通过watch -d cat /proc/softirqs来观测软中断的变化,其中watch -d表示观测动态变化的部分,并且会高亮显示。
5 观测软中断变化率/proc/softirqs
Every 2.0s: cat /proc/softirqs Tue May 10 09:02:38 2022 CPU0 CPU1 CPU2 CPU3 HI: 0 0 0 0 TIMER: 2672518579 2647468403 2431745598 2558594737 NET_TX: 352 10833273 371 333 NET_RX: 515094643 446562848 759935086 435055629 BLOCK: 63459234 10831408 34464900 555490751 BLOCK_IOPOLL: 0 0 0 0 TASKLET: 797639 1134312 1504795 2253722 SCHED: 1560074575 1518308323 1388392141 1486880062 HRTIMER: 0 0 0 0 RCU: 1446535727 1445120992 1404463822 1436449926
这里,可以看到系统额NET_RX,网络收包的软中断变化最大。其它几个软中断指标变化不是特别明显。
6 sar -n DEV 1监控网络流量变化
[root@master-node ~]# sar -n DEV 1 09时11分26秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s 09时11分27秒 vethd3c10b0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 veth7222006 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 veth9134df2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 veth0212667 6375.00 12751.00 361.08 672.42 0.00 0.00 0.00 09时11分27秒 lo 122.00 122.00 22.10 22.10 0.00 0.00 0.00 09时11分27秒 virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 veth7fd5d21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 ens160 12765.00 6378.00 750.80 362.66 0.00 0.00 0.00 09时11分27秒 flannel.1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 09时11分27秒 docker0 6376.00 12751.00 273.97 672.42 0.00 0.00 0.00 平均时间: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s 平均时间: vethd3c10b0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: veth7222006 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: veth9134df2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: veth0212667 6355.20 12710.32 359.96 670.27 0.00 0.00 0.00 平均时间: lo 134.77 134.77 23.47 23.47 0.00 0.00 0.00 平均时间: virbr0-nic 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: virbr0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: veth7fd5d21 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: ens160 12741.69 6372.33 751.24 367.56 0.00 0.00 0.00 平均时间: flannel.1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 平均时间: docker0 6355.20 12710.33 273.07 670.27 0.00 0.00 0.00 [root@master-node ~]#
从上,可以看到ens160这块网卡接收数据包个数rxpck/s是12741个,发送数据包个数txpck/s是6372,接收数据包大小rxKB/s为751,发送数据包大小367KB/s。折算下来,平均每秒接收的每个数据包大小为751*1024/12741≈60 bytes。也就是我们常说的网络小包。
同时,看到另外两块网卡docker0和veth0212667的网络收发数据流量方向正好和ens160网卡设备相反,数据量大小基本保持一致。这其实是server端的物理网卡接收到网络流量之后,转发给Docker容器的网卡设备。
7 tcpdump网络抓包分析
[root@master-node ~]# tcpdump -i ens160 -n tcp port 80 ... 09:13:10.121181 IP 172.16.11.148.61312 > 172.16.11.168.http: Flags [R], seq 32336669, win 0, length 0 09:13:10.121218 IP 172.16.11.148.61316 > 172.16.11.168.http: Flags [S], seq 101696433, win 512, length 0 09:13:10.121230 IP 172.16.11.148.61314 > 172.16.11.168.http: Flags [R], seq 214645300, win 0, length 0 09:13:10.121329 IP 172.16.11.148.61315 > 172.16.11.168.http: Flags [R], seq 511517631, win 0, length 0 09:13:10.121332 IP 172.16.11.148.61313 > 172.16.11.168.http: Flags [R], seq 1262824714, win 0, length 0 09:13:10.121363 IP 172.16.11.148.61317 > 172.16.11.168.http: Flags [S], seq 1170847465, win 512, length 0 09:13:10.121415 IP 172.16.11.168.http > 172.16.11.148.61316: Flags [S.], seq 181639977, ack 101696434, win 29200, options [mss 1460], length 0 09:13:10.121450 IP 172.16.11.168.http > 172.16.11.148.61317: Flags [S.], seq 952647435, ack 1170847466, win 29200, options [mss 1460], length 0 09:13:10.121649 IP 172.16.11.148.61319 > 172.16.11.168.http: Flags [S], seq 793001380, win 512, length 0 09:13:10.121650 IP 172.16.11.148.61318 > 172.16.11.168.http: Flags [S], seq 49059466, win 512, length 0 09:13:10.121666 IP 172.16.11.148.61316 > 172.16.11.168.http: Flags [R], seq 101696434, win 0, length 0 09:13:10.121747 IP 172.16.11.168.http > 172.16.11.148.61318: Flags [S.], seq 940527943, ack 49059467, win 29200, options [mss 1460], length 0 09:13:10.121817 IP 172.16.11.168.http > 172.16.11.148.61319: Flags [S.], seq 2772151625, ack 793001381, win 29200, options [mss 1460], length 0^C 29465 packets captured 77060 packets received by filter 47427 packets dropped by kernel [root@master-node ~]#
从中,看到网络数据包的来源主要是172.16.11.148。
五小结
通过一个hping3的客户端模拟向服务器的NGINX持续发送小网络数据包,可以引起服务器端的软中断的CPU使用率上升。进一步分析的去看,是属于软中断中的网络接收数据的中断程序引起的。
如果案例中的软中断CPU不明显的话,可以把hping3发送数据的频率再进一步缩小。比如:hping3 -S -p 80 -i u10 172.16.11.168
软中断 CPU 使用率(softirq)升高是一种很常见的性能问题。虽然软中断的类型很多,但实际生产中,我们遇到的性能瓶颈大多是网络收发类型的软中断,特别是网络接收的软中断。
六参考
倪朋飞老师Linux性能优化实战,第10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?