NIO的epoll空輪詢bug

2022-08-18 04:36:15 字數 1094 閱讀 6221

jdk nio的bug,例如epoll bug,它會導致selector空輪詢,最終導致cpu 100%。

selector bug出現的原因

若selector的輪詢結果為空,也沒有wakeup或新訊息處理,則發生空輪詢,cpu使用率100%

這個bug的描述內容為,在nio的selector中,即使是關注的select輪詢事件的key為0的話,nio照樣不斷的從select本應該阻塞的

情況中wake up出來,也就是下圖中的紅色阻塞的部分:

然後,因為selector的select方法,返回numkeys是0,所以下面本應該對key值進行遍歷的事件處理根本執行不了,又回到最上面的while(true)迴圈,迴圈往復,不斷的輪詢,直到linux系統出現100%的cpu情況,其它執行任務幹不了活,最終導致程式崩潰。

從這個bug上來看,這個絕對是jdk中的問題,select方法就應該是阻塞的,沒有key事件過來,那麼就不應該返回,和應用程式的寫法沒有任何的關係

netty的解決辦法

1) 根據該bug的特徵,首先偵測該bug是否發生

偵測方法:對selector的select操作週期進行統計,每完成一次空的select操作進行一次計數;

若在某個週期內連續發生n次空輪詢,則觸發了epoll死迴圈bug, netty預設是512次

2) 將問題selector上註冊的channel轉移到新建的selector上;

3) 老的問題selector關閉,使用新建的selector替換。

下面具體看下**,首先檢測是否發生了該bug:

epoll bug 檢測:

一旦檢測發生該bug,則重建selector,**如下:

重建完成之後,替換老的selector,**如下:

大量生產系統的執行表明,netty的規避策略可以解決epoll bug 導致的io執行緒cpu死迴圈問題。

netty的解決**在package io.netty.channel.nio.nioeventloop這個類下面

NIO客戶端主動關閉連線,導致伺服器空輪詢

當客戶端連線關閉時,伺服器select 不會阻塞,然後一直分發讀就緒操作。public static void main string args throws ioexception else if selectionkey.isreadable catch ioexception e if cou...

ajax的輪詢和長輪詢

概念 輪詢 polling 客戶端按規定時間定時像服務端傳送ajax請求,伺服器接到請求後馬上返回響應資訊並關閉連線。概念總是枯燥的,只有 方能解心頭之快 前段 index.html 服務端php server.php conn mysqli connect localhost root test ...

長輪詢和短輪詢的區別

http 協議是請求 響應正規化的,每乙個 http 響應都是由乙個對應的 http 請求產生的 http 協議是無狀態的,多個 http 請求之間是沒有關係的.目前 http 協議普遍使用的是 1.1 版本,之前有個 1.0 版本,兩者之間的乙個區別是 1.1 支援 http 長連線,或者叫持久連...