成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Netty 框架總結(jié)「ChannelHandler 及 EventLoop」

VioletJack / 1920人閱讀

摘要:隨著狀態(tài)發(fā)生變化,相應(yīng)的產(chǎn)生。這些被轉(zhuǎn)發(fā)到中的來采取相應(yīng)的操作。當(dāng)收到數(shù)據(jù)或相關(guān)的狀態(tài)改變時(shí),這些方法被調(diào)用,這些方法和的生命周期密切相關(guān)。主要由一系列組成的。采用的線程模型,在同一個(gè)線程的中處理所有發(fā)生的事。

「博客搬家」  原地址: 簡(jiǎn)書  原發(fā)表時(shí)間: 2017-05-05

學(xué)習(xí)了一段時(shí)間的 Netty,將重點(diǎn)與學(xué)習(xí)心得總結(jié)如下,本文主要總結(jié)ChannelHandler 及 EventLoop 的知識(shí)點(diǎn)和基本用法,本文章節(jié)排序參照《Netty in Action》的章節(jié)排序。

以下內(nèi)容主要參考「并發(fā)編程網(wǎng)」的 《Netty in Action》中文版 以及《Netty in Action》原版圖書,輔助參考 Essential Netty in Action 《Netty 實(shí)戰(zhàn)(精髓)》 以及 Netty 官網(wǎng)的 Netty 4.1 JavaDoc 。
6. ChannelHandler 和 ChannelPipeline

一個(gè) Channel 正常的生命周期如下圖所示。隨著狀態(tài)發(fā)生變化,相應(yīng)的 event 產(chǎn)生。這些 event 被轉(zhuǎn)發(fā)到 ChannelPipeline 中的 ChannelHandler 來采取相應(yīng)的操作。

6.1 ChannelHandler

ChannelHandler 有兩個(gè)重要的子接口:

「ChannelInboundHandler」處理輸入數(shù)據(jù)和所有類型的狀態(tài)變化

「ChannelOutboundHandler」處理輸出數(shù)據(jù),可以攔截所有操作

6.1.1 ChannelInboundHandler

下表列出接口 ChannelInboundHandler 的方法。當(dāng)收到數(shù)據(jù)或相關(guān) Channel 的狀態(tài)改變時(shí),這些方法被調(diào)用,這些方法和Channel的生命周期密切相關(guān)。

方法 描述
channelRegistered 當(dāng)一個(gè)Channel注冊(cè)到EventLoop上,可以處理I/O時(shí)被調(diào)用
channelUnregistered 當(dāng)一個(gè)Channel從它的EventLoop上解除注冊(cè),不再處理I/O時(shí)被調(diào)用
channelActive 當(dāng)Channel變成活躍狀態(tài)時(shí)被調(diào)用;Channel是連接/綁定、就緒的
channelInactive 當(dāng)Channel離開活躍狀態(tài),不再連接到某個(gè)遠(yuǎn)端時(shí)被調(diào)用
channelReadComplete 當(dāng)Channel上的某個(gè)讀操作完成時(shí)被調(diào)用
channelRead 當(dāng)從Channel中讀數(shù)據(jù)時(shí)被調(diào)用
6.1.2 ChannelOutboundHandler

輸出的操作和數(shù)據(jù)由 ChannelOutBoundHandler 處理。它的方法可以被 Channel,ChannelPipeline 和 ChannelHandlerContext 調(diào)用,子接口 ChannelOutboundHandler 的主要方法如下:

方法 描述
bind(ChannelHandlerContext,SocketAddress,ChannelPromise) 請(qǐng)求綁定 Channel 到一個(gè)本地地址
connect(ChannelHandlerContext, SocketAddress,SocketAddress,ChannelPromise) 請(qǐng)求連接 Channel 到遠(yuǎn)端
disconnect(ChannelHandlerContext, ChannelPromise) 請(qǐng)求從遠(yuǎn)端斷開 Channel
close(ChannelHandlerContext,ChannelPromise) 請(qǐng)求關(guān)閉 Channel
deregister(ChannelHandlerContext, ChannelPromise) 請(qǐng)求 Channel 從它的 EventLoop 上解除注冊(cè)
read(ChannelHandlerContext) 請(qǐng)求從 Channel 中讀更多的數(shù)據(jù)
flush(ChannelHandlerContext) 請(qǐng)求通過 Channel 刷隊(duì)列數(shù)據(jù)到遠(yuǎn)端
write(ChannelHandlerContext,Object, ChannelPromise) 請(qǐng)求通過 Channel 寫數(shù)據(jù)到遠(yuǎn)端
6.1.3 ChannelHandler 適配器類

ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 這兩個(gè)適配器類分別提供了 ChannelInboundHandler 和 ChannelOutboundHandler 的基本實(shí)現(xiàn),它們繼承了共同的父接口 ChannelHandler 的方法,擴(kuò)展了抽象類 ChannelHandlerAdapter。

