inBound事件spa
當發生某個IO事件的時候,例如鏈路創建,鏈路關閉,讀取操做完成(register,read,active)等,都會產生一個事件,事件在pipeline中傳播和處理。pipeline中以fireXXX命名的方法都是從IO線程向用戶業務Handler的inBound事件,它們的實現因功能而異,可是處理步驟相似。以下:線程
(1)調用HeadHandler對應的fireXXX方法。事件
(2)執行事件相關的邏輯操做。ip
當調用ChannelHandlerContext.fireXXX(fireChannelRead())方法的時候,事件會從當前節點向下進行傳播,就是找到下一個ChannelInBoundHandler,而後調用ChannelInBoundHandler的channelXXX方法,若是不覆蓋channelXXX方法的話,默認會將這個消息在pipeline上從頭至尾進行傳播,最後會調用到Tail節點的channelXXX方法,若是說有消息一直調用到Tail節點的channelXXX方法,說明前面的channelHandler沒有處理消息,使得消息一直到了尾節點,尾節點須要進行必定的釋放,防止內存泄漏。內存
SimpleChannelInBoundHandler的channelRead0方法會幫助自動釋放ByteBuf,它的channelRead方法調用channelRead0()而且釋放ByteBuf。pip
outBound事件io
由用戶線程或者代碼發起的IO操做被稱作outBound事件。ChannelOutBoundHandler的添加順序和事件傳播的順序是相反的。而outBound事件是尋找下一個ChannelOutBoundHandler,調用該handler的方法,最終會從Tail節點傳播到Head節點。內存泄漏
總結:每次使用pipeline傳播調用方法時,是從頭結點或者尾節點開始傳播,而使用ChannelHandlerContext則是從當前節點開始傳播。exception
異常傳播channel
異常的傳播並不區分是inBoundHandler仍是outBoundHandler,異常都會在上面進行傳播。異常的傳播順序是和handler添加的順序相關(同樣)。默認狀況下異常的傳播是直接拿到當前節點的下一個節點,最終會傳播到Tail節點的exceptionCaught(),Tail節點最終會打印這個exception,通知這個異常並無被處理。若是說咱們須要對異常作一個處理的話,最好在pipeline最後添加一個異常處理器,最終能夠對異常進行一個統一的處理。