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這個類下面

相關文章
相關標籤/搜索