Netty中如何解决select空轮询导致cpu使用率升至100%的bug

1、 BUG出现的原因:
若Selector的轮询结果为空,也没有wakeup或新消息处理,则发生N多次空轮询,使得CPU使用率100%

2、Netty中的解决思路:
对Selector()方法中的阻塞定时 select(timeMIllinois)操作的 次数进行统计,每完成一次select操作进行一次计数,若在循环周期内    发生N次空轮询,如果N值大于BUG阈值(默认为512),就进行空轮询BUG处理。重建Selector,判断是否是其他线程发起的重建请求,若不是则将原SocketChannel从旧的Selector上去除注册,重新注册到新的    Selector上,并将原来的Selector关闭。
源码:已将部分代码省略,全部代码在io.netty.channel.nio.NioEventLoop类当中的select()方法中。

select方法分三个部分:
//第一部分:超时处理逻辑
//第二部分:定时阻塞select(timeMillins)  
// 第三步: 解决空轮询 BUG
            long time = System.nanoTime();
            //此处的逻辑就是: 当前时间 - 循环开始时间 >= 定时select的时间timeoutMillis,说明已经执行过一次阻塞select()
            if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) {
                selectCnt = 1; // 说明发生过一次阻塞式轮询
                
                // 如果空轮询的次数大于空轮询次数阈值 SELECTOR_AUTO_REBUILD_THRESHOLD(512)
            } else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
                /*  setlctRebuildSelector():
                *   1.首先创建一个新的Selecor
                *   2.将旧的Selector上面的键及其一系列的信息放到新的selector上面。
                /*
                selector = this.selectRebuildSelector(selectCnt);  
                selectCnt = 1;
                break;
            }
            currentTimeNanos = time;


转:https://blog.csdn.net/qq_41884976/article/details/91913820 
 

你可能感兴趣的:(Netty)