ChannelHandlerAdapter 提供了工具方法 isSharable()。如果類實(shí)現(xiàn)帶 @Sharable 注解,那么這個(gè)方法就會(huì)返回 true,意味著這個(gè)對(duì)象可以被添加到多個(gè) ChannelPipeline 中。

ChannelInboundHandlerAdapter 和 ChannelOutboundHandlerAdapter 中的方法調(diào)用相關(guān) ChannelHandlerContext 中的等效方法,因此將事件轉(zhuǎn)發(fā)到管道中的下一個(gè)ChannelHandler。

6.1.4 ChannelFuture 和 ChannelPromise

ChannelPromise 是 ChannelFuture 的子接口

而 ChannelFuture 是不可變對(duì)象

ChannelPromise 定義了可寫的方法,比如 setSuccess(), setFailure()

6.1.5 釋放資源

1. 輸入方向「Inbound」
當(dāng)一個(gè) ChannelInboundHandler 實(shí)現(xiàn)類重寫 channelRead() 方法時(shí),它要負(fù)責(zé)釋放 ByteBuf 相關(guān)的內(nèi)存??墒褂?Netty 提供的工具方法:

    ReferenceCountUtil.release(「ByteBuf 的對(duì)象」)

更簡(jiǎn)單的,可使用子類 SimpleChannelInboundHandler ,一條消息在被 ChannelRead0() 讀取后,會(huì)被自動(dòng)釋放資源,此時(shí)任何對(duì)消息的引用都會(huì)變成無效,所以不能保存這些引用待后來使用。

2. 輸出方向「Outbound」
在輸出方向,如果處理一個(gè) write() 操作并且丟棄一條消息(沒有寫入 Channel),就應(yīng)該負(fù)責(zé)釋放這條消息。

@ChannelHandler.Sharable public 
class DiscardOutboundHandler extends ChannelOutboundHandlerAdapter {

@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
    ReferenceCountUtil.release(msg);  //使用 ReferenceCountUtil.release(...) 釋放資源
    promise.setSuccess();  //通知 ChannelPromise 數(shù)據(jù)已經(jīng)被處理
}

如果一個(gè)消息被“消費(fèi)”或者丟棄,沒有送到 ChannelPipeline 中的下一個(gè) ChannelOutboundHandler,用戶就要負(fù)責(zé)調(diào)用 ReferenceCountUtil.release()。如果消息到達(dá)了真正的傳輸層,在它被寫到 Socket 中或者 Channel 關(guān)閉時(shí),會(huì)被自動(dòng)釋放,用戶不用管。

6.2 ChannelPipeline 接口

每個(gè)新創(chuàng)建的 Channel 都會(huì)分配一個(gè)新的 ChannelPipeline,Channel 不可以更換或解除當(dāng)前的 ChannelPipeline,在 Netty 組件的整個(gè)生命周期中這個(gè)關(guān)系是固定的。

一個(gè) ChannelPipeline 可看成是一串 ChannelHandler 實(shí)例,攔截穿過 Channel 的輸入輸出 event。

根據(jù)來源,一個(gè) event 可以被一個(gè) ChannelInboundHandler 或 ChannelOutboundHandler 處理。接下來,通過調(diào)用 ChannelHandlerContext 的方法,event 會(huì)被轉(zhuǎn)發(fā)到下一個(gè)同類型的 handler。

6.2.1 ChannelHandlerContext

