最近,某团外卖被爆出大数据杀熟,所谓的大数据杀熟指的是平台利用户的数据,分析你是否是钱多的人,或者是否是不纠结价格的人,如果是,那么你买同样的物品会比普通用户贵一点,一般这种没有特地去对比价格是很难发现的,所以平台就利用了这点额外赚一些钱。说来很可笑,我们作为平台的资深用户,竟然被平台背后偷偷捞一笔。
不过,大数据杀熟早已是屡见不鲜的事情了,事实上,几乎所有大平台都存在这种现象,没办法,这就是真实的互联网。

刹车,大数据杀熟的话题就说到这了,我们还是回归到今日的技术主题:什么是软中断?。

01
中断是什么?
先来看看什么是中断?在计算机中,中断是系统用来响应硬件设备请求的一种机制,操作系统收到硬件的中断请求,会打断正在执行的进程,然后调用内核中的中断处理程序来响应请求。

这样的解释可能过于学术了,容易云里雾里,我就举个生活中取外卖的例子。

小林中午搬完砖,肚子饿了,点了份白切鸡外卖,这次我带闪了,没有被某团大数据大熟。虽然平台上会显示配送进度,但是我也不能一直傻傻地盯着呀,时间很宝贵,当然得去干别的事情,等外卖到了配送员会通过「电话」通知我,电话响了,我就会停下手中地事情,去拿外卖。

这里的打电话,其实就是对应计算机里的中断,没接到电话的时候,我可以做其他的事情,只有接到了电话,也就是发生中断,我才会停下当前的事情,去进行另一个事情,也就是拿外卖。

从这个例子,我们可以知道,中断是一种异步的事件处理机制,可以提高系统的并发处理能力。

操作系统收到了中断请求,会打断其他进程的运行,所以中断请求的响应程序,也就是中断处理程序,要尽可能快的执行完,这样可以减少对正常进程运行调度地影响。

而且,中断处理程序在响应中断时,可能还会「临时关闭中断」,这意味着,如果当前中断处理程序没有执行完之前,系统中其他的中断请求都无法被响应,也就说中断有可能会丢失,所以中断处理程序要短且快。

还是回到外卖的例子,小林到了晚上又点起了外卖,这次为了犒劳自己,共点了两份外卖,一份小龙虾和一份奶茶,并且是由不同地配送员来配送,那么问题来了,当第一份外卖送到时,配送员给我打了长长的电话,说了一些杂七杂八的事情,比如给个好评等等,但如果这时另一位配送员也想给我打电话。

很明显,这时第二位配送员因为我在通话中(相当于关闭了中断响应),自然就无法打通我的电话,他可能尝试了几次后就走掉了(相当于丢失了一次中断)。

02
什么是软中断?
前面我们也提到了,中断请求的处理程序应该要短且快,这样才能减少对正常进程运行调度地影响,而且中断处理程序可能会暂时关闭中断,这时如果中断处理程序执行时间过长,可能在还未执行完中断处理程序前,会丢失当前其他设备的中断请求。

那 Linux 系统为了解决中断处理程序执行过长和中断丢失的问题,将中断过程分成了两个阶段,分别是「上半部和下半部分」。

上半部用来快速处理中断,一般会暂时关闭中断请求,主要负责处理跟硬件紧密相关或者时间敏感的事情。
下半部用来延迟处理上半部未完成的工作,一般以「内核线程」的方式运行。
前面的外卖例子,由于第一个配送员长时间跟我通话,则导致第二位配送员无法拨通我的电话,其实当我接到第一位配送员的电话,可以告诉配送员说我现在下楼,剩下的事情,等我们见面再说(上半部),然后就可以挂断电话,到楼下后,在拿外卖,以及跟配送员说其他的事情(下半部)。

这样,第一位配送员就不会占用我手机太多时间,当第二位配送员正好过来时,会有很大几率拨通我的电话。

再举一个计算机中的例子,常见的网卡接收网络包的例子。

网卡收到网络包后,会通过硬件中断通知内核有新的数据到了,于是内核就会调用对应的中断处理程序来响应该事件,这个事件的处理也是会分成上半部和下半部。

上部分要做到快速处理,所以只要把网卡的数据读到内存中,然后更新一下硬件寄存器的状态,比如把状态更新为表示数据已经读到内存中的状态值。

接着,内核会触发一个软中断,把一些处理比较耗时且复杂的事情,交给「软中断处理程序」去做,也就是中断的下半部,其主要是需要从内存中找到网络数据,再按照网络协议栈,对网络数据进行逐层解析和处理,最后把数据送给应用程序。

所以,中断处理程序的上部分和下半部可以理解为:

