Netty責任鏈Pipeline詳解

2020-12-20 騰訊網

一起說說Netty責任鏈,責任鏈這塊是netty運行機制的核心,一起來完整的了解下netty的責任鏈。

(一)責任鏈模式

介紹

責任鏈模式(Chain of Responsibility Pattern) 為請求創建了一個處理對象的鏈。一個請求過來後,就交給一個責任鏈進行調用。在責任鏈裡面定義很多很多的handler,具體請求這個程序的handler,請求者不關心,多少個步驟,多少次,只負責發送到責任鏈上,請求傳遞的細節不關心。

實現責任鏈模式

處理器抽象類,具體的處理器實現類,保存處理器信息,處理執行。

源碼分析

(二)Netty中的ChannelPipeline責任鏈

介紹

pipeline管道保存了通道所有處理器信息,創建channel時自動創建一個專有的pipeline,入站事件和出站事件會調用pipeline上的處理器。

入站事件和出站事件

入站事件:通常指IO線程生成了入站數據

(通俗理解:從socket底層自己往上冒上來的事件都是入站)

比如EventLoop收到selector的OP_READ事件,入站處理器調用socketChannel.read(ByteBuffer)接受到數據後,這將導致通道的ChannelPipeline中包含的下一個中的channelRead方法被調用

出站事件:通常指IO線程執行實際的輸出操作

(通俗理解:想主動往socket底層操作的事件的都是出站)

比如bind方法用時請求server socket綁定到給定的SocketAddress,這將導致通道的ChannelPipeline中包含的下一個出站處理器中的bind方法被調用

Nettty中定義的事件

Pipeline中的handler是什麼

ChannelHeadler

用於處理I/O事件或者攔截I/O操作,並轉發到ChannelPipeline中下一個處理器。這個頂級接口定義功能很弱,實際使用時會去實現下面兩大子接口:處理入站I/O事件的ChannelInboundHandler、處理出站I/O操作的ChannelOutboundHandler

適配器類

為了方便開發,避免所有handler去實現一遍接口方法,Netty提供了簡單的實現類:

ChannelInboundHandlerAdapter處理入站I/O事件

ChannelOutboundHandlerAdapter處理出站I/O事件

ChannelDuplexHandler支持同時處理入站和出站事件

ChannelHandlerContext

實際存儲在Pipeline中的並非是ChannelHandler,而是上下文對象。將Handler包裹在上下文對象中,通過上下文對象與它所屬的ChannelPipeline交互,向上或向下傳遞事件或者修改pipeline都是通過上下文對象。

那麼如何維護Pipeline中的handler呢

ChannelPipeline是線程安全的,ChannelHandler可以在任何時候添加或者刪除。例如你可以在即將交換敏感信息時插入加密處理程序,並在交換後刪除它。一般操作,初始化的時候增加進去,較少刪除。下面是Pipeline中管理的API

除了register方法還有bind方法,bind方法時出站事件執行順序和入站事件相反

請求過來以後又是如何處理的呢?我們通過Accept事件獲取請求,所以我們應該去看accept入站事件是如何處理的,

PS:用戶在管道中有一個或者多個channelhandler來接收I/O事件(例如讀取)和請求I/O操作(例如寫入和關閉)一個典型的伺服器在每個通道的管道中都有以下處理程序,但是根據協議和業務邏輯的複雜性和特徵,可能會有所不同。

協議解碼器--將二進位數據(例如ByteBuf)轉換為Java對象

協議編碼器--將java對象轉化為二進位數據

業務邏輯處理程序--執行實際的業務邏輯(例如訪問資料庫)

