Netty簡介

我們已經瞭解了Socket通信的IO/NIO/AIO編程,對於通信模型已經有了一個初步的認識。在實際的工作中,我們需要不斷地完善、擴展和優化。比如很經典的TCP讀包寫包問題,或者是數據接收的大小,實際的通信讀取與應答的處理邏輯等一些細節的問題需要我們認真的去思考,而這些我們都需要大量的時間和精力,以及豐富的經驗。而Netty在這基礎上做了封裝,我們使用Netty可以更加簡單地實現上述細節。我們再也不必去編寫複雜的代碼邏輯去實現通信,我們再也不需要去考慮性能問題,不需要考慮編解碼問題,半包讀寫問題等。這些細節Netty都已經幫我們實現好了,我們只需要使用即可。

Netty是一款異步的事件驅動的網絡應用程序框架,支持快速地開發可維護的高性能的面向協議的服務器和客戶端。Netty是目前最流行的NIO框架,它具有很強的健壯性、性能、可定製性和可擴展性,它已經得到成百上千的商業項目驗證,如Hadoop的RPC框架Avro以及JMS框架、RocketMQ和分佈式通信框架Dubbox等。

一.Netty的特性

Netty的主要特性如下:

  • 設計:統一的API,適用於不同的協議(阻塞和非阻塞);基於靈活、可擴展的事件驅動模型;高度可定製的線程模型;可靠的無連接數據Socket支持(UDP)
  • 性能:更好的吞吐量;低延遲,更省資源,儘量減少不必要的內存拷貝
  • 安全:完整的SSL/TLS和STARTTLS的支持;能在Applet與Android的限制環境運行良好
  • 健壯性:不再因過快、過慢或超負載連接導致OutOfMemoryError;不再有在高速網絡環境下NIO讀寫頻率不一致的問題
  • 易用:完善的JavaDoc,用戶指南和樣例;簡潔簡單;僅信賴於JDK1.5

二.Netty核心組件

Netty的主要構建塊包括:

  • Channel
  • 回調
  • Future
  • 事件和ChannelHandler

這些構建塊代表了不同類型的構造:資源、邏輯以及通知。我們的應用程序將使用它們來訪問網絡以及流經網絡的數據。

2.1 Channel

Channel是Java NIO的一個基本構造,它代表了一個到實體的開放連接,如讀操作和寫操作。可以把Channel看作是傳入(入站)或者傳出(出站)數據的載體。因此,它可以被打開或者被關閉,連接或者斷開連接。

2.2 回調

一個回調其實就是一個方法,一個指向已經被提供給另外一個方法的方法的引用。這使得後者可以在適當的時候調用前者。

Netty在內部使用了回調來處理事件,當一個回調被觸發時,相關的事件可以被一個ChannelHandler接口的實現來處理。

2.3 Future

Future提供了另一種在操作完成時通知應用程序的方式。這個對象可以看作是一個異步操作的結果的佔位符;它將在未來的某個時刻完成,並提供對其結果的訪問。

2.4 事件和ChannelHandler

Netty使用不同的事件來通知我們狀態的改變或者是操作的狀態,這使得我們能夠基於已經發生的事件來觸發適當的動作。這些動作可能是:記錄日誌、數據轉換、流控制、應用程序控制。

Netty是一個網絡編程框架,所以事件是按照它們與入站或出站數據流的相關性進行分類的。可能由入站數據或者相關的狀態更改而觸發的事件包括:連接已被激活或者連接失活、數據讀取、用戶事件、錯誤事件。

出站事件是未來將會觸發的某個動作的操作結果,這些動作包括:打開或者關閉到遠程節點的連接;將數據寫到或者沖刷到套接字。

每個事件都可以被分發給ChannelHandler類中的某個用戶實現的方法。這是一個很好的將事件驅動範式直接轉換爲應用程序構建快的例子。下圖展示了一個事件是如何被一個這樣的ChannelHandler鏈處理的。

Netty提供了大量預定義的可以開箱即用的ChannelHandler實現,包括用於各種協議(如HTTP和SSL/TLS)的ChannelHandler。

三.把它們放在一起

3.1 Future/回調和ChannelHandler

Netty的異步網絡編程模型是建立在Future和回調的概念之上的,而將事件派發到ChannelHandler的方法則發生在更深的層次上。結合在一起,這些元素就提供了就提供了一個處理環境,使你的應用程序邏輯可以獨立於任何網絡操作相關的顧慮而獨立地演變。

攔截操作以及高速地轉換入站數據和出站數據,都只需要你提供回調或者利用操作所返回的Future。這使得鏈接操作變得即簡單又高效,並且促進了可重用的通用代碼的編寫。

3.2 選擇器、事件和EventLoop

Netty通過觸發事件將Selector從應用程序中抽象出來,消除了所有本來就需要手動編寫的派發代碼。在內部,將會爲每個Channel分配一個EventLoop,用以處理所有事件,包括:

  • 註冊感興趣的事件
  • 將事件派發給ChannelHandler
  • 安排進一步的動作

EventLoop本身只由一個線程驅動,其處理了一個Channel的所有I/O事件,並且在該EventLoop的整個生命週期內都不會發生改變。這個簡單而且強大的設計消除了可能有的在ChannelHandler實現中需要進行同步的顧慮,因此我們可以專注於提供正確的邏輯,用來在感興趣的數據要處理的時候執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章