1. 程式人生 > >《Netty 權威指南》—— 4種IO的對比

《Netty 權威指南》—— 4種IO的對比

宣告:本文是《Netty 權威指南》的樣章,感謝博文視點授權併發程式設計網站釋出樣章,

2.5.1.概念澄清

為了防止由於對一些技術概念和術語的理解或者叫法不一致引起歧義,本小節特意對本書中的專業術語或者技術用語做下宣告,如果它們與其它的一些技術書籍術語不一致,請以本小節的解釋為準。

2.5.1.1. 非同步非阻塞IO

很多人喜歡將JDK1.4提供的NIO框架稱為非同步非阻塞IO,但是,如果嚴格按照Unix網路程式設計模型和JDK的實現進行區分,實際上它只能被稱為非阻塞IO,不能叫非同步非阻塞IO。在早期的JDK1.4和1.5 update10版本之前,JDK的Selector基於select/poll模型實現,它是基於IO複用技術的非阻塞IO,不是非同步IO。在JDK1.5 update10和linux core2.6以上版本,sun優化了Selctor的實現,它底層使用epoll替換了select/poll,上層的API並沒有變化,我們可以認為是JDK NIO的一次效能優化,但是它仍舊沒有改變IO的模型。相關優化的官方說明如下:

1

JDK1.5_update10 支援epoll

JDK1.7提供的NIO2.0,新增了非同步的套接字通道,它是真正的非同步IO,在非同步IO操作的時候可以傳遞訊號變數,當操作完成之後會回撥相關的方法,非同步IO也被稱為AIO。

NIO類庫支援非阻塞讀和寫操作,相比於之前的同步阻塞讀和寫,它是非同步的,因此很多人習慣於稱NIO為非同步非阻塞IO,包括很多介紹NIO程式設計的書籍也沿用了這個說法。為了符合大家的習慣,本書也會將NIO稱為非同步非阻塞IO或者非阻塞IO,請大家理解,不要過分糾結在一些技術術語的咬文嚼字上。

2.5.1.2. 多路複用器Selector

幾乎所有的中文技術書籍都將Selector翻譯為選擇器,但是實際上我認為這樣的翻譯並不恰當,選擇器僅僅是字面上的意思,這樣翻譯體現不出Selector的功能和特點。

在前面的章節我們介紹過Java NIO的實現關鍵是通過多路複用IO技術實現的,多路複用的核心就是通過Selector來輪詢註冊在其上的Channel,當發現某個或者多個Channel處於就緒狀態後,從阻塞狀態返回就緒的Channel的選擇鍵集合,進行IO操作。由於多路複用器是NIO實現非阻塞IO的關鍵,它又是主要通過Selector實現,所以本書將Selector翻譯為多路複用器,它與其它技術書籍所說的選擇器是同一個東西,請大家瞭解。

2.5.1.3.  偽非同步IO

偽非同步IO的概念完全來源於實踐,在JDK NIO程式設計沒有流行之前,為了解決Tomcat通訊執行緒同步IO導致業務執行緒被掛住的問題,大家想到了一個辦法,就是在通訊執行緒和業務執行緒之間做個緩衝區,這個緩衝區用於隔離IO執行緒和業務執行緒間的直接訪問,這樣業務執行緒就不會被IO執行緒阻塞,對於後端的業務側來說,將訊息或者Task放到執行緒池後就返回了,它不再直接訪問IO執行緒或者進行IO讀寫,這樣也就不會被同步阻塞。類似這樣的設計還包括前端啟動一組執行緒,將接收的客戶端封裝成Task,放到後端的執行緒池執行,用於解決一連線一執行緒問題,類似這樣通過執行緒池做緩衝區的做法,我們習慣稱它為偽非同步IO,官方並沒有偽非同步IO這種說法。

下面的小節我們對幾種常見的IO進行對比,以便大家能夠理解幾種IO的差異。

2.5.2.不同IO模型對比

不同的IO模型由於執行緒模型、API等差別很大,所以它們的用法差異也非常大。由於之前的幾個小節已經集中對這幾種IO的API和用法進行了說明,本小節重點對這幾種IO進行功能對比。

2

幾種IO模型的功能和特性對比

儘管本書是專門介紹NIO框架Netty的,但是,並不意味著所有的Java網路程式設計都必須要選擇NIO和Netty,具體選擇什麼樣的IO模型或者NIO框架,完全基於業務的實際應用場景和效能訴求,如果客戶端併發連線數不多,周邊對接的網元不多,伺服器的負載也不重,那就完全沒必要選擇NIO做服務端;如果是相反情況,那就要考慮選擇合適的NIO框架進行開發。

對比完Java的幾種主流IO模型之後,我們繼續看下為什麼要選擇Netty進行NIO開發,而不是直接使用JDK的NIO原生類庫。