Netty详解(四):Netty 整体架构
1. 概述
Netty是JBoss出品的高效的Java NIO開發框架,本文將主要分析Netty實現方面的東西。
Netty總體架構圖:
2. Buffer
org.jboss.netty.buffer包的接口及類的結構圖如下:
2.1 Channel Buffer的種類
Netty使用ChannelBuffer來存儲并操作讀寫的網絡數據。ChannelBuffer除了提供和ByteBuffer類似的方法,還提供了 一些實用方法,具體可參考其API文檔。ChannelBuffer的實現類有多個,這里列舉其中主要的幾個:
2.2 Buufer的讀寫策略
對于讀寫網絡數據的buffer,分配策略有兩種:
buffer的寄存策略常見的也有兩種(其實是我知道的就限于此):
Netty對buffer的處理策略是:讀請求數據時,Netty首先讀數據到新創建的固定大小的HeapChannelBuffer中,當HeapChannelBuffer滿或者沒有數據可讀 時,調用handler來處理數據,這通常首先觸發的是用戶自定義的DecodeHandler,因為handler對象是和ChannelSocket 綁定的,所以在DecodeHandler里可以設置ChannelBuffer成員,當解析數據包發現數據不完整時就終止此次處理流程,等下次讀事件觸發時接著上次的數據繼續解析。就這個過程來說,和ChannelSocket綁定的DecodeHandler中的Buffer通常是動態的可重用 Buffer(DynamicChannelBuffer),而在NioWorker中讀ChannelSocket中的數據的buffer是臨時分配的固定大小的HeapChannelBuffer,這個轉換過程是有個字節拷貝行為的。
2.3 ChannelBufferFactory
對ChannelBuffer的創建,Netty內部使用的是ChannelBufferFactory接口,具體的實現有 DirectChannelBufferFactory和HeapChannelBufferFactory。對于開發者創建 ChannelBuffer,可使用實用類ChannelBuffers中的工廠方法。
3. Channel
和Channel相關的接口及類結構圖如下:
從該結構圖也可以看到,Channel主要提供的功能如下:
在Channel實現方面,以通常使用的nio socket來說,Netty中的NioServerSocketChannel和NioSocketChannel分別封裝了java.nio中包含的 ServerSocketChannel和SocketChannel的功能。
4. ChannelEvent
如前所述,Netty是事件驅動的,其通過ChannelEvent來確定事件流的方向。一個ChannelEvent是依附于Channel的 ChannelPipeline來處理,并由ChannelPipeline調用ChannelHandler來做具體的處理。下面是和 ChannelEvent相關的接口及類圖:
對于使用者來說,在ChannelHandler實現類中會使用繼承于ChannelEvent的MessageEvent,調用其 getMessage()方法來獲得讀到的ChannelBuffer或被轉化的對象。
4. ChannelPipeline
Netty 在事件處理上,是通過ChannelPipeline來控制事件流,通過調用注冊其上的一系列ChannelHandler來處理事件,這也是典型的攔截 器模式。下面是和ChannelPipeline相關的接口及類圖:
事件流有兩種,upstream事件和downstream事件。在ChannelPipeline中,其可被注冊的ChannelHandler既可以 是 ChannelUpstreamHandler 也可以是ChannelDownstreamHandler ,但事件在ChannelPipeline傳遞過程中只會調用匹配流的ChannelHandler。在事件流的過濾器鏈 中,ChannelUpstreamHandler或ChannelDownstreamHandler既可以終止流程,也可以通過調用 ChannelHandlerContext.sendUpstream(ChannelEvent)或 ChannelHandlerContext.sendDownstream(ChannelEvent)將事件傳遞下去。下面是事件流處理的圖示:
從上圖可見,upstream event是被Upstream Handler們自底向上逐個處理,downstream event是被Downstream Handler們自頂向下逐個處理,這里的上下關系就是向ChannelPipeline里添加Handler的先后順序關系。簡單的理 解,upstream event是處理來自外部的請求的過程,而downstream event是處理向外發送請求的過程。
服務端處 理請求的過程通常就是解碼請求、業務邏輯處理、編碼響應,構建的ChannelPipeline也就類似下面的代碼片斷
4.1 ChannelPipeline中編碼解碼Handler
ChannelPipeline pipeline = Channels.pipeline(); pipeline.addLast("decoder", new MyProtocolDecoder()); pipeline.addLast("encoder", new MyProtocolEncoder()); pipeline.addLast("handler", new MyBusinessLogicHandler());其中,MyProtocolDecoder是ChannelUpstreamHandler類型,MyProtocolEncoder是 ChannelDownstreamHandler類型,MyBusinessLogicHandler既可以是 ChannelUpstreamHandler類型,也可兼ChannelDownstreamHandler類型,視其是服務端程序還是客戶端程序以及 應用需要而定。
補充一點,Netty對抽象和實現做了很好的解耦。像org.jboss.netty.channel.socket包, 定義了一些和socket處理相關的接口,而org.jboss.netty.channel.socket.nio、 org.jboss.netty.channel.socket.oio等包,則是和協議相關的實現。
5. codec framework
對于請求協議的編碼解碼,當然是可以按照協議格式自己操作ChannelBuffer中的字節數據。另一方面,Netty也做了幾個很實用的codec helper,這里給出簡單的介紹。
總結
以上是生活随笔為你收集整理的Netty详解(四):Netty 整体架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Netty详解(六):Netty 编解码
- 下一篇: Netty详解(七):Netty 编解码