1. 程式人生 > >Netty高效能之Reactor執行緒模型

Netty高效能之Reactor執行緒模型

Netty是一個高效能、非同步事件驅動的NIO框架,它提供了對TCP、UDP和檔案傳輸的支援,作為一個非同步NIO框架,Netty的所有IO操作都是非同步非阻塞的,通過Future-Listener機制,使用者可以方便的主動獲取或者通過通知機制獲得IO操作結果。

作為當前最流行的NIO框架,Netty在網際網路領域、大資料分散式計算領域、遊戲行業、通訊行業等獲得了廣泛的應用,一些業界著名的開源元件也基於Netty的NIO框架構建

傳統通訊採用了同步阻塞IO,當客戶端的併發壓力或者網路時延增大之後,同步阻塞IO會由於頻繁的wait導致IO執行緒經常性的阻塞,由於執行緒無法高效的工作,IO處理能力自然下降。

我們通過BIO通訊模型圖看下BIO通訊的弊端


採用BIO通訊模型的服務端,通常由一個獨立的Acceptor執行緒負責監聽客戶端的連線,接收到客戶端連線之後為客戶端連線建立一個新的執行緒處理請求訊息,處理完成之後,返回應答訊息給客戶端,執行緒銷燬,這就是典型的一請求一應答模型

該架構最大的問題就是不具備彈性伸縮能力,當併發訪問量增加後,服務端的執行緒個數和併發訪問數成線性正比,由於執行緒是JAVA虛擬機器非常寶貴的系統資源,當執行緒數膨脹之後,系統的效能急劇下降,隨著併發量的繼續增加,可能會發生控制代碼溢位、執行緒堆疊溢位等問題,並導致伺服器最終宕機。

Netty基於NIO,實現了對NIO的封裝及優化,從而Netty的通訊模式為非同步非阻塞通訊

在IO程式設計過程中,當需要同時處理多個客戶端接入請求時,可以利用多執行緒或者IO多路複用技術進行處理。IO多路複用技術通過把多個IO的阻塞複用到同一個select的阻塞上,從而使得系統在單執行緒的情況下可以同時處理多個客戶端請求。與傳統的多執行緒/多程序模型比,I/O多路複用的最大優勢是系統開銷小,系統不需要建立新的額外程序或者執行緒,也不需要維護這些程序和執行緒的執行,降低了系統的維護工作量,節省了系統資源。

JDK1.4提供了對非阻塞IO(NIO)的支援,JDK1.6版本使用epoll替代了傳統的select/poll,極大的提升了NIO通訊的效能

Netty架構按照Reactor模式設計和實現

,它的服務端通訊序列圖如下




Netty的IO執行緒NioEventLoop由於聚合了多路複用器Selector,可以同時併發處理成百上千個客戶端Channel,由於讀寫操作都是非阻塞的,這就可以充分提升IO執行緒的執行效率,避免由於頻繁IO阻塞導致的執行緒掛起。另外,由於Netty採用了非同步通訊模式,一個IO執行緒可以併發處理N個客戶端連線和讀寫操作,這從根本上解決了傳統同步阻塞IO一連線一執行緒模型,架構的效能、彈性伸縮能力和可靠性都得到了極大的提升。

何為Reactor執行緒模型?

Reactor模式是事件驅動的,有一個或多個併發輸入源,有一個Service Handler,有多個Request Handlers;這個Service Handler會同步的將輸入的請求(Event)多路複用的分發給相應的Request Handler


從結構上,這有點類似生產者消費者模式,即有一個或多個生產者將事件放入一個Queue中,而一個或多個消費者主動的從這個Queue中Poll事件來處理;而Reactor模式則並沒有Queue來做緩衝,每當一個Event輸入到Service Handler之後,該Service Handler會立刻的根據不同的Event型別將其分發給對應的Request Handler來處理

這個做的好處有很多,首先我們可以將處理event的Request handler實現一個單獨的執行緒,即


這樣Service Handler 和request Handler實現了非同步,加快了service Handler處理event的速度,那麼每一個request同樣也可以以多執行緒的形式來處理自己的event,即Thread1 擴充套件成Thread pool 1,

Netty的Reactor執行緒模型1 Reactor單執行緒模型    Reactor機制中保證每次讀寫能非阻塞讀寫


一個執行緒(單執行緒)來處理CONNECT事件(Acceptor),一個執行緒池(多執行緒)來處理read,一個執行緒池(多執行緒)來處理write,那麼從Reactor Thread到handler都是非同步的,從而IO操作也多執行緒化。

到這裡跟BIO對比已經提升了很大的效能,但是還可以繼續提升,由於Reactor Thread依然為單執行緒,從效能上考慮依然有所限制

2 Reactor多執行緒模型


這樣通過Reactor Thread Pool來提高event的分發能力

3 Reactor主從模型


Netty的高效併發程式設計主要體現在如下幾點:

1) volatile的大量、正確使用;

2) CAS和原子類的廣泛使用;

3) 執行緒安全容器的使用;

4) 通過讀寫鎖提升併發效能。

Netty除了使用reactor來提升效能,當然還有

1、零拷貝,IO效能優化

2、通訊上的粘包拆包

2、同步的設計

3、高效能的序列