上半部直接处理硬件请求,也就是硬中断,主要是负责耗时短的工作,特点是快速执行;
下半部是由内核触发,也就说软中断,主要是负责上半部未完成的工作,通常都是耗时比较长的事情,特点是延迟执行;
还有一个区别,硬中断(上半部)是会打断 CPU 正在执行的任务,然后立即执行中断处理程序,而软中断(下半部)是以内核线程的方式执行,并且每一个 CPU 都对应一个软中断内核线程,名字通常为「ksoftirqd/CPU 编号」,比如 0 号 CPU 对应的软中断内核线程的名字是 ksoftirqd/0

不过,软中断不只是包括硬件设备中断处理程序的下半部,一些内核自定义事件也属于软中断,比如内核调度等、RCU 锁(内核里常用的一种锁)等。

03
系统里有哪些软中断?
在 Linux 系统里,我们可以通过查看 /proc/softirqs 的 内容来知晓「软中断」的运行情况,以及 /proc/interrupts 的 内容来知晓「硬中断」的运行情况。

接下来,就来简单的解析下 /proc/softirqs 文件的内容,在我服务器上查看到的文件内容如下:

你可以看到,每一个 CPU 都有自己对应的不同类型软中断的累计运行次数,有 3 点需要注意下。

第一点,要注意第一列的内容,它是代表着软中断的类型,在我的系统里,软中断包括了 10 个类型,分别对应不同的工作类型,比如 NET_RX 表示网络接收中断,NET_TX 表示网络发送中断、TIMER 表示定时中断、RCU 表示 RCU 锁中断、SCHED 表示内核调度中断。

第二点,要注意同一种类型的软中断在不同 CPU 的分布情况,正常情况下,同一种中断在不同 CPU 上的累计次数相差不多,比如我的系统里,NET_RX 在 CPU0 、CPU1、CPU2、CPU3 上的中断次数基本是同一个数量级,相差不多。

第三点,这些数值是系统运行以来的累计中断次数,数值的大小没什么参考意义,但是系统的中断次数的变化速率才是我们要关注的,我们可以使用 watch -d cat /proc/softirqs 命令查看中断次数的变化速率。

前面提到过,软中断是以内核线程的方式执行的,我们可以用 ps 命令可以查看到,下面这个就是在我的服务器上查到软中断内核线程的结果:

可以发现,内核线程的名字外面都有有中括号,这说明 ps 无法获取它们的命令行参数,所以一般来说,名字在中括号里到,都可以认为是内核线程。

而且,你可以看到有 4 个 ksoftirqd 内核线程,这是因为我这台服务器的 CPU 是 4 核心的,每个 CPU 核心都对应着一个内核线程。

04
如何定位软中断 CPU 使用率过高的问题?
要想知道当前的系统的软中断情况,我们可以使用 top 命令查看,下面是一台服务器上的 top 的数据:

上图中的黄色部分 si,就是 CPU 在软中断上的使用率,而且可以发现,每个 CPU 使用率都不高,两个 CPU 的使用率虽然只有 3% 和 4% 左右,但是都是用在软中断上了。

另外,也可以看到 CPU 使用率最高的进程也是软中断 ksoftirqd,因此可以认为此时系统的开销主要来源于软中断。

如果要知道是哪种软中断类型导致的,我们可以使用 watch -d cat /proc/softirqs 命令查看每个软中断类型的中断次数的变化速率。

一般对于网络 I/O 比较高的 Web 服务器,NET_RX 网络接收中断的变化速率相比其他中断类型快很多。

如果发现 NET_RX 网络接收中断次数的变化速率过快,接下里就可以使用 sar -n DEV 查看网卡的网络包接收速率情况,然后分析是哪个网卡有大量的网络包进来。

接着,在通过 tcpdump 抓包,分析这些包的来源,如果是非法的地址,可以考虑加防火墙,如果是正常流量,则要考虑硬件升级等。

05
总结
为了避免由于中断处理程序执行时间过长,而影响正常进程的调度,Linux 将中断处理程序分为上半部和下半部:

上半部,对应硬中断,由硬件触发中断,用来快速处理中断;
下半部,对应软中断,由内核触发中断,用来异步处理上半部未完成的工作;
Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,可以通过查看 /proc/softirqs 来观察软中断的累计中断次数情况,如果要实时查看中断次数的变化率,可以使用 watch -d cat /proc/softirqs 命令。

每一个 CPU 都有各自的软中断内核线程,我们还可以用 ps 命令来查看内核线程,一般名字在中括号里面到,都认为是内核线程。

如果在 top 命令发现,CPU 在软中断上的使用率比较高,而且 CPU 使用率最高的进程也是软中断 ksoftirqd 的时候,这种一般可以认为系统的开销被软中断占据了。

这时我们就可以分析是哪种软中断类型导致的,一般来说都是因为网络接收软中断导致的,如果是的话,可以用 sar 命令查看是哪个网卡的有大量的网络包接收,再用 tcpdump 抓网络包,做进一步分析该网络包的源头是不是非法地址,如果是就需要考虑防火墙增加规则,如果不是,则考虑硬件升级等。

