第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Netty 心跳檢測

1. 前言

本節(jié),我們主要講解心跳機(jī)制 heartbeat,Netty 給我們提供了三個(gè) Handler,分別是 IdleStateHandler、ReadTimeoutHandlerWriteTimeoutHandler,主要目的是檢查對方是否有效,也就是說對方是否還在線。

2. 為什么需要心跳機(jī)制

了解 TCP: TCP 協(xié)議適用于客戶端數(shù)量相對比較少,并且通信頻繁的業(yè)務(wù)場景;Http 協(xié)議則適用于客戶端數(shù)量比較大的業(yè)務(wù)場景。因?yàn)?Http 是短連接,請求完成即會釋放連接資源,不再占用服務(wù)器資源,但是,TCP 則不會,連接成功,則可以多次請求,不會釋放,除非特殊原因?qū)е逻B接斷開。

面臨問題: 既然長連接是不會釋放連接資源,那么如果很多客戶端只是完成了連接,但是并沒有實(shí)際的業(yè)務(wù)請求操作,那么服務(wù)器的資源還是被占用,導(dǎo)致服務(wù)器性能下降。

解決辦法: 把那些長期占用連接資源,但是并沒有實(shí)際業(yè)務(wù)操作的連接斷開掉,等它們需要做業(yè)務(wù)操作的時(shí)候,再重連服務(wù)器。這樣可以達(dá)到即使釋放沒用的資源,提高服務(wù)器的性能。

總結(jié),心跳機(jī)制主要有以下兩個(gè)方面的作用

  1. 定時(shí)剔除哪些沒用的連接,減輕服務(wù)端的壓力;
  2. 適用于中間件(比如:RPC 框架),服務(wù)端規(guī)定時(shí)間內(nèi)沒用收到客戶端的心跳數(shù)據(jù),則可以認(rèn)為其宕機(jī),服務(wù)端剔除對于的映射關(guān)系。

圖片描述

3. 三個(gè)核心類講解

為了實(shí)現(xiàn)以上需求,Netty 給我們提供了幾個(gè)特殊的 Handler 類。

名稱 作用
IdleStateHandler 當(dāng)連接空閑時(shí)間(讀或?qū)懀┨L時(shí),將觸發(fā) IdleStateEvent 事件,可以通過 ChannelInboundHandler 中重寫 userEventTrigged 方法來處理該事件。
ReadTimeoutHandler 如果在指定的時(shí)間之內(nèi)沒有發(fā)生讀事件,就會拋出這個(gè)異常,并且自動關(guān)閉連接??梢栽?exectionCaught 方法中處理這個(gè)異常。
WriteTimeoutHandler 如果在指定的時(shí)間之內(nèi)沒有發(fā)生寫事件,拋出次異常,并且關(guān)閉連接??梢栽?exectionCaught 方法中處理這個(gè)異常。

IdleStateHandler 構(gòu)造函數(shù)說明

/*
* readerIdleTimeSeconds 讀事件空閑時(shí)間,如果為0則表示禁用
* writerIdleTimeSeconds 寫事件空閑時(shí)間,如果為0則表示禁用
* allIdleTimeSeconds 讀寫事件空閑時(shí)間
*/
public IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
    
}

public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
    
}

總結(jié):都是利用定時(shí)器調(diào)度任務(wù)完成。 IdleStateHandler 超時(shí)調(diào)用 handler 的 userEventTriggered 方法。ReadTimeOutHandler 超時(shí)拋出異常,調(diào)用 handler 的 exceptionCaught 方法,并且會關(guān)閉 channel。

4. 案例測試

4.1 服務(wù)端

實(shí)例:

ChannelPipeline pipeline = ch.pipeline();

