当前位置: 首页 > 科技观察

不管你的JDK还是Linux,我和Netty一起坐拥钓鱼台!

时间:2023-03-14 12:21:24 科技观察

你好,我是。今天讲的也是老生常谈的问题:JDKSelector的空轮询bug。今天我们就来简单的看一下。这个东西大概可以追溯到2006年,就基于这个BUG,我们摊开一下,看看能给我们带来什么启发。最近回头看,一直没在写Netty系列。我想谈谈Netty。如果你在网上看过相关资料,肯定会提到Linux系统下JDKNIO空轮询的bug,就是调用Selector.select(timeout),即使没有事件发生,也不会阻塞超时时间,但立即返回,这样的空轮询将导致100%CPU。这个bug的一般原因是:连接突然中断,poll和epoll会被POLLHUP或者POLLERR事件唤醒,所以Selector会被唤醒,但是JDKSelector没有事件(JDK只定义了CONNECT,READ,WRITE,ACCEPT这些事件)需要处理?然后又循环....没有要处理的事件,然后又循环...没有要处理的事件,然后又循环....如此来回,空轮询使CPU100%.这个BUG真是老历了。查了下JDK的bug库,2013年3月以后的相关bug我都没有提,按照官方说法,这也是和linux版本有关。到目前为止,应该没有这个问题。?(我不知道)。让我们看一下错误存储库的历史。我查了下最早提到linux中Selector(底层使用的poll或epoll)不堵BUG是2006年3月24日,可见Resolved的日期有点长。一年后修复,也就是2006年提到的2007年。不过那天给出了一个解决方案:解决方案简单粗暴,就是把不挡风的Selector删掉,新建一个一个来代替它。(有时候简单粗暴的才是最好的)后来找了Selector的bug,发现2008年的bug还是有的(不是修了吗?),处理的日期是13年!最后的结果是无法修复,相关的JDK6版本。2013年也有类似的bug,但是在JDK7版本上,最终的解决方案是修复不彻底!从处理时间和结果来看,我个人推断JDK对这个bug的态度是消极的,认为是Linux自身的bug造成的现象(同样是程序员习惯性的扔掉)。从JDK-6670302的评测可以看出:大致意思是:升级linux内核版本即可(2.4版本有这个问题),2.6版本已经发布4年了,不需要这个修复。很小。这其实是可以理解的。站在一个JDK开发者的角度:我的代码在windows下运行的很好,但是在你的linux下就不行了?唔?我的问题?为什么Linux会给我这样一个莫名其妙的事件?你打断了什么叫醒??但从Linux开发者的角度来看,就不一样了:嗯?给我责备?明明是你写代码的时候没有考虑到这种特殊情况,还怪我干嘛?从我们Java开发的角度来说:你怎么不给我?如果有错误,请不要管它。我不管你的JDK,你得给我修好!(相信JDK开发者也是这样看Linux开发者的)哈哈哈,不真实?总之,我个人认为之所以这个bug被网上的文章反复拿出来。第一,因为netty通过曲线救国,真正避免了那段时间在linux上部署的应用程序中,JavaSelector直接产生的空白。轮询bug,所以说Netty在当时还是很值得的。二是世界上抄袭的文章很多,懂的人都懂。对了,虽然查了bug库,发现以后没有类似的bug了,但是网上有文章说这个bug在JDK8中还是重现了!链接:https://juejin.cn/post/6844903491505242119啧啧,俗话说得好,靠别人不如靠自己。Netty靠自己解决这个bug,也就是上面说的简单粗暴的解决方法!Netty:空循环,对吧?我会统计你循环了多少次,只要达到一定的次数,我还以为你有bug,于是我重新建了一个Selector,把之前抽风的Selector给扔掉了!这样我就不管你的JDK或者Linux会不会处理了。我就坐在钓鱼台上!这是Netty的解决方案~所以不能说Netty修复了JDKNIO的bug,它只是曲线救国,变相避免了这个bug。这其实可以为我们的日常开发提供一些思路。有时候,求别人比求自己好。我们应该以怀疑的态度对待两方和三方接口。不要太相信他们,尤其是三方接口。做好对方挂断或返回奇怪结果的心理准备。之前连接过一个大厂的接口,返回值悄无声息的变化,没有任何的公告和通知,就是那种你认为不可能改变的值。比如一个返回城市名称的接口,正常情况下返回的是杭州市,但不知何故变成了杭州市(常用)。当然,我只是举个例子,具体是什么就不方便说了。我之前也连接过别的大厂的接口。当时他们的服务几乎处于挂掉的状态。返回很慢,经常超时。这种情况我还是有经验的。一开始我设置接口超时,等待响应时间。是3s,但是对方服务有问题,经常超过3s,导致我们无法拉取数据。然后我给对方提交工单,对方让我把超时等待时间调整为10s。我傻眼了,正常返回100ms的界面,让我设置一个10s,就是让我挂掉他们的服务呀。在这种情况下,不要听对方的。您必须认为这会拖累您的应用程序。你设置的超时时间越长,线程被占用的时间就越长,其他被阻塞的请求就没有线程来处理它,然后请求就会堆积起来,最终你的应用程序都会崩溃。多亏对方能想出这种回复,遇到这种类似的情况,如果不确定,及时和同事或者领导商量一下,不要只听他的就改.你看看所谓大厂的接口,也是一样。总之,在处理二方、三方接口的时候,一定要多加小心,空判断、降级等一定要小心。我发现有些新生真的不喜欢评空,因为他们觉得多写一个if很难看,啧啧,年轻还是太年轻,从来没有被打过!那么,你遇到三方时最恶心的一幕是什么?收到消息祝大家快乐?好了,今天就这些啦~我是的,从一点点到十亿点,下篇文章见~