NIO的epoll空轮询bug

JDK NIO的bug,例如epoll bug,它会致使Selector空轮询,最终致使CPU 100%。linux

Selector BUG出现的缘由

若Selector的轮询结果为空,也没有wakeup或新消息处理,则发生空轮询,CPU使用率100%oop

这个bug的描述内容为,在NIO的selector中,即便是关注的select轮询事件的key为0的话,NIO照样不断的从select本应该阻塞的spa

状况中wake up出来,也就是下图中的红色阻塞的部分:.net

 

而后,由于selector的select方法,返回numKeys是0,因此下面本应该对key值进行遍历的事件处理根本执行不了,又回到最上面的while(true)循环,循环往复,不断的轮询,直到linux系统出现100%的CPU状况,其它执行任务干不了活,最终致使程序崩溃。线程

从这个bug上来看,这个绝对是JDK中的问题,select方法就应该是阻塞的,没有key事件过来,那么就不该该返回,和应用程序的写法没有任何的关系netty

Netty的解决办法

1) 根据该BUG的特征,首先侦测该BUG是否发生blog

   侦测方法:对Selector的select操做周期进行统计,每完成一次空的select操做进行一次计数;事件

                  若在某个周期内连续发生N次空轮询,则触发了epoll死循环bug, netty默认是512次io

2) 将问题Selector上注册的Channel转移到新建的Selector上;class

3) 老的问题Selector关闭,使用新建的Selector替换。

下面具体看下代码,首先检测是否发生了该BUG:

epoll bug 检测:

一旦检测发生该BUG,则重建Selector,代码以下:

重建完成以后,替换老的Selector,代码以下:

 

大量生产系统的运行代表,Netty的规避策略能够解决epoll bug 致使的IO线程CPU死循环问题。

netty的解决代码在package io.netty.channel.nio.NioEventLoop这个类下面

相关文章
相关标签/搜索