相關焦點

  • Netty 實戰:如何實現文件伺服器?
    ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 編碼 String ch.pipeline
  • Netty 實現原理淺析
    Reactor線程是個多面手,負責多路分離套接字,Accept新連接,並分派請求到處理器鏈中。該模型 適用於處理器鏈中業務處理組件能快速完成的場景。不過,這種單線程模型不能充分利用多核資源,所以實際使用的不多。
  • 敖C肝了一個月的Netty知識點
    高能預警,本文是我一個月前就開始寫的,所以內容會非常長,當然也非常硬核,dubbo源碼系列結束之後我就想著寫一下netty系列的,但是netty的源碼概念又非常多,所以才寫到了現在。 = ch.pipeline();                            pipeline.addLast(new StringDecoder());                            pipeline.addLast(new StringEncoder());                            pipeline.addLast
  • Netty堆外內存洩漏排查,這一篇全講清楚了
    ,業務不需要釋放;業務創建的 ByteBuf 則需要自己釋放,Netty 框架不會釋放產生這種誤解是有原因的,Netty框架是會在一些場景調用ByteBuf.release()方法:1 入站消息處理當處理入站消息時,Netty會創建ByteBuf讀取channel上的消息,並觸發調用pipeline
  • 手把手教你調試Netty創建連接流程源碼
    :SocketChannel socketChannel = serverSocketChannel.accept()selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);selectionKey.interestOps(OP_READ);創建連接的初始化和註冊是通過pipeline.fireChannelRead
  • Java-徹底弄懂netty-程式設計師先從簡單例子開啟netty編程-知識鋪
    回顧下簡單服務端Nio代碼:二、netty簡單服務端編程2.1 創建服務啟動類 ServerBootstrap2.2 創建accept線程 ExecutorService accept2.3 創建處理線程
  • SpringBoot+Netty+Websocket整合案例(實現基本的聊天功能)
    二、整合開發建立一個項目,名字叫做SpringbootNettyWebSocket1、添加依賴2、在application.properties文件修改埠號一句話:server.port=80813、新建service包,創建NettyServer類這個類的代碼是模板代碼,最核心的就是ch.pipeline
  • netty writeAndFlush源碼分析
    writeAndFlush,顧名思義,就是寫入(發送緩衝區)並且刷新,熟悉netty編碼的同學對這個方法一定不會感到陌生, 這方法既能將數據寫到發送緩存中
  • Netty服務端是如何一步一步啟動的?
    // See https://github.com/netty/netty/issues/2586                    promise.executor = channel.eventLoop();                }                doBind0(regFuture
  • pipeline什麼意思
    pipeline什麼意思pipe,管子、管道,管中有液體或氣體,能夠從一個地方流到另一個地方。你知道鍵盤上的這個符號:| 英文就是pipe嗎?linespipeline,一根非常長的管道,管中有液體或氣體,可以傳輸很遠的距離,而且這根管道通常鋪設在地下。
  • sklearn 機器學習 Pipeline 模板
    最終完整Pipeline使用 sklearn 的 pipeline 搭建機器學習的流程本文例子為 [Kesci] 新人賽 · 員工滿意度預測參考 [Hands On ML] 2. 一個完整的機器學習項目(加州房價預測)1.
  • Coal pipeline reduces costs and environmental
    km pipeline built by Huayu Coal Chemicals is the longest in Asia for coal transportation.JIAO ZHAOZHAO/FOR CHINA DAILY The 8.4-kilometer pipeline built by Huayu Coal Chemicals is the longest in Asia for coal transportation.
  • Netty 內存模型分析(一)ByteBuf總覽
    本文開始,將主要圍繞netty相關知識展開,力求從宏觀上把握整個內存結構。
  • 提供基於transformer的pipeline、準確率達SOTA
    pipeline 也更加輕鬆;與 NLP 生態系統的其他部分有許多新的和改進的集成。為了實現最流暢的更新過程,項目開發者建議用戶在一個新的虛擬環境中啟動:在具體操作上,用戶可以選擇自己的作業系統、包管理器、硬體、配置、訓練 pipeline,以及選擇 pipeline 時可以選擇側重效率性或者準確性。
  • Major oil pipeline to help Niger develop
    The 1,950-kilometer Niger-Benin oil pipeline, constructed by the China National Petroleum Corporation
  • Obama calls Canadian PM over rejection of pipeline
    President Barack Obama on Wednesday called Canadian Prime Minister Stephen Harper to personally convey his administration's decision to reject the proposed Keystone oil pipeline between their countries
  • 用 Scikit-learn Pipeline 創建機器學習流程
    下面我們將用 scikit-learn pipeline 進行這些轉換。在構建 pipeline 之前,我們先將訓練數據分為訓練和測試集,以便評估模型性能。Loan_Status', axis=1)y = train['Loan_Status']from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) 建立 pipeline