点个外卖搞定「软中断」相关推荐

  1. 点个外卖,我把「软中断」搞懂了

    最近,某团外卖被爆出大数据杀熟,所谓的大数据杀熟指的是平台利用户的数据,分析你是否是钱多的人,或者是否是不纠结价格的人,如果是,那么你买同样的物品会比普通用户贵一点,一般这种没有特地去对比价格是很难发 ...

  2. 我又换了一个新姿势,三秒搞定「搬乐」Ad!再也不用撸代码啦!

    温馨提示:文末有送书福利 前言 为了帮助更多人,更多非程序员也能上手小游戏,晓衡之前提供了: GameNavigator:小游戏互跳导航组件 RewardedVideoAd:激励视频组件 Creato ...

  3. 一口气搞懂「文件系统」,就靠这 25 张图了

    前言 不多 BB,直接上「硬菜」. 正文 文件系统的基本组成 文件系统是操作系统中负责管理持久数据的子系统,说简单点,就是负责把用户的文件存到磁盘硬件中,因为即使计算机断电了,磁盘里的数据并不会丢失, ...

  4. 避開創業者常犯的錯誤,5分鐘帶你搞懂「使命」「願景」和「戰略」的差異

    作者:顧遠/周賢 這幾天,Aha創業加速營的小伙伴們,圍繞著一個「新的」老話題:「到底什麼是使命和願景」而爭論不休.說它是老話題,因為社會領域的每個機構對此都能琅琅上口:無論是尋找新的資助方還是參加任 ...

  5. 你搞清楚「NULL」、「0」、「'0'」、「0」「\0」了吗?

    我们先讨论NULL,平时使用指针的时候,会经常遇见这个家伙,这个家伙的值是是这样定义的 #define NULL 0 或者 #define NULL (void *)0 我们看一下下面这段代码 #in ...

  6. 一篇文章帮你搞懂「估值」

    微信公众号:超漫时光 关注可了解更多的基金知识及投资技巧.问题或建议,请公众号留言; 如果本篇文章对你有帮助,欢迎点击在看 文章目录 前言 估值的本质 常见的估值方法 市盈率(PE) 盈利收益率(EP ...

  7. 点个外卖时间,我把「软中断」搞懂了

    作者 | 小林coding  责编 | 张文 头图 | CSDN 下载自视觉中国 来源 | 小林coding(ID:CodingLin) 最近,某团外卖被爆出大数据杀熟.所谓的大数据杀熟指的是平台利用 ...

  8. 斯坦福统计学习理论笔记:Percy Liang带你搞定「贼难」的理论基础

    选自 GitHub 机器之心整理 参与:刘晓坤.思源 CS229T/STAT231 是由斯坦福大学开设的统计学习理论课程,着重于对机器学习算法统计特性的理论理解,涉及机器学习算法何时起作用和原因.如何 ...

  9. 一口气搞懂「链表」,就靠这20+张图了

    顺序存储和链式存储 数组-顺序存储 数组作为一个顺序储存方式的数据结构,可是有大作为的,它的灵活使用为我们的程序设计带来了大量的便利: 但是,但是,数组最大的缺点就是我们的插入和删除时需要移动大量的元 ...

最新文章

  1. java代码如何避免死锁,Java可重入锁如何避免死锁
  2. IOS8如何获取当前UIViewController
  3. WEB前端面试题汇总整理01
  4. 计算机桌面打标签,在电脑桌面上添加便签的方法步骤详解(2)
  5. c++的输入流基础知识
  6. Cesium 加载天地图
  7. 练手级计算机,快来打怪
  8. Hadoop2.7.3完全分布式集群搭建(三节点)
  9. DbUtils jar包下载
  10. MatplotlibTutorial——Matplotlib的基本使用【Jupiter Notebook代码】
  11. 【OBS】OBS Studio 的安装、参数设置和录屏、摄像头使用教程
  12. ES 检索 word、pdf 文档插件 ingest attachment 的管道配置和文档结构映射
  13. ASP.NET 2.0收集
  14. UNIX经典命令详解
  15. python 换页符_Python用什么方法可以将换行符分割成多行?
  16. 谷歌SEO优化入门:Google SEO优化方法(2022最新)
  17. 新闻联播变脸报道“嫦娥发射”才更酷
  18. 《模仿游戏》没有告诉你的图灵真相
  19. Response重定向
  20. 商品模块数据库表解析(一)

热门文章

  1. C语言 数据结构 二叉树实现、二叉树的三种递归遍历
  2. linux系列之:告诉他,他根本不懂kill
  3. Libra教程之:Transaction的生命周期
  4. ERC20 Short Address Attack
  5. ES更新嵌套数组(使用Java API)
  6. flink从0到第一个应用成功运行遇到的所有问题和解决方法
  7. 容器源码解析之LinkedHashSet(六)
  8. Leecode 1218. 最长定差子序列——Leecode每日一题系列
  9. python遍历excel_python遍历文件读取并写结果到excel
  10. OpenStack的部署T版(九)——控制台部署