系统优化-CPU-软中断以及软中断过多带来的危害

什么是软中断

因为响应硬件的事件优先级高于我们正在运行的进程,所以CPU为了响应硬件,需要中断正在运行的进程。这个中断就是我们今天要讨论的中断。

当cpu响应中断的时候回临时关闭中断,也就是说其他的中断都需要响应完现有的中断才行,这时候就会出现中断丢失或者中断延迟比较大的现象,那linux是如何解决的呢?

linux将中断变为上下俩部分

-上部分:主要处理响应和硬件相关的事件,它会关闭中断响应,特点是速度很快,处理完毕后会发送软中断信号,我们称他为硬中断;
-下部分:根据中断的类型处理具体的事件逻辑,它由内核线程负责,在Linux中,每个CPU都对应一个软中断内核线程,名字是ksoftirqd/【CPU编号】,处理硬中断中的数据然后发送给需要的用户线程,我们称他为软中断,特点是延迟执行。

软中断的类型

我们可以通过查看/proc/softirqs来看各cpu的中断情况,由于软中断是内核线程所以在top中我们看到的软中断进程是[ksoftirqd/0]这样的

1
2
3
4
5
6
7
8
9
10
11
12
$ 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

一般来讲每种软中断应该在各cpu上运行的次数差不多,但是TASKLET例外,它是最常用的软中断实现机制,每次运行一次就会推出,且只在调用它的cpu上运行。

软中断带来的CPU使用率够高的性能问题

工具准备

  • sar 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告历史统计数据。
  • hping3 是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙测试等。
  • tcpdump 是一个常用的网络抓包工具,常用来分析各种网络问题。

    测试的方案

  1. 我们准备一个nginx的容器
  2. 我们通过hping3来模拟对nginx的SYNC_FLOOD攻击。

    现象:系统的吞吐会降低,响应变慢,用top查看结果发现cpu占用不高,但是都用在软中断上,我们可以去查看软中断。

1
2
3
4
5
6
7
8
9
10
11
12
13
#watch可以查看变化并且-d可以看到变化的数据
$ 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

发现NET_RX变化很快,初步判断是网络引发用sar来看下玩过的情况

1
2
3
4
5
6
7
8

# -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 分别表示每秒接收、发送的网络帧数,也就是 PPS。
  • 第五、六列:rxkB/s 和 txkB/s 分别表示每秒接收、发送的千字节数,也就是 BPS。后面的其他参数基本接近 0,显然跟今天的问题没有直接关系,你可以先忽略掉。

eth0这个网卡接收远大于发送,查看报文的大小,664*1024/12607=54字节,这是一个小包。

我们用tcpdump抓包

1
2
3
4
5
# -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
...
  • 从 tcpdump 的输出中,你可以发现192.168.0.2.18238 > 192.168.0.30.80 ,表示网络帧从 192.168.0.2 的 18238 端口发送到 192.168.0.30 的 80 端口,也就是从运行 hping3 机器的 18238 端口发送网络帧,目的为 Nginx 所在机器的 80 端口。
  • Flags [S] 则表示这是一个 SYN 包。再加上前面用 sar 发现的, PPS 超过 12000 的现象,现在我们可以确认,这就是从 192.168.0.2 这个地址发送过来的 SYN FLOOD 攻击。