Netty檢測(cè)空閑連接以及超時(shí)

2018-08-08 10:42 更新

為了能夠及時(shí)的將資源釋放出來(lái),我們會(huì)檢測(cè)空閑連接和超時(shí)。常見(jiàn)的方法是通過(guò)發(fā)送信息來(lái)測(cè)試一個(gè)不活躍的鏈接,通常被稱為“心跳”,然后在遠(yuǎn)端確認(rèn)它是否還活著。(還有一個(gè)方法是比較激進(jìn)的,簡(jiǎn)單地?cái)嚅_(kāi)那些指定的時(shí)間間隔的不活躍的鏈接)。

處理空閑連接是一項(xiàng)常見(jiàn)的任務(wù),Netty 提供了幾個(gè) ChannelHandler 實(shí)現(xiàn)此目的。表8.4概述。

Table 8.4 ChannelHandlers for idle connections and timeouts

名稱描述
IdleStateHandler如果連接閑置時(shí)間過(guò)長(zhǎng),則會(huì)觸發(fā) IdleStateEvent 事件。在 ChannelInboundHandler 中可以覆蓋 userEventTriggered(...) 方法來(lái)處理 IdleStateEvent。
ReadTimeoutHandler在指定的時(shí)間間隔內(nèi)沒(méi)有接收到入站數(shù)據(jù)則會(huì)拋出 ReadTimeoutException 并關(guān)閉 Channel。ReadTimeoutException 可以通過(guò)覆蓋 ChannelHandler 的 exceptionCaught(…) 方法檢測(cè)到。
WriteTimeoutHandlerWriteTimeoutException 可以通過(guò)覆蓋 ChannelHandler 的 exceptionCaught(…) 方法檢測(cè)到。

詳細(xì)看下 IdleStateHandler,下面是一個(gè)例子,當(dāng)超過(guò)60秒沒(méi)有數(shù)據(jù)收到時(shí),就會(huì)得到通知,此時(shí)就發(fā)送心跳到遠(yuǎn)端,如果沒(méi)有回應(yīng),連接就關(guān)閉。

Listing 8.7 Sending heartbeats

public class IdleStateHandlerInitializer extends ChannelInitializer<Channel> {

    @Override
    protected void initChannel(Channel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new IdleStateHandler(0, 0, 60, TimeUnit.SECONDS));  //1
        pipeline.addLast(new HeartbeatHandler());
    }

    public static final class HeartbeatHandler extends ChannelInboundHandlerAdapter {
        private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled.unreleasableBuffer(
                Unpooled.copiedBuffer("HEARTBEAT", CharsetUtil.ISO_8859_1));  //2

        @Override
        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
            if (evt instanceof IdleStateEvent) {
                 ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate())
                         .addListener(ChannelFutureListener.CLOSE_ON_FAILURE);  //3
            } else {
                super.userEventTriggered(ctx, evt);  //4
            }
        }
    }
}
  1. IdleStateHandler 將通過(guò) IdleStateEvent 調(diào)用 userEventTriggered ,如果連接沒(méi)有接收或發(fā)送數(shù)據(jù)超過(guò)60秒鐘
  2. 心跳發(fā)送到遠(yuǎn)端
  3. 發(fā)送的心跳并添加一個(gè)偵聽(tīng)器,如果發(fā)送操作失敗將關(guān)閉連接
  4. 事件不是一個(gè) IdleStateEvent 的話,就將它傳遞給下一個(gè)處理程序

總而言之,這個(gè)例子說(shuō)明了如何使用 IdleStateHandler 測(cè)試遠(yuǎn)端是否還活著,如果遠(yuǎn)端已經(jīng)不活著了就可以將該鏈接關(guān)閉以釋放資源。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)