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

資訊專欄INFORMATION COLUMN

Netty-ChannelHandler-ChannelPipeline

warkiz / 604人閱讀

摘要:只有在詳盡的測試之后才應設置為這值使用的默認采樣率檢測并報告任何發(fā)現(xiàn)的泄漏。這是默認級別,適合絕大部分情況使用默認的采樣率,報告所發(fā)現(xiàn)的任何的泄漏以及對應的消息被訪問的位置類似于但是其將會對每次對消息的訪問都進行采樣。

ChannelHandler Channel生命周期
狀態(tài) 描述
ChannelUnregistered Channel已經(jīng)被創(chuàng)建,但未注冊到EventLoop
ChannelRegistered Channel已經(jīng)被注冊到了EventLoop
ChannelActive Channel處于活動狀態(tài)(已經(jīng)連接到它的遠程節(jié)點)?,F(xiàn)在Channel可以接受和發(fā)送數(shù)據(jù)
ChannelInActive Channel沒有連接到遠程節(jié)點

一般Channel的生命周期順序ChannelRegistered -> ChannelActive -> ChannelInactive -> ChannelUnregistered。

當Channel的狀態(tài)發(fā)生變化時,將會生成對應的事件。與此同時,這些事件會被轉(zhuǎn)發(fā)給ChannelPipeline中的ChannelHandler。

ChannelHandler生命周期

ChannelHandler定義的生命周期操作,在ChannelHandler被添加到ChannelPipeline中或者被從ChannelPipeline中移除時會調(diào)用這些方法。這些方法中都可以接受一個ChannelHandlerContext參數(shù)。

類型 描述
handlerAdded 當把ChannelHandler添加到ChannelPipeline中時被調(diào)用
handlerRemoved 當從ChannelHandler在ChannelPipeline移除時調(diào)用
exceptionCaught 當處理過程中在ChannelPipeline中有錯誤產(chǎn)生時被調(diào)用

Netty中定義了下面兩個重要的ChannelHandler接口:

ChannelInboundHandler——處理入站數(shù)據(jù)以及各種狀態(tài)變化

CHannelOutboundHandler——處理出站數(shù)據(jù)并且允許攔截所有的操作

ChanneInboundHandler接口
類型 描述
channelRegistered 當Channel已經(jīng)注冊到它的EventLoop并且能夠處理I/O時被調(diào)用
channelUnregistered 當Channel從它的EventLoop注銷并且無法處理任何I/O時被調(diào)用
channelActive 當Channel處于活動狀態(tài)時被調(diào)用;Channel已經(jīng)連接/綁定并且已經(jīng)就緒
channelInactive 當Channel離開活動狀態(tài)并且不再連接它的遠程節(jié)點時被調(diào)用
channelReadComplete 當Channel的一個讀操作完成時被調(diào)用
channelRead 當從Channel讀取數(shù)據(jù)時被調(diào)用
channelWritabilityChanged 當Channel的可寫狀態(tài)發(fā)生改變時被調(diào)用。用戶可以確保寫操作不會完成的太快(以避免發(fā)生OutOfMemoryError)或者可以在Channel變?yōu)樵俅慰蓪憰r恢復寫入。Channel的isWriteable()方法可以來檢測Channel的可寫性。與可寫性相關的閥值可以通過Channel.config().setWriteHighWaterMark()和Channel.config().setWriteLowWaterMark()方法來設置
userEventTriggered 當ChannelInboundHandler.fireUserEventTriggered()方法被調(diào)用時被調(diào)用。

當某個ChannelInboundHandler的實現(xiàn)重寫channelRead()方法時,它將負責顯示地釋放與池化的ByteBuf實例相關的內(nèi)存。ReferenceCountUtil.release()

Netty會使用WARN級別的日志消息記錄未釋放的資源,但是以這種方式管理資源可能非常繁瑣,Netty采用SimpleChannelInboundHandler來簡化這種操作。

ChannelOutboundHandler接口

出站操作和數(shù)據(jù)將由ChannelOutboundHandler處理。它的方法將被Channel、ChannelPipeline以及ChannelHandlerContext調(diào)用。

ChannelOutboundHandler可以按需推遲操作或者事件。

