Netty架構設計

功能特性

  • 傳輸服務
    支持BIO和NIO
  • 容器集成
    支持OSGI、JBossMC、Spring、Guice容器
  • 協議支持
    HTTP、Protobuf、二進制、文本、WebSocket等一系列常見協議都支持。
    還支持通過實行編碼解碼邏輯來實現自定義協議
  • Core核心
    可擴展事件模型、通用通信API、支持零拷貝的ByteBuf緩衝對象

模塊組件

Bootstrap、ServerBootstrap

Bootstrap意思是引導,一個Netty應用通常由一個Bootstrap開始,主要作用是配置整個Netty程序,串聯各個組件,Netty中Bootstrap類是客戶端程序的啓動引導類,ServerBootstrap是服務端啓動引導類。

Future、ChannelFuture

正如前面介紹,在Netty中所有的IO操作都是異步的,不能立刻得知消息是否被正確處理,但是可以過一會等它執行完成或者直接註冊一個監聽,具體的實現就是通過Future和ChannelFutures,他們可以註冊一個監聽,當操作執行成功或失敗時監聽會自動觸發註冊的監聽事件。

Channel

Netty網絡通信的組件,能夠用於執行網絡I/O操作。
Channel爲用戶提供:

  • 當前網絡連接的通道的狀態(例如是否打開?是否已連接?)
  • 網絡連接的配置參數 (例如接收緩衝區大小)
  • 提供異步的網絡I/O操作(如建立連接,讀寫,綁定端口),異步調用意味着任何I / O調用都將立即返回,並且不保證在調用結束時所請求的I / O操作已完成。調用立即返回一個ChannelFuture實例,通過註冊監聽器到ChannelFuture上,可以I / O操作成功、失敗或取消時回調通知調用方。
  • 支持關聯I/O操作與對應的處理程序

不同協議、不同的阻塞類型的連接都有不同的 Channel 類型與之對應,下面是一些常用的 Channel 類型

  • NioSocketChannel,異步的客戶端 TCP Socket 連接
  • NioServerSocketChannel,異步的服務器端 TCP Socket 連接
  • NioDatagramChannel,異步的 UDP 連接
  • NioSctpChannel,異步的客戶端 Sctp 連接
  • NioSctpServerChannel,異步的 Sctp 服務器端連接

這些通道涵蓋了 UDP 和 TCP網絡 IO以及文件 IO.

Selector

Netty基於Selector對象實現I/O多路複用,通過 Selector, 一個線程可以監聽多個連接的Channel事件, 當向一個Selector中註冊Channel 後,Selector 內部的機制就可以自動不斷地查詢(select) 這些註冊的Channel是否有已就緒的I/O事件(例如可讀, 可寫, 網絡連接完成等),這樣程序就可以很簡單地使用一個線程高效地管理多個 Channel 。

NioEventLoop

NioEventLoop中維護了一個線程和任務隊列,支持異步提交執行任務,線程啓動時會調用NioEventLoop的run方法,執行I/O任務和非I/O任務:

  • I/O任務
    即selectionKey中ready的事件,如accept、connect、read、write等,由processSelectedKeys方法觸發。
  • 非IO任務
    添加到taskQueue中的任務,如register0、bind0等任務,由runAllTasks方法觸發。

兩種任務的執行時間比由變量ioRatio控制,默認爲50,則表示允許非IO任務執行的時間與IO任務的執行時間相等。

NioEventLoopGroup

NioEventLoopGroup,主要管理eventLoop的生命週期,可以理解爲一個線程池,內部維護了一組線程,每個線程(NioEventLoop)負責處理多個Channel上的事件,而一個Channel只對應於一個線程。

ChannelHandler

ChannelHandler是一個接口,處理I / O事件或攔截I / O操作,並將其轉發到其ChannelPipeline(業務處理鏈)中的下一個處理程序。
ChannelHandler本身並沒有提供很多方法,因爲這個接口有許多的方法需要實現,方便使用期間,可以繼承它的子類:

  • ChannelInboundHandler用於處理入站I / O事件
  • ChannelOutboundHandler用於處理出站I / O操作

或者使用以下適配器類:

  • ChannelInboundHandlerAdapter用於處理入站I / O事件
  • ChannelOutboundHandlerAdapter用於處理出站I / O操作
  • ChannelDuplexHandler用於處理入站和出站事件

ChannelHandlerContext

保存Channel相關的所有上下文信息,同時關聯一個ChannelHandler對象

ChannelPipline

保存ChannelHandler的List,用於處理或攔截Channel的入站事件和出站操作。 ChannelPipeline實現了一種高級形式的攔截過濾器模式,使用戶可以完全控制事件的處理方式,以及Channel中各個的ChannelHandler如何相互交互。

下圖引用Netty的Javadoc4.1中ChannelPipline的說明,描述了ChannelPipeline中ChannelHandler通常如何處理I/O事件。 I/O事件由ChannelInboundHandler或ChannelOutboundHandler處理,並通過調用ChannelHandlerContext中定義的事件傳播方法(例如ChannelHandlerContext.fireChannelRead(Object)和ChannelOutboundInvoker.write(Object))轉發到其最近的處理程序。

入站事件由自下而上方向的入站處理程序處理,如圖左側所示。 入站Handler處理程序通常處理由圖底部的I / O線程生成的入站數據。 通常通過實際輸入操作(例如SocketChannel.read(ByteBuffer))從遠程讀取入站數據。

出站事件由上下方向處理,如圖右側所示。 出站Handler處理程序通常會生成或轉換出站傳輸,例如write請求。 I/O線程通常執行實際的輸出操作,例如SocketChannel.write(ByteBuffer)。

在 Netty 中每個 Channel 都有且僅有一個 ChannelPipeline 與之對應, 它們的組成關係如下:

一個 Channel 包含了一個 ChannelPipeline, 而 ChannelPipeline 中又維護了一個由 ChannelHandlerContext 組成的雙向鏈表, 並且每個 ChannelHandlerContext 中又關聯着一個 ChannelHandler。入站事件和出站事件在一個雙向鏈表中,入站事件會從鏈表head往後傳遞到最後一個入站的handler,出站事件會從鏈表tail往前傳遞到最前一個出站的handler,兩種類型的handler互不干擾。

參考:
再有人問你Netty是什麼,就把這篇文章發給他


技術討論 & 疑問建議 & 個人博客

版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 許可協議,轉載請註明出處!

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