通過 ChannelHandlerContext,一個(gè) handler 可以通知 ChannelPipeline 中的下一個(gè)ChannelHandler,甚至動(dòng)態(tài)改動(dòng)下一個(gè)ChannelHandler 所屬的 ChannelPipeline。

ChannelPipeline 主要由一系列 ChannelHandler 組成的。ChannelPipeline 提供在 ChannelPipeline 中傳送 event 的方法。

ChannelHandlerContext 的一些方法和其他類(Channel 和 ChannelPipeline)的方法名字相似,但是 ChannelHandlerContext 的方法采用了更短的 event 傳遞路程。我們應(yīng)該盡可能利用這一點(diǎn)來實(shí)現(xiàn)最好的性能。

如果你在 Channel 或者 ChannelPipeline 實(shí)例上調(diào)用這些方法,它們的調(diào)用會(huì)穿過整個(gè) pipeline。而在 ChannelHandlerContext 上調(diào)用的同樣的方法,僅僅從當(dāng)前 ChannelHandler 開始,走到 pipeline 中下一個(gè)可以處理這個(gè) event 的 ChannelHandler。

「本節(jié)參考」 第六章 ChannelHandler 和 ChannelPipeline

7. EventLoop 和 EventLoopGroup 7.1 Java 基本的線程池模式

從池中空閑的線程中選出一個(gè),分配一個(gè)提交的task「一個(gè)Runnable的實(shí)現(xiàn)」

當(dāng)task完成,線程返回池中,等待復(fù)用「下一次task分配」

7.2 EventLoop「事件循環(huán)」

EventLoop 始終由一個(gè)線程驅(qū)動(dòng)

一個(gè) EventLoop 可以被指派來服務(wù)多個(gè) Channel

一個(gè) Channel 只擁有一個(gè) EventLoop

task (Runnable或Callable) 可以直接提交到 EventLoop 實(shí)現(xiàn)即刻或者延后執(zhí)行。根據(jù)配置和可用的CPU核,可以創(chuàng)建多個(gè) EventLoop 來優(yōu)化資源利用。

一個(gè) event 的本質(zhì)決定了它將如何被處理;它可能從網(wǎng)絡(luò)協(xié)議棧傳送數(shù)據(jù)到你的應(yīng)用,或者反過來,或者做一些完全不一樣的事情。但是 event 處理邏輯必須足夠通用和靈活,來對(duì)付所有可能的情況。

所以,在 Netty 4,所有的 I/O 操作和 event 都是由分配給 EventLoop 的那一個(gè) Thread 來處理的。Netty 4 采用的線程模型,在同一個(gè)線程的 EventLoop 中處理所有發(fā)生的事。

7.3 EventLoopGroup

EventLoopGroup 負(fù)責(zé)分配 EventLoop 到新創(chuàng)建的 Channel

異步實(shí)現(xiàn)只用了很少 EventLoop,這幾個(gè) EventLoop 被所有 Channel 共享

一但 Channel 被指派了一個(gè) EventLoop,在它的整個(gè)生命周期過程中,都會(huì)用這個(gè) EventLoop

為 Channel 的 I/O 和 event 提供服務(wù)的 EventLoop 都包含在一個(gè) EventLoopGroup 中。EventLoop 創(chuàng)建和分配的方式根據(jù)傳輸實(shí)現(xiàn)的不同而有所不同。

異步實(shí)現(xiàn)只用了很少幾個(gè) EventLoop(和它們關(guān)聯(lián)的線程),在目前 Netty 的模型中,這幾個(gè) EventLoop 被所有 Channel 共享。這讓很多 Channel 被最少數(shù)量的線程服務(wù),而不是每個(gè) Channel 分配一個(gè)線程。

EventLoopGroup 負(fù)責(zé)分配一個(gè) EventLoop 到每個(gè)新創(chuàng)建的 Channel。在目前的實(shí)現(xiàn)中,采用循環(huán) (round-robin) 策略可以滿足一個(gè)平衡的分配,同一個(gè) Eventloop 還可能會(huì)被分配到多個(gè) Channel。

「本節(jié)參考」 第七章 EventLoop和線程模型

參考鏈接

《Netty in Action》中文版

Essential Netty in Action 《Netty 實(shí)戰(zhàn)(精髓)》

Netty 4.1 JavaDoc

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68250.html