類型 描述
bind(ChannelHandlerContext, SockertAddress, ChannelPromise) 當請求將Channel綁定到本地地址時被調(diào)用
connect(ChannelHandlerContext, SocketAddress, SockertAddress, ChannelPromise) 當請求將Channel連接到遠程節(jié)點時被調(diào)用
disconnect(ChannelHandlerContext, ChannelPromise) 當請求將Channel從遠程節(jié)點斷開時被調(diào)用
close(ChannelHandlerContext, ChannelPromise) 當請求關閉Channel時被調(diào)用
deregister(ChannelHandlerContext, ChannelPromise) 當請求將Channel叢它的EventLoop注銷時被調(diào)用
read(ChannelHandlerContext) 當請求從Channel讀取更多的數(shù)據(jù)時被調(diào)用
flush(ChannelHandlerContext) 當請求通過Channel將入隊數(shù)據(jù)沖刷到遠程節(jié)點時被調(diào)用
write(ChannelHandlerContext, Object, ChannelPromise) 當請求通過Channel將數(shù)據(jù)寫到遠程節(jié)點時被調(diào)用

ChannelOutboundHandler中的大部分方法都需要一個ChannelPromise參數(shù),方便在操作完成時獲取通知。ChannelPromise時ChannelFuture的一個子類,定義了一些可寫方法,如setSuccess()和setFailure()方法

ChannelHandler適配器

ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter兩個適配器分別提供了ChannelInboundHandler和ChannelOutboundHandler的基本實現(xiàn)。通過擴展抽象類ChannelHandlerAdapter,它們獲得了它們共同的超接口ChannelHandler的方法。

ChannelHandlerAdapter提供了isSharable(),如果其對應的實現(xiàn)被注解標注為Sharable,這方法將返回true,表示它可以被添加到多個ChannelPipeline。

ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter中的方法體調(diào)用了其相關聯(lián)的ChannelHandlerContext上的等效方法,從而將事件轉(zhuǎn)發(fā)到了ChannelPipeline中的下一個ChannelHandler中。

資源管理

Netty目前定義了4種泄露檢測級別:

級別 描述
DISABLED 禁用泄漏檢測。只有在詳盡的測試之后才應設置為這值
SIMPLE 使用1%的默認采樣率檢測并報告任何發(fā)現(xiàn)的泄漏。這是默認級別,適合絕大部分情況
ADVANCED 使用默認的采樣率,報告所發(fā)現(xiàn)的任何的泄漏以及對應的消息被訪問的位置
PARANOID 類似于ADVANCED,但是其將會對每次(對消息的)訪問都進行采樣。會對性能有很大影響,只能在調(diào)試階段使用

java -Dio.netty.leakDetectionLevel=ADVANCED

如果一個消息被消費或者丟棄了,并且沒有傳遞給ChannelPipeline中的下一個ChannelOutboundHandler,那么用戶就有責任調(diào)用ReferenceCountUtil.release()。如果消息到達了實際的傳輸層,那么當它被寫入時或者Channel關閉時,都將被自動釋放。

ChannelPipeline接口

每一個新創(chuàng)建的Channel都將會被分配一個新的ChannelPipeline。這項關聯(lián)是永久性的;Channel既不能附加另外一個ChannelPipeline,也不能分離當前的。

根據(jù)事件的起源,事件將會被ChannelInboundHandler或者ChannelOutboundHandler處理。隨后,會調(diào)用ChannelHandlerContext實現(xiàn),它將被轉(zhuǎn)發(fā)給同一超類型的下一個ChannelHandler。

ChannelHandlerContext使ChannelHandler能夠和它的ChannelPipeline以及其他的ChannelHandler交互。ChannelHandler可以通知其所屬的ChannelPipeline中的下一個ChannelHandler,甚至可以動態(tài)修改它所屬的ChannelPipeline。

在ChannelPipeline傳播事件時,它會測試ChannelPipeline中的下一個ChannelHandler的類型是否和事件的運動方向相匹配。如果不匹配,ChannelPipeline將跳過該ChannelHandler并前進到下一個,直到它找到和該事件所期望的方向相匹配的為止。(ChannelHandler可以同時實現(xiàn)ChannelInboundHandler和ChannelOutboundHandler接口

修改ChannelPipeline

ChannelHandler可以通過添加、刪除或者替換其他的ChannelHandler來實時地修改ChannelPipeline的布局。

名稱 描述
addFirst(),addBefore(),addAfter(),addLast() 將一個ChannelHandler添加到ChannelPipeline
remove() 將一個ChannelHandler從ChannelPipeline中移除
replace() 將ChannelPipeline中的一個ChannelHandler替換為另一個ChannelHandler
get() 通過類型或者名稱返回ChannelHandler
context() 返回和ChannelHandler綁定的ChannelHandlerContext
names() 返回ChannelPipeline中所有的ChannelHandle的名稱
觸發(fā)事件

ChannelPipeline的API公開了用于調(diào)用入站和出站操作的附加方法,用于通知ChannelInboundHandler在ChannelPipeline中所發(fā)生的事件。

名稱 描述
fireChannelRegistered 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelRegistered(ChannelHandlerContext)方法
fireChannelUnregistered 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelUnregistered(ChannelHandlerContext)方法
fireChannelActive 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelActive(ChannelHandlerContext)
fireChannelInActive 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelInactive(ChannelHandlerContext)方法
fireExceptionCaught 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的exceptionCaught(ChannelHandlertext, Throwable)方法
fireUserEventTriggerd 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的userEventTriggered(ChannelHandlertext, Object)方法
fireChannelRead 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelRead(ChannelHandlertext, Object msg)方法
fireChannelReadComplete 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelReadComplete(ChannelHandlertext)方法
fireChannelWritabilityChanged 調(diào)用ChannelPipeline中下一個ChannelInboundHandler的channelWritabilityChanged(ChannelHandlertext)方法

ChannelPipelin的出站操作

名稱 描述
bind 將Channel綁定到一個本地地址,將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的bind(ChannelHandlerContext,Socket,ChannelPromise)方法
connect 將Channel連接到一個遠程地址,這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的connect(ChannelHandlerContext,Socket,ChannelPromise)方法
disconnect 將Channel斷開連接。這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的disconnect(ChannelHandlerContext,Socket,ChannelPromise)方法
close 將Channel關閉。這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的close(ChannelHandlerContext,ChannelPromise)方法
deregister 將Channel從它先前分配的EventExecutor(即EventLoop)中注銷,這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的deregister(ChannelHandlerContext,ChannelPromise)方法
flush 沖刷Channel所有掛起的寫入。這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的flush(ChannelHandlerContext)方法
write 將消息寫入Channel。這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的write(ChannelContext,Object msg,ChannelPromise)方法。這并不會將消息寫入底層的Socket,而只會將它放入到隊列中。要將它寫入到Socket,需要調(diào)用flush或者writeAndFlush方法
writeAndFlush 先調(diào)用write再調(diào)用flush的便利方法
read 請求從Channel中讀取更多的數(shù)據(jù)。這將調(diào)用ChannelPipeline中的下一個ChannelOutboundHandler的read(ChannelHandlerContext)方法

ChannelPipeline保存了與Channel相關聯(lián)的ChannelHandler

ChannelPipeline可以根據(jù)需要,通過添加或者刪除ChannelHandler來動態(tài)修改

ChannelPipeline有著豐富的API調(diào)用,以響應入站和出站事件

ChanneHandlerContext接口

ChannelHandlerContext代表了ChannelHandler和ChannelPipeline之間的關聯(lián)。每當有ChannelHandler添加到ChannelPipeline中時,都會創(chuàng)建ChannelHandlerContext。ChannelHandlerContext的主要功能是管理它所關聯(lián)的ChannelHandler和在同一個ChannelPipeline中的其他ChannelHandler之間的交互。

ChannelHandlerContext有很多方法,其中一些方法也存在于Channel和ChannelPipeline本身上。如果調(diào)用Channel或者ChannelPipeline上的方法,它們將沿著整個ChannelPipeline進行傳播,而調(diào)用ChannelHandlerContext上的相同方法,則從當前所關聯(lián)的ChannelHandler開始,并且只會傳播給位于該ChannelHandler的下一個能夠處理該事件的ChannelHandler。

方法名稱 描述
alloc 返回和這個實例相關的Channel所配置的ByteBufAllocator
bind 綁定到給定的SocketAddress,并返回ChannelFuture
channel 返回綁定到這個實例的Channel
close 關閉Channel,并返回ChannelFuture
connect 連接給定的SocketAddress,并返回ChannelFuture
deregister 從之前分配的EventExecutor注銷,并返回ChannelFuture
disconnect 從遠程節(jié)點斷開,并返回ChannelFuture
executor 返回調(diào)度事件的EventExecutor
fireChannelActive 觸發(fā)對下一個ChannelInboundHandler上的channelActive()方法的調(diào)用
fireChannelInActive 觸發(fā)下一個ChannelInboundHandler上的channelInActive()方法
fireChannelRead 觸發(fā)對下一個ChannelInboundHandler上的channelRead()方法
fireChannelReadComplete 觸發(fā)對下一個ChannelInboundHandler上的channelReadComplete()方法的調(diào)用
fireChannelRegistered 觸發(fā)對下一個ChanneInboundHandler上的fireChannelRegistered方法的調(diào)用
fireChannelUnregistered 觸發(fā)對下一個ChannelInboundHandler上的fireChannelUnregistered方法的調(diào)用
fireChannelWritabilityChanged 觸發(fā)對下一個ChannelInboundHandler上的fireChannelWritabilityChanged方法的調(diào)用
fireExceptionCaught 觸發(fā)對下一個ChannelInboundHandler上的fireExceptionCaught方法的調(diào)用
fireUserEventTriggered 觸發(fā)對下一個ChannelInboundHandler上的fireUserEventTriggered(Object evt)方法的調(diào)用
handler 返回綁定到這個實例的ChannelHandler
isRemoved 如果從關聯(lián)的ChannelHandler已經(jīng)被從ChannelPipeline中移除則返回true
name 返回這個實例的唯一名稱
pipeline 返回這個實例相關聯(lián)的ChannelPipeline
read 將數(shù)據(jù)從Channel讀取到第一個入站緩沖區(qū);如果讀取成功則觸發(fā)一個channelRead事件,并(在最后一個消息被被讀取完成后)通知ChannelInboundHandler的channelReadComplete(ChannelHandlerContext)方法
write 通過這個實例寫入消息并經(jīng)過ChannelPipeline
writeAndFlush 通過這個實例寫入并沖刷消息并經(jīng)過ChannelPipeline

ChannelHanlderContext和ChannelHandler之間的關聯(lián)是永遠不會改變的,所以緩存對它的引用是安全的

ChannelHandlerContext上的方法產(chǎn)生的事件流更短,應該利用這個特性盡可能的獲得最大的性能

使用ChannelHandlerContext

讓ChannePipeline從某個特定的點開始傳播的原因:

為了減少將事件傳經(jīng)對它不感興趣的ChannelHandler所帶來的開銷

為了減少將事件傳經(jīng)那些可能會對它感興趣的ChannelHandler

要想調(diào)用從某個特定的ChannelHandler開始處理的過程,必須獲取到在(ChannelPipeline)該ChannelHandler之前的hannelHandler所關聯(lián)的ChannelHandlerContext。這個ChannelHandlerContext將調(diào)用和它所關聯(lián)的ChannelHandler之后的ChannelHandler。

一個ChannelHandler可以從屬于多個ChannelPipeline,所以它(同一個ChannelHandler)也可以綁定到多個ChannelHandlerContext實例。用于這種用法的ChannelHandler必須使用@Shareable注解標注;否則將它添加到多個ChannelPipeline時將會觸發(fā)異常。顯而易見,為了安全地被用于多個并發(fā)的Channel(即連接),這樣的ChannelHandler必須是線程安全的。

為何要共享一個ChannelHandler?
在多個ChannelPipeline中安裝同一個ChannelHandler的一個常見原因是用于收集跨越多個Channel的統(tǒng)計信息。

異常處理 處理入站異常

如果在處理入站事件的過程中有異常被拋出,那么它將從它在ChannelInboundHandler里被觸發(fā)的那一點開始流經(jīng)ChannelPipeline。如果想要處理這種類型的入站異常,必須在你的ChannelInboundHandler中重寫exceptionCaught(ChannelHandlerContext,Throwable)

異常會按照入站方向流動,所以一般處理異常的邏輯通常都在最后一個ChannelInboundHandler中實現(xiàn)

ChannelHandler.exceptionCaught()的默認實現(xiàn)是簡單的將當前異常轉(zhuǎn)發(fā)給ChannelPipeline中的下一個ChannelHandler

如果異常到達了ChannelPipeline的尾端,它將會被記錄為未被處理

要想定義自定義的處理邏輯,你需要重寫exceptionCaught()方法,然后決定是否將該異常傳播出去。

處理出站異常

用于處理出站操作中的正常完成以及異常的選項,都基于以下的通知機制:

每個出站操作都返回一個ChannelFuture。注冊到ChannelFuture的ChannelFutureListener將在操作完成時被通知該操作是成功了還是出錯了。

幾乎所有的ChannelOutboundHandler上的方法都會傳入一個ChannelPromise的實例。作為ChannelFuture的子類,ChannelPromise也可以被分配用于異步通知的監(jiān)聽器。

添加ChannelFuturListener只需要調(diào)用ChannelFuture實例上的addListener(ChannelFutureListener)方法,并且有兩種不同的方式去實現(xiàn)。第一種是調(diào)用出站操作(如write方法)所返回的ChanneFuture上的addListener方法;第二種方式是將ChannelFutureListener添加到即將作為參數(shù)傳遞給ChannelOutboundHandler的方法的ChannelPromise

通過調(diào)用ChannelPromise上的setSuccess和setFailure方法,可以使一個操作的狀態(tài)在ChannelHandler的方法返回給其調(diào)用者時即刻被感知到。

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

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

相關文章

  • 使用PHPWord合并Word文檔,在文檔指定頁插入另一個文檔的內(nèi)容

    摘要:提示不支持文件的讀取有一個客戶有這樣的需求,需要在里使用組件,把一個文檔的內(nèi)容,插入另一個文檔的指定頁內(nèi)。由于兩個文檔的內(nèi)容都不是固定的,所以不能使用的功能。當讀取到指定的分頁符之后,再讀取的內(nèi)容,跟著前面的內(nèi)容插入,最后保存新的文檔。 提示:不支持.doc文件的讀取有一個客戶有這樣的需求,需要在ThinkPHP里使用PHPWord組件,把一個文檔(DOC1)的內(nèi)容,插入另一個文檔(D...

    RobinTang 評論0 收藏0
  • Spring Cloud 參考文檔(Hystrix超時和Ribbon客戶端)

    摘要:要運行儀表板,請使用注解主類,然后訪問并將儀表板指向客戶端應用程序中的單個實例的端點。連接到使用的端點時,必須信任服務器使用的證書,如果證書不受信任,則必須將證書導入,以便儀表板成功連接到流端點。 Hystrix超時和Ribbon客戶端 使用包裝Ribbon客戶端的Hystrix命令時,要確保將Hystrix超時配置為長于配置的Ribbon超時,包括可能進行的任何可能的重試,例如,如果...

    pf_miles 評論0 收藏0
  • CSS學習部分知識點記錄

    摘要:整理一些最近幾天學習的一些知識點,好記性不如爛筆頭,寫下來敲一遍代碼為自己寫哈。這點就不獻丑了,也是才學習。脫離文檔流的元素,其高度不再計算到高度內(nèi)。 整理一些最近幾天學習CSS的一些知識點,好記性不如爛筆頭,寫下來敲一遍代碼為自己寫哈。 左右兩欄或三欄布局1、常用方法是給div加float浮動方式實現(xiàn),加了浮動后div不再獨占一行。 2、還有就是position屬性實現(xiàn),通過posi...

    maxmin 評論0 收藏0
  • CSS學習部分知識點記錄

    摘要:整理一些最近幾天學習的一些知識點,好記性不如爛筆頭,寫下來敲一遍代碼為自己寫哈。這點就不獻丑了,也是才學習。脫離文檔流的元素,其高度不再計算到高度內(nèi)。 整理一些最近幾天學習CSS的一些知識點,好記性不如爛筆頭,寫下來敲一遍代碼為自己寫哈。 左右兩欄或三欄布局1、常用方法是給div加float浮動方式實現(xiàn),加了浮動后div不再獨占一行。 2、還有就是position屬性實現(xiàn),通過posi...

    lookSomeone 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<