//5秒鐘沒有讀事件,則斷開連接
pipeline.addLast(new ReadTimeoutHandler(5, TimeUnit.SECONDS));
//5秒鐘沒有寫事件,則斷開連接
pipeline.addLast(new WriteTimeoutHandler(5, TimeUnit.SECONDS));
//解碼器
pipeline.addLast(new StringDecoder());
//編碼器
pipeline.addLast(new StringEncoder());
//業(yè)務(wù)Handler
pipeline.addLast(new HeartBeanHandler());
public class HeartBeanHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("channelRead>>>"+msg+">>>"+ LocalDateTime.now());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("exceptionCaught>>>"+cause.getMessage());
    }
}

4.2 客戶端 1

實(shí)例:延遲 1 秒鐘,每個(gè) 15 秒鐘往服務(wù)端發(fā)送一次 hello world

channelFuture.channel().eventLoop().scheduleWithFixedDelay(new Runnable() {
    public void run() {
        channelFuture.channel().writeAndFlush("hello world");
    }    
},1,15, TimeUnit.SECONDS);

服務(wù)端執(zhí)行結(jié)果:

channelRead>>>hello world>>>2020-07-26T15:16:08.893
exceptionCaught>>>null

客戶端執(zhí)行結(jié)果:

客戶端關(guān)閉了
Process finished with exit code 0

代碼說明:

  1. 客戶端每隔 15 秒發(fā)送一次數(shù)據(jù);
  2. 服務(wù)端如果 5 秒之內(nèi)沒有讀寫事件,則自動斷開連接;
  3. 從時(shí)間設(shè)置上來看,客戶端每次發(fā)送數(shù)據(jù)都是超時(shí)了,因此,連接會被斷開。

4.3 客戶端 2

實(shí)例:延遲 1 秒鐘,每個(gè) 3 秒鐘往服務(wù)端發(fā)送一次 hello world。

channelFuture.channel().eventLoop().scheduleWithFixedDelay(new Runnable() {
    public void run() {
        channelFuture.channel().writeAndFlush("hello world");
    }    
},1,3, TimeUnit.SECONDS);

服務(wù)端執(zhí)行結(jié)果:

channelRead>>>hello world>>>2020-07-26T15:15:10.889
channelRead>>>hello world>>>2020-07-26T15:15:13.892
channelRead>>>hello world>>>2020-07-26T15:15:16.893
channelRead>>>hello world>>>2020-07-26T15:15:19.894

代碼說明:

  1. 客戶端每隔 3 秒發(fā)送一次數(shù)據(jù);
  2. 服務(wù)端如果 5 秒之內(nèi)沒有讀寫事件,則自動斷開;
  3. 從時(shí)間設(shè)置上來看,客戶端每次發(fā)送數(shù)據(jù)的時(shí)間都在超時(shí)時(shí)間范圍之內(nèi),因此,連接不會被斷開。

4.4 特殊說明

ReadTimeoutHandler 和 WriteTimeoutHandler 既可以用于客戶端,也可以用于服務(wù)端,或者兩邊同時(shí)使用。常見的業(yè)務(wù)場景如下所示:

場景一: 如果是服務(wù)端往客戶端推送消息(消息推送),則 WriteTimeoutHandler 用于服務(wù)端,ReadTimeoutHandler 用于客戶端;
場景二: 如果是客戶端主動發(fā)起請求的業(yè)務(wù)(比如:IM),則 WriteTimeoutHandler 用于客戶端,ReadTimeoutHandler 用于服務(wù)端。

4.5 IdleStateHandler 的使用

實(shí)例:管道中添加 IdleStateHandler

// 空閑檢測
ch.pipeline().addLast(new IdleStateHandler(60,45,20,TimeUnit.SECONDS));
// 業(yè)務(wù)Handler
ch.pipeline().addLast(new HeartBeatHandler());

5. 小結(jié)

本節(jié)主要掌握的知識點(diǎn)

  1. 為什么需要做心跳檢測,以及它的常見作用,分別是:主動剔除無用連接減輕服務(wù)端壓力、用于中間件的心跳檢測;
  2. Netty 提了三個(gè)核心類,分別是 IdleStateHandler、ReadTimeoutHandler、WriteTimeoutHandler,它們的作用以及使用方法。