相關(guān)文章

  • netty實(shí)戰(zhàn)》閱讀筆記(1)——Netty 的概念體系結(jié)構(gòu)

    摘要:它使用了事件通知以確定在一組非阻塞套接字中有哪些已經(jīng)就緒能夠進(jìn)行相關(guān)的操作。目前,可以把看作是傳入入站或者傳出出站數(shù)據(jù)的載體。出站事件是未來將會(huì)觸發(fā)的某個(gè)動(dòng)作的操作結(jié)果,這些動(dòng)作包括打開或者關(guān)閉到遠(yuǎn)程節(jié)點(diǎn)的連接將數(shù)據(jù)寫到或者沖刷到套接字。 netty的概念 定義 Netty 是一款異步的事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架,支持快速地開發(fā)可維護(hù)的高性能的面向協(xié)議的服務(wù)器和客戶端。我們可以很簡(jiǎn)單的...

    solocoder 評(píng)論0 收藏0
  • Netty組件入門學(xué)習(xí)

    摘要:可以用來接收入站事件和數(shù)據(jù),隨后使用應(yīng)用程序的業(yè)務(wù)邏輯進(jìn)行處理。因?yàn)橛脩舨⒉皇顷P(guān)心所有的事件,因此提供了抽象類和。抽象類最常見的一個(gè)情況,你的應(yīng)用程序會(huì)利用一個(gè)來接受解碼消息,并對(duì)該數(shù)據(jù)應(yīng)用業(yè)務(wù)邏輯。 Channel、EventLoop和ChannelFuture Channel——Socket; EventLoop——控制流、多線程處理、并發(fā) ChannelFuture異步通知 ...

    qpal 評(píng)論0 收藏0
  • Netty學(xué)習(xí)筆記(二)

    摘要:支持很多協(xié)議,并且提供用于數(shù)據(jù)處理的容器。我們已經(jīng)知道由特定事件觸發(fā)??蓪S糜趲缀跛械膭?dòng)作,包括將一個(gè)對(duì)象轉(zhuǎn)為字節(jié)或相反,執(zhí)行過程中拋出的異常處理。提供了一個(gè)容器給鏈并提供了一個(gè)用于管理沿著鏈入站和出站事件的流動(dòng)。子類通過進(jìn)行注冊(cè)。 前兩天寫了一點(diǎn)netty相關(guān)的知識(shí),并寫了一個(gè)demo,但是對(duì)其原理還是沒有深入,今天我們來做一次研究吧 首先讓我們來認(rèn)識(shí)一下netty的幾個(gè)核心人物吧...

    0x584a 評(píng)論0 收藏0
  • Netty4.x 源碼實(shí)戰(zhàn)系列(四):Pipeline全剖析

    摘要:在上一篇源碼實(shí)戰(zhàn)系列三全剖析中,我們?cè)敿?xì)分析了的初始化過程,并得出了如下結(jié)論在中,每一個(gè)都有一個(gè)對(duì)象,并且其內(nèi)部本質(zhì)上就是一個(gè)雙向鏈表本篇我們將深入源碼內(nèi)部,對(duì)其一探究竟,給大家一個(gè)全方位解析。 在上一篇《Netty4.x 源碼實(shí)戰(zhàn)系列(三):NioServerSocketChannel全剖析》中,我們?cè)敿?xì)分析了NioServerSocketChannel的初始化過程,并得出了如下結(jié)論...

    13651657101 評(píng)論0 收藏0
  • ChannelPipeline 和 ChannelHandler

    摘要:概念與概念一致用以連接設(shè)備文件等的紐帶例如將網(wǎng)絡(luò)的讀寫客戶端發(fā)起連接主動(dòng)關(guān)閉連接鏈路關(guān)閉獲取通信雙方的網(wǎng)絡(luò)地址等的類型主要有兩種非阻塞以及阻塞數(shù)據(jù)傳輸類型有兩種按事件消息傳遞以及按字節(jié)傳遞適用方類型也有兩種服務(wù)器以及客戶端還有一些根據(jù)傳輸協(xié) ChannelHandler Channel Channel 概念與 java.nio.channel 概念一致, 用以連接IO設(shè)備 (socke...

    William_Sang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<