今天聊的也是一个老生常谈的问题了:JDK Selector 的空轮询 bug。

今天来简单地扒一下,这玩意大概能追溯到 06 年,并且基于这个 BUG 我们再发散下,看看能给我们什么启发。

追溯

最近我不是一直在写 Netty 系列嘛,我想谈到什么 Netty ,但凡你在网上看过相关资料,那肯定会提到 JDK NIO 在 Linux 系统下空轮询的 bug,就是调用 Selector.select(timeout),即使没事件发生,也不会阻塞 timeout 时间,而是立马 return,这样的空轮询导致 CPU 100%。

产生这个 bug 大致的原因我讲下:连接突然中断,poll 和 epoll 会被 POLLHUP 或者 POLLERR 事件唤醒,于是 Selector 虽然被唤醒了,但是 JDK Selector 一看,没事件(JDK只定义了CONNECT、READ、WRITE、ACCEPT这几个事件)需要处理啊?

然后就又循环了....没事件要处理啊,然后就又循环了....没事件要处理啊,然后就又循环了....

如此往复,空轮询使得 CPU 100%。

这个 BUG 真算是个老黄历了,我查了查 JDK 的 bug 库,大致 13 年 3 月份之后就没提相关的 bug ,而且按照官方的说法这也和 Linux 版本有关,至今应该没这问题了?(我不确定)。

我们来回顾一下 bug 库的历史。

我查了下最早提到的 Selector(底层用的是 poll 或者 epoll) 在 Linux 不会阻塞的 BUG 是在 06 年 3 月 24 日。

可以看到,这 Resolved 的日期有点长,隔了一年,也就是 06 提的 07 年才说修复了,不过当天是给了个解决方案的:

解决方案简单粗暴,就是把抽风不阻塞的 Selector 删了,然后创建个新的,取而代之。(有时候简单粗暴的就是最好的)

我再往后找了找 Selector 的 bug ,发现 08 年还有 bug(不是说修复了吗?),并且处理的日期是 13 年!最终结果是无法修复,相关的是 JDK 6 版本。

同 13 年还有类似的 bug ,不过是在 JDK 7 版本上,最终 resolution 是不完整的修复!

从这个处理的时间和结果来看,我个人推断 JDK 对此 bug 的态度是消极的,认为这是 Linux 自身的 bug 导致的现象(同为程序员习惯性地甩)。

从 JDK-6670302 的评价就可以看出:

大致的意思就是:升级下 Linux 内核版本(2.4版本有这个问题)就好了,2.6 版本发布已经 4 年了,这个修复也没啥必要了,需求很小。

这其实可以理解。

站在 JDK 开发者的角度来看:我这代码在 windows 下运行得好好的,到你 Linux 就不行了?嗯?我的问题?Linux 为什么给我这样莫名其妙的事件?你中断唤醒了个什么玩意?

但是站 Linux 开发者角度来看就不一样了:嗯?甩锅给我?明明是你写代码没考虑到这种特殊情况,跟着跟我甩锅呢?

那站我们 Java 开发而言:你搁着跟我搁那呢?有 bug 还搁这甩,我管你 JDK 什么情况,你就得给我修!(我相信 JDK 开发者也是这样看的 Linux 开发者的)

哈哈哈,真不真实?

总之,我个人觉得这个 bug 之所以会被网上的文章拿出来反复鞭尸.

一是,因为 netty 通过曲线救国的方式,确实避免了那个时间段部署在 Linux 的应用直接用 Java Selector 产生的空轮询 bug,所以在当时谈到 Netty 就值得拿这个说事儿。

二是,天下文章一大抄嘛,懂的都懂。

对了,虽然我查 bug 库发现后面确实都没再有类似的bug,但是网上有文章说在 JDK8 还是重现了这个 bug!

链接:https://juejin.cn/post/6844903491505242119

啧啧,俗话说得好,靠人不如靠己,Netty 就是靠己来解决这个 bug,也就是上面提到的简单粗暴的解决办法!

Netty :空循环是吧,我数数你循环几次,只要到达一定次数,我就认为你产生 bug 了,于是我就重建一个 Selector,废弃以前那个已经抽风了的 Selector!这样我管你 JDK 还是 Linux 会不会处理,我这波就是稳坐钓鱼台!

这就是 Netty 的解决办法~所以也不能说是 Netty 修复了 JDK NIO 的 bug ,它只是曲线救国,变相避免了这个 bug 罢了。

这其实能给我们日常的开发提供一点思路,有时候求人不如求己,对于二方、三方的接口还是报以质疑的态度去看待,不要过度的相信他们,特别是三方的接口,一定要做好对方挂掉或者返回奇怪结果的准备。

我之前对接某大厂的接口,返回值就无声无息的变了,没有任何公告和通知,就是那种你认为不可能会变的值。比如一个返回城市名的接口,正常返回叫杭州市,它莫名其妙变了个杭州市(常用)。当然我只是举个例子哈,具体是啥不方便说。

还有之前对接过另一个大厂的接口,那时候他们的服务几乎属于要挂的情况,返回的贼慢,经常超时,这种我还是有经验的,起初就我设置了接口超时等待响应时间是 3s,而对方服务有问题,往往都超过了 3s,导致我们拉不到数据。

然后我向对方提了工单,对方竟然让我把超时等待时间调整到 10s,我听得都傻了,正常返回 100ms 的接口,让我设个 10s,这是让我跟着他们的服务一起挂是吗。

遇到这种情况可千万别听对方的,你得想到这就是在拖垮你的应用,你设置的超时等待的时间越久,线程被占用时间就的越长,那其他被的请求不就没线程去处理了嘛,然后请求就堆积了,最终你的应用就全部崩盘了。

也亏对方想得出来这种回复,遇到这种类似的情况,如果你个人拿捏不准,及时找你同事或者领导讨论下,别傻傻的听他的就改了。

你看看所谓的大厂的接口也都这样,总而言之,对待二方、三方接口,要多加个心眼,一定要做好判空、降级等等情况。

我发现有些新同学就很不喜欢判空,因为觉得多写一个 if 很丑陋,啧啧,年轻还是太年轻了,没遭受过毒打!

所以,你们遇到三方最恶心的场景是什么?拿到留言区给大家乐呵乐呵?

好了,今天就扯到这儿~

管你 JDK 还是 Linux,我 Netty 稳坐钓鱼台相关推荐

  1. 安防AI芯片“战国时代” 谁能稳坐钓鱼台?

    https://www.toutiao.com/a6646901372891431432/ 2019-01-16 09:32:05 [中国安防展览网 企业关注]AI应用不再是锦衣夜行,特别是在安防行业 ...

  2. Netty和JDK源码来看Netty的NIO和JDK的NIO有什么不同

    JDK底层提供了NIO实现,在Linux环境会调用内核epoll. 但是Netty通过JNI的方式提供了Native Socket Transport,为什么Netty要自己搞一套NIO呢? 这篇文章 ...

  3. c++ 开方_刷屏时尚圈!The Story Shoulder稳坐风尚C位的背后究竟有什么奇妙魔力?...

    不知道大家还记不记得白哥去年背的一款来自Alexander McQueen的The Story手袋:当时你白形容说:"它处处散发着麦昆式的Woman Power".这只采用了极简设 ...

  4. 2018年Github最受欢迎机器学习语言Python稳坐冠军,numpy、scipy是最受欢迎软件包...

    在 GitHub 2018 年的 Octoverse 报告中,机器学习和数据科学是 GitHub 上的热门话题.其中,tensorflow / tensorflow 是项目贡献最多的项目之一,pyto ...

  5. 中one_十月中大型SUV销量排行:途昂稳坐第一,理想ONE晋升亚军

    11月末12初,国内车市进入了传统的年底冲量环节,不知想购车的朋友有没有选到合适的车型?今天我为大家带来国内中大型SUV在10月份的销量排行,为大家购车提供参考.其中,大众和通用系的产品表现仍然非常显 ...

  6. 2019 编程语言终极排行榜:Java 稳坐榜首!

    原文:https://www.tiobe.com/tiobe-index/ 编译:程序猿(ID:imkuqin) TIOBE公布了12月份编程语言排行榜.相比上个月编程语言Top 5并没有太大的变化, ...

  7. 稳坐全球第一的小米手环,爆款背后的“护城河”是如何造就的?

    当一个中国的品牌产品,即便放置全球,其销量连续4年稳坐第一,是怎样一种存在? 看似夸张,但这个现象级的事例,真实的发生在智能可穿戴设备领域. 这就是小米手环给出的答案. 据国际权威第三方数据机构IDC ...

  8. 业绩不稳的永信至诚,能稳坐国内网络靶场的头把交椅吗?

    数据智能产业创新服务媒体 --聚焦数智 · 改变商业 在行业竞争激烈的背景下,作为IT安全服务细分市场--安全企业级培训服务的龙头,北京永信至诚科技有限公司(以下简称"永信至诚") ...

  9. 坐拥行业5成新增用户,每日优鲜稳坐生鲜电商头名

    [techweb]随着盒马.叮咚买菜.朴朴超市.美团买菜等玩家纷纷进军"线上菜市场"业务,生鲜电商再度成为今年的热门话题.近日,第三方数据咨询公司TrustData发布的<2 ...

最新文章

  1. 12月22日 find命令
  2. Exists and IN
  3. dubbo原理_dubbo实现原理介绍
  4. c#中的protected和internal
  5. Python之ffmpeg-python:ffmpeg-python库的简介、安装、使用方法之详细攻略
  6. 4月21日云栖精选夜读:【校园头条】第1期:找实习、找工作时,让你脱颖而出的秘籍...
  7. IntelliJ IDEA 如何创建一个普通的java项目,及创建java文件并运行
  8. java的字符_Java中的字符
  9. unity 源码_Unity-DataFlowGraph 读源码例子Tour笔记 14
  10. Mysql mysqld_safe启动与myslqd启动坑
  11. REST(三)Restlet实现REST
  12. HihoCoder 1384 Genius ACM
  13. Java5的倍数_关于java:将数字四舍五入到最接近的5的倍数
  14. npm ERR! nested aliases not supported 报错原因
  15. Surfacebook电池1充不上电解决办法亲测有效
  16. TensorFlow在win10上安装--精简教程
  17. revit建模中复合墙与叠层墙区别?Revit中怎么创建叠层墙?
  18. 这才是21 世纪的 API 文档该有的样子
  19. IC学习笔记20——VCS的使用(一)仿真事件队列
  20. hive、impala的客户端,cli、beeline、WebHCat

热门文章

  1. linux 内核 课程,Linux内核分析课程-全面剖析Linux内核技术 揭开Linux内核的面纱 Linux内核学习视频教 ......
  2. 2022年5月8日 解决手机连接电脑无法选择“传输文件”
  3. 防百度云加速html,百度云加速3.0轻松应对全球最大DDoS攻击
  4. WEB漏洞——SQL注入之简要SQL注入
  5. 如何使用开源合成器Natron入门
  6. excel countif_计算Excel数据COUNTIF COUNTA时出现问题
  7. 第三方备份软件调用RMAN的原理
  8. 洛谷:P1033 [NOIP2002 提高组] 自由落体 C++详解
  9. Google 桌面搜索的使用
  10. 分享一下自己用的SQLite数据库密码操作小工具(含源码)