Netty高效能之Reactor執行緒模型
作為當前最流行的NIO框架,Netty在網際網路領域、大資料分散式計算領域、遊戲行業、通訊行業等獲得了廣泛的應用,一些業界著名的開源元件也基於Netty的NIO框架構建
傳統通訊採用了同步阻塞IO,當客戶端的併發壓力或者網路時延增大之後,同步阻塞IO會由於頻繁的wait導致IO執行緒經常性的阻塞,由於執行緒無法高效的工作,IO處理能力自然下降。
我們通過BIO通訊模型圖看下BIO通訊的弊端
該架構最大的問題就是不具備彈性伸縮能力,當併發訪問量增加後,服務端的執行緒個數和併發訪問數成線性正比,由於執行緒是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、同步的設計