这篇文章上次修改于 899 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
中断处理程序响应中断时,会临时关闭中断。导致上一次中断处理完成之前不会响应别的中断,导致中断丢失。
Linux 将中断分成了上下两半部:
- 上半部直接处理硬件请求,为硬中断,特点是快速执行。
- 下半部由内核触发,为软中断,特点是延迟执行。
查看软中断和内核线程
/proc/softirqs 提供了软中断运行情况。
/proc/interrupts 提供了硬中断运行情况。
查看各种类型的软中断在不同 CPU 上的累积运行次数:
$ cat /proc/softirqs
CPU0
HI: 1
TIMER: 1026316871
NET_TX: 0 # 网络发送中断
NET_RX: 61775356 # 网络接收中断
BLOCK: 40798866
BLOCK_IOPOLL: 0
TASKLET: 16
SCHED: 0
HRTIMER: 0
RCU: 1131073805
Linux 中的软中断包括网络收发,定时,调度、RCU 锁等类型。
查看软中断线程:
$ ps aux | grep softirq
root 6 0.0 0.0 0 0 ? S 4月03 5:06 [ksoftirqd/0]
root 1435 0.0 0.0 112828 972 pts/0 D+ 16:23 0:00 grep --color=auto softirq
软中断是以内核线程方式运行的,每个 CPU 都对应一个软中断线程。
软中断CPU使用率升高怎么办?
当发现系统响应变慢时,需要用 top 查看下系统资源情况:
# top运行后按数字1切换到显示所有CPU
$ 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
...
PID USER 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
2663 root 20 0 923480 28292 13996 S 0.3 0.3 4:58.66 docker-containe
3699 root 20 0 0 0 0 I 0.3 0.0 0:00.13 kworker/u4:0
3708 root 20 0 44572 4176 3512 R 0.3 0.1 0:00.07 top
1 root 20 0 225384 9136 6724 S 0.0 0.1 0:23.25 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.03 kthreadd
...
会发现,CPU 使用率不高,负载不高。但是 CPU 的使用率主要在软中断,且进程中 CPU 利用率最高的是软中断进程。所以接下来查看下软中断:
$ 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:47 eth0 12607.00 6304.00 664.86 358.11 0.00 0.00 0.00 0.01
15:03:47 docker0 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 veth9f6bbcd 6302.00 12604.00 356.95 664.66 0.00 0.00 0.00 0.05
其中:
- 第一列:报告的时间
- 第二列:IFACE 表示网卡
- 第三、四列:rxpck/s,txpck/s 分别表示每秒发送、接收帧数。
- 第五、六列:txkB/s,txkB/s 分别表示每秒发送、接收字节数。
可见,eth0 的 rxpck/s 较大,而 rxkB/s 较小,平均每个网络帧只有 664*1024/12607 = 5456 字节,说明接收的包是小包,需要查看该包到底是什么。可通过 tcpdump 在 eth0 上抓包分析:
# -i eth0 只抓取eth0网卡,-n不解析协议名和主机名
# tcp port 80表示只抓取tcp协议并且端口号为80的网络帧
$ 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
...
Flags[S] 表示这是一个 SYN 包,可以确认,这是 192.168.0.2 发来的 SYN FLOOD 攻击,需将该 IP 禁掉。
参考
倪朋飞. Linux 性能优化实战.
没有评论