ChannelPipeline原始碼分析
pipeline的初使化
- pipeline的建立:pipeline在建立channel(無論是客服端的channel還是服務端的channel)的時候被建立。
pipeline的入口
- Netty裡目前只有一個pipeline的實現, 也就是DefaultChannelPipeline,構造方法如圖:
pipeline的構造方法
- 在Netty裡,業務邏輯是以寫對應的ChannelHandler來實現的,在Netty的內部,會將ChannelHandler封裝成ChannelHandlerContext物件,然後以連結串列的雙鏈表的形式進行組織。AbstractChannelHandlerContext部分程式碼如下:
AbstractChannelHandlerContext
AbstractChannelHandlerContext構造方法
- 在pipeline裡有head和tail兩個屬性,分別指向channelHandlerContext的頭結點和尾結點,其中HeadContext內部有unsafe物件,可以通過unsafe處理讀寫事件。程式碼如下:
HeadContext構造方法
- TailContext的inbound屬性設定為true
TailContext構造方法
新增ChannelHandler
DefaultChannelPipeline提供了往連結串列裡增加節點的方法,增加一個ChannelHandler包括如下幾個步驟

添回ChannelHandler步驟
- 判斷是否重複新增
checkMultiplicity方法來防止重複增加
- 建立節點並新增到雙鏈表中
將ChannelHandler轉成DefaultChannelHandlerContext
增加到雙鏈表中
- 回撥添回完成事件
呼叫回撥方法
改變ChannelHandlerContext的狀態
刪除ChannelHandler
刪除channleHandler的入口如下圖:

DefaultChannelPipeline的remove方法
- 找結點
找結點的入口方法
連結串列找結點邏輯
- 刪除結點
找到結點後刪除節點邏輯
雙鏈表中刪除結點操作
- 回撥事件
回撥方法
事件與異常的傳播
channelHandler在大類上可以分為InboundHandler與outboundHandler。類圖如下:

channelHandler的類結構圖
read事件的傳播分析(Inbound事件)
當連線監聽到有OP_READ事件後,會呼叫unsafe的read方法進行處理,下面來看看unsafe是如何處理事件的。
- 處理channel read的入口
NioByteUnsafe的read方法
- pipeline觸發read的入口
DefaultChannelPipeline的fireChannelRead方法
- 呼叫head的invokeChannelRead方法
invokeChannelRead方法
- 最終會呼叫到channelHandler的channelRead方法
- head結點的處理邏輯
head結點的處理邏輯
- 找到下一個型別為inbound的channelHandler
- 尾結點的處理邏輯,如果訊息沒處理,則會打個warm日誌,並釋放bytebuf物件
write事件的傳播分析(Outbound事件)
在寫業務ChannelHandler的時候,如果是outbound型別的handler,可以重寫write方法,並通過ChannelHandlerContext物件呼叫write,讓write進行傳播,其中通過 channel呼叫的write方法會從pipeline的tail結點開始傳播,而直接呼叫ChannelHandlerContext的write方法會從當前結點進行傳播 。下面分析write事件如何在pipeline裡進行傳播
- 事件傳播的入口
AbstractChannel的write方法
- tail結點write處理邏輯
- 找到前一個結點的處理邏輯
- 呼叫handler的witer方法
- 通過head結點的write方法,呼叫channel的unsafe物件,執行寫入操作
異常的傳播
當channelHandler在處理業務的時候發生了異常,異常資訊會從當前的鏈上往下傳播,直到有一個channelHandler把異常處理了,如果沒有channelHandler把異常處理,會傳播到tail結點,在實際業務中, 在channelHandler鏈的最後增加一個統一的異常處理 下面分析異常的傳播流程
- 異常傳播入口
- 會呼叫到invokeExceptionCaught方法
- 呼叫到hander的exceptionCaught方法
- 在channelHandlerAdapter裡,預設會讓exception往下傳播
- AbstractChannelHandlerContext異常傳播的邏輯,先當前結點的下一個結點
- 傳到tail結點的邏輯