天天看點

《Netty 權威指南》—— 4種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的模型。相關優化的官方說明如下:

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

jdk1.5_update10 支援epoll

jdk1.7提供的nio2.0,新增了異步的套接字通道,它是真正的異步io,在異步io操作的時候可以傳遞信号變量,當操作完成之後會回調相關的方法,異步io也被稱為aio。

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

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

在前面的章節我們介紹過java nio的實作關鍵是通過多路複用io技術實作的,多路複用的核心就是通過selector來輪詢注冊在其上的channel,當發現某個或者多個channel處于就緒狀态後,從阻塞狀态傳回就緒的channel的選擇鍵集合,進行io操作。由于多路複用器是nio實作非阻塞io的關鍵,它又是主要通過selector實作,是以本書将selector翻譯為多路複用器,它與其它技術書籍所說的選擇器是同一個東西,請大家了解。

僞異步io的概念完全來源于實踐,在jdk nio程式設計沒有流行之前,為了解決tomcat通信線程同步io導緻業務線程被挂住的問題,大家想到了一個辦法,就是在通信線程和業務線程之間做個緩沖區,這個緩沖區用于隔離io線程和業務線程間的直接通路,這樣業務線程就不會被io線程阻塞,對于後端的業務側來說,将消息或者task放到線程池後就傳回了,它不再直接通路io線程或者進行io讀寫,這樣也就不會被同步阻塞。類似這樣的設計還包括前端啟動一組線程,将接收的用戶端封裝成task,放到後端的線程池執行,用于解決一連接配接一線程問題,類似這樣通過線程池做緩沖區的做法,我們習慣稱它為僞異步io,官方并沒有僞異步io這種說法。

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

不同的io模型由于線程模型、api等差别很大,是以它們的用法差異也非常大。由于之前的幾個小節已經集中對這幾種io的api和用法進行了說明,本小節重點對這幾種io進行功能對比。

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

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

盡管本書是專門介紹nio架構netty的,但是,并不意味着所有的java網絡程式設計都必須要選擇nio和netty,具體選擇什麼樣的io模型或者nio架構,完全基于業務的實際應用場景和性能訴求,如果用戶端并發連接配接數不多,周邊對接的網元不多,伺服器的負載也不重,那就完全沒必要選擇nio做服務端;如果是相反情況,那就要考慮選擇合适的nio架構進行開發。

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

<a href="http://ifeve.com/netty-2-5/#abh_posts">latest posts</a>

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

《netty權威指南》作者,進階架構師。

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

<a href="http://ifeve.com/netty-2-5/?wpfpaction=add&amp;postid=12372">添加本文到我的收藏</a>

<a href="http://ifeve.com/netty-2-4-3/">《netty 權威指南》—— aio版本時間伺服器運作結果</a>

<a href="http://ifeve.com/netty-definitive-guide/">《netty 權威指南》樣章</a>

<a href="http://ifeve.com/netty-2-3-1/">《netty 權威指南》—— nio類庫簡介</a>

<a href="http://ifeve.com/netty-2-3-4/">《netty 權威指南》—— nio用戶端序列圖</a>

<a href="http://ifeve.com/netty-definitive-guide-2-1/">《netty 權威指南》—— 傳統的bio程式設計</a>

<a href="http://ifeve.com/netty-2-3-2/">《netty 權威指南》—— 服務端序列圖</a>

<a href="http://ifeve.com/netty-2-3-5/">《netty 權威指南》—— nio建立的timeclient源碼分析</a>

<a href="http://ifeve.com/netty-definitive-guide-2-2/">《netty 權威指南》—— 僞異步io程式設計</a>

<a href="http://ifeve.com/netty-2-6/">《netty 權威指南》—— 選擇netty的理由</a>

<a href="http://ifeve.com/netty-4-2/">《netty 權威指南》—— aio建立的timeclient源碼分析</a>

<a href="http://ifeve.com/netty-2-4-1/">《netty 權威指南》—— aio 建立的timeserver源碼分析</a>

<a href="http://ifeve.com/netty-2-3-3/">《netty 權威指南》—— nio建立的timeserver源碼分析</a>

<a href="http://ifeve.com/netty-mina-in-depth-1/">netty-mina深入學習與對比(一)</a>

<a href="http://ifeve.com/netty5-user-guide/">netty 5使用者指南</a>

<a href="http://ifeve.com/netty-mina-in-depth-2/">netty-mina深入學習與對比(二)</a>