最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Nett中的心跳機(jī)制與斷線重連詳解

 更新時(shí)間:2023年12月21日 10:01:14   作者:Colins~  
這篇文章主要介紹了Nett中的心跳機(jī)制與斷線重連詳解,我們以客戶端發(fā)送心跳為例,平時(shí)我們的心跳實(shí)現(xiàn)方式可能是搞個(gè)定時(shí)器,定時(shí)發(fā)送是吧,但是在Netty中卻不一樣,心跳被稱為空閑檢測(cè),需要的朋友可以參考下

心跳機(jī)制

我們以客戶端發(fā)送心跳為例,平時(shí)我們的心跳實(shí)現(xiàn)方式可能是搞個(gè)定時(shí)器,定時(shí)發(fā)送是吧,但是在Netty中卻不一樣,心跳被稱為空閑檢測(cè),因?yàn)樾奶淖钪饕饔镁褪桥袛嗍欠翊婊?、是否假死等情況,所以Netty中并不是定時(shí)發(fā)送,而是空閑的情況下才發(fā)送,空閑指的是一段時(shí)間內(nèi)無(wú)讀寫(xiě)事件的發(fā)生,也就是沒(méi)有信息接收和信息發(fā)送啦,這時(shí)候我就要檢測(cè)一下了

所以Netty的機(jī)制就是通過(guò)監(jiān)測(cè)一段時(shí)間內(nèi)是否有信息的讀、寫(xiě)發(fā)生,然后產(chǎn)生一個(gè)事件,我們可以處理這個(gè)事件來(lái)達(dá)到我們的目的

IdleStateHandler

心跳與其他的數(shù)據(jù)處理Handler一樣,都是建立連接后的數(shù)據(jù)處理,所以同樣都是處理管道中的,IdleStateHandler就是Netty幫我們封裝好了的處理類,我們可以直接使用并將它放入管道中,就可以自動(dòng)檢測(cè)一段時(shí)間內(nèi)是否有讀、寫(xiě)發(fā)生了,常用的構(gòu)造有4個(gè)參數(shù):

  • readerIdleTime:讀事件檢測(cè),該時(shí)間內(nèi)沒(méi)有信息讀取就會(huì)產(chǎn)生一個(gè)讀信息的事件
  • writerIdleTime:寫(xiě)事件檢測(cè),該時(shí)間內(nèi)沒(méi)有信息發(fā)送就會(huì)產(chǎn)生一個(gè)寫(xiě)信息的事件
  • allIdleTime:讀寫(xiě)事件檢測(cè),該時(shí)間內(nèi)沒(méi)有信息發(fā)送或者讀取就會(huì)產(chǎn)生一個(gè)讀寫(xiě)信息的事件
  • unit:時(shí)間單位
public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
    this(false, readerIdleTime, writerIdleTime, allIdleTime, unit);
}

使用:

// 管道中直接添加
// 時(shí)間配置為0則代表不檢測(cè)對(duì)應(yīng)事件
channel.pipeline().addLast(new IdleStateHandler(5,0,0, TimeUnit.SECONDS))

觸發(fā)的事件類型:

  • IdleState.READER_IDLE:讀信息的事件
  • IdleState.WRITER_IDLE:寫(xiě)信息的事件
  • IdleState.ALL_IDLE:讀寫(xiě)信息的事件

舉個(gè)例子:假設(shè)我們是客戶端主動(dòng)發(fā)送心跳,那客戶端就要檢測(cè)一段時(shí)間內(nèi)是否有寫(xiě)信息的操作,如果沒(méi)有就會(huì)觸發(fā)IdleState.WRITER_IDLE事件,那我們監(jiān)聽(tīng)這個(gè)事件,就做出自己的處理,那就是主動(dòng)發(fā)送心跳包嘛

下面我們就以客戶端發(fā)送心跳包為例!

客戶端

像上面那樣直接使用IdleStateHandler,那還需要單獨(dú)寫(xiě)一個(gè)事件處理的類,所以這里我們直接繼承IdleStateHandler

ClientHeartbeatHandler 如下:

我們?cè)O(shè)置5秒,5秒內(nèi)沒(méi)有寫(xiě)過(guò)信息,我們就發(fā)送心跳包(這里消息很隨意,圖方便)

@Slf4j
public class ClientHeartbeatHandler extends IdleStateHandler {
    // 設(shè)置寫(xiě)事件為5s
    // 如果5s沒(méi)有寫(xiě)事件發(fā)生 就會(huì)觸發(fā)下面的IdleStateEvent
    private static final int WRITE_IDLE_TIME = 5;
    public ClientHeartbeatHandler() {
        super(0, WRITE_IDLE_TIME, 0, TimeUnit.SECONDS);
    }
    @Override
    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
        // 指定時(shí)間內(nèi)沒(méi)有寫(xiě)事件發(fā)送 就會(huì)觸發(fā) IdleState.WRITER_IDLE 類型事件
        // 我們就可以對(duì)該連接進(jìn)行處理 主動(dòng)發(fā)送心跳
        if(evt.state()== IdleState.WRITER_IDLE){
            log.info("{} 秒內(nèi)沒(méi)有發(fā)送數(shù)據(jù),再不發(fā)送小心和服務(wù)端斷開(kāi)連接", WRITE_IDLE_TIME);
            ctx.writeAndFlush(new NettyMsg(ServiceCodeEnum.TEST_TYPE,"我還活著,不要斷開(kāi)連接"));
        }
    }
}

NettyClient

管道中加入這個(gè)即可,注意要放在編解碼之后

在這里插入圖片描述

服務(wù)端

基本跟客戶端一樣,但是由于是客戶端給我發(fā)心跳,所以服務(wù)端要監(jiān)測(cè)讀事件

ServerHeartbeatHandler

這里我們?cè)O(shè)置10s,一般會(huì)更多因?yàn)橐o客戶端一些容忍度,適量就好,一旦沒(méi)滿足就和客戶端斷開(kāi)連接

@Slf4j
public class ServerHeartbeatHandler extends IdleStateHandler {
    // 設(shè)置讀取事件為10s
    // 如果10s沒(méi)有讀事件發(fā)生 就會(huì)觸發(fā)下面的IdleStateEvent
    private static final int READER_IDLE_TIME = 10;
    public ServerHeartbeatHandler() {
        super(READER_IDLE_TIME, 0, 0, TimeUnit.SECONDS);
    }
    @Override
    protected void channelIdle(ChannelHandlerContext ctx, IdleStateEvent evt) throws Exception {
        // 指定時(shí)間內(nèi)沒(méi)有讀事件發(fā)送 就會(huì)觸發(fā) IdleState.READER_IDLE 類型事件
        // 我們就可以對(duì)該連接進(jìn)行處理 這里是直接關(guān)閉
        if(evt.state()== IdleState.READER_IDLE){
            log.info("{} 秒內(nèi)沒(méi)有讀取到數(shù)據(jù),關(guān)閉連接", READER_IDLE_TIME);
            ctx.channel().close();
        }
    }
}

NettyServer

在這里插入圖片描述

測(cè)試

正常情況

服務(wù)端

在這里插入圖片描述

客戶端

在這里插入圖片描述

異常情況

我們將客戶端心跳拉長(zhǎng)

在這里插入圖片描述

可以發(fā)現(xiàn)時(shí)間一到自動(dòng)斷連

在這里插入圖片描述

總結(jié)

這里是以客戶端發(fā)送心跳為例,如果是以服務(wù)端發(fā)送心跳也是一樣,主要就是對(duì)讀寫(xiě)事件的監(jiān)聽(tīng),然后做出相應(yīng)處理,上面其實(shí)是很隨意的哈,正常情況下心跳包是會(huì)用專門(mén)的消息類型的,而且服務(wù)端也需要做出應(yīng)答的,心跳應(yīng)答也會(huì)有對(duì)應(yīng)的消息類型

斷線重連

這個(gè)就很簡(jiǎn)單了,肯定是斷線后,客戶端發(fā)起重連嘛,就是在客戶端檢測(cè)到連接斷開(kāi)的時(shí)候,重新連接就好了

ClientHeartbeatHandler加上一段:

在這里插入圖片描述

看看效果,客戶端心跳時(shí)間還是12s哈

在這里插入圖片描述

能這么隨意嗎?當(dāng)然不行啊,別學(xué)我,正常會(huì)搞多次重連,而且謹(jǐn)慎起見(jiàn),每次重連還可以加一個(gè)時(shí)間的間隔,可以學(xué)一下nacos里面的高級(jí)玩法,隨著重連次數(shù)的增加,間隔重試的時(shí)間也隨之增加,比如:

第一次重連是4s,第二次重連是8s,第三次是16s,以此類推

也就是設(shè)置重連間隔時(shí)間基數(shù)為4s,每嘗試一次,左移一位(4<<1),連接成功后基數(shù)復(fù)位為4s

需要設(shè)置最大重試次數(shù),最長(zhǎng)間隔時(shí)間(一直左移后面會(huì)很長(zhǎng)時(shí)間,所以要設(shè)置一個(gè)上限,超過(guò)了就以上限為準(zhǔn))

偽代碼如下

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().remoteAddress() + " 已斷開(kāi)連接,開(kāi)始重連");
        int maxRetryNum=6; //最大重連次數(shù)
        int maxRetryTime=60; // 最大重連時(shí)間
        int baseRetryTime=4; // 間隔時(shí)間基數(shù)
        // 開(kāi)始重連
        for (int i = 1; i <= maxRetryNum; i++) {
            log.info("第{}次重連,間隔{}s后開(kāi)始",i,baseRetryTime > maxRetryTime ? maxRetryTime:baseRetryTime);
            ctx.channel().eventLoop().schedule(()->{
                // 重連操作
                // .......
                // 判斷是否超過(guò)隔間上限
            },baseRetryTime > maxRetryTime ? maxRetryTime:baseRetryTime,TimeUnit.SECONDS);
            // 左移擴(kuò)大一倍
            baseRetryTime = baseRetryTime << 1;
        }
        log.info("這么多次重連都不行寄了吧");
    }

偽代碼哈,偽代碼!

結(jié)果如下

建立連接后,手動(dòng)關(guān)閉服務(wù)端,可以看到重連了6次,每次間隔時(shí)間翻倍,達(dá)到間隔時(shí)間上限后,就以上限的時(shí)間為準(zhǔn)

在這里插入圖片描述

到此這篇關(guān)于Nett中的心跳機(jī)制與斷線重連詳解的文章就介紹到這了,更多相關(guān)Nett心跳機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java面試題沖刺第二十三天--算法(2)

    Java面試題沖刺第二十三天--算法(2)

    這篇文章主要為大家分享了最有價(jià)值的三道關(guān)于算法的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • JavaWeb項(xiàng)目中classpath路徑詳解

    JavaWeb項(xiàng)目中classpath路徑詳解

    今天小編就為大家分享一篇關(guān)于JavaWeb項(xiàng)目中classpath路徑詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • Java switch關(guān)鍵字原理及用法詳解

    Java switch關(guān)鍵字原理及用法詳解

    這篇文章主要介紹了Java中 switch關(guān)鍵原理及用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 淺談java異常處理(父子異常的處理)

    淺談java異常處理(父子異常的處理)

    下面小編就為大家?guī)?lái)一篇淺談java異常處理(父子異常的處理)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • SpringCloud 如何提取公共配置

    SpringCloud 如何提取公共配置

    這篇文章主要介紹了SpringCloud 提取公共配置的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路

    基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性的設(shè)計(jì)思路

    這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)自動(dòng)裝配返回屬性,這里涉及到的技術(shù)知識(shí)點(diǎn)有注解解析器,為什么用ResponseBodyAdvice這里解析?不在Filter,Interceptors,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-03-03
  • Spring Boot之內(nèi)嵌tomcat版本升級(jí)操作示例

    Spring Boot之內(nèi)嵌tomcat版本升級(jí)操作示例

    這篇文章主要為大家介紹了Spring Boot之內(nèi)嵌tomcat版本升級(jí)操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • JDK動(dòng)態(tài)代理提高代碼可維護(hù)性和復(fù)用性利器

    JDK動(dòng)態(tài)代理提高代碼可維護(hù)性和復(fù)用性利器

    這篇文章主要為大家介紹了JDK動(dòng)態(tài)代理提高代碼可維護(hù)性和復(fù)用性利器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Spring mvc攔截器實(shí)現(xiàn)原理解析

    Spring mvc攔截器實(shí)現(xiàn)原理解析

    這篇文章主要介紹了Spring mvc攔截器實(shí)現(xiàn)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java--裝箱和拆箱詳解

    Java--裝箱和拆箱詳解

    本篇文章主要介紹了詳解Java 自動(dòng)裝箱與拆箱的實(shí)現(xiàn)原理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-07-07

最新評(píng)論

襄城县| 昌黎县| 连州市| 清水河县| 齐河县| 九寨沟县| 高邑县| 八宿县| 焉耆| 林周县| 桐乡市| 文登市| 高阳县| 东山县| 济源市| 杭州市| 南溪县| 平乐县| 丰原市| 澄城县| 平昌县| 行唐县| 沙河市| 文化| 海晏县| 新余市| 双鸭山市| 梅河口市| 平远县| 皋兰县| 宾阳县| 容城县| 久治县| 进贤县| 江达县| 伊宁市| 资兴市| 太白县| 镶黄旗| 藁城市| 琼中|