Netty源碼分析 - 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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章