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

Netty中的心跳檢測機制詳解

 更新時間:2023年12月11日 11:06:41   作者:warybee  
這篇文章主要介紹了Netty中的心跳檢測機制詳解,Netty 是 基于 TCP 協(xié)議開發(fā)的,在四層協(xié)議 TCP 協(xié)議的實現(xiàn)中也提供了 keepalive 報文用來探測對端是否可用,TCP 層將在定時時間到后發(fā)送相應(yīng)的 KeepAlive 探針以確定連接可用性,需要的朋友可以參考下

Netty心跳檢測機制

1 心跳檢測使用場景

長連接的應(yīng)用場景非常的廣泛,比如監(jiān)控系統(tǒng),IM系統(tǒng),即時報價系統(tǒng),推送服務(wù)等等。像這些場景都是比較注重實時性,如果每次發(fā)送數(shù)據(jù)都要進行一次DNS解析,建立連接的過程肯定是極其影響體驗。

而長連接的維護必然需要一套機制來控制。比如 HTTP/1.0 通過在 header 頭中添加 Connection:Keep-Alive參數(shù),如果當(dāng)前請求需要?;顒t添加該參數(shù)作為標(biāo)識,否則服務(wù)端就不會保持該連接的狀態(tài),發(fā)送完數(shù)據(jù)之后就關(guān)閉連接。HTTP/1.1以后 Keep-Alive 是默認打開的。

Netty 是 基于 TCP 協(xié)議開發(fā)的,在四層協(xié)議 TCP 協(xié)議的實現(xiàn)中也提供了 keepalive 報文用來探測對端是否可用。TCP 層將在定時時間到后發(fā)送相應(yīng)的 KeepAlive 探針以確定連接可用性。

Netty 中提供了 tcp-keepalive 的設(shè)置:

在這里插入圖片描述

.childOption(ChannelOption.SO_KEEPALIVE,true) 表示打開 TCP 的 keepAlive 設(shè)置。

2 Netty心跳檢測機制

Netty 中提供了 IdleStateHandler 類專門用于處理心跳。構(gòu)造函數(shù)如下:

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

參數(shù)說明:

  • readerIdleTime 隔多久檢查一下讀事件是否發(fā)生,如果 channelRead() 方法超過 readerIdleTime 時間未被調(diào)用則會觸發(fā)超時事件調(diào)用 userEventTrigger() 方法
  • writerIdleTime 隔多久檢查一下寫事件是否發(fā)生,如果 write() 方法超過 writerIdleTime 時間未被調(diào)用則會觸發(fā)超時事件調(diào)用 userEventTrigger() 方法;
  • allIdleTime 隔多久檢查讀寫事件是否發(fā)生
  • unit 時間單位

可以分別控制讀,寫,讀寫超時的時間,如果設(shè)置為0表示不檢測,所以如果全是0,則相當(dāng)于沒添加這個 IdleStateHandler,連接是個普通的短連接。

2.1 代碼演示

服務(wù)端

public class TestHeartServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap=new ServerBootstrap();
            bootstrap.group(bossGroup,workerGroup)
                      .channel(NioServerSocketChannel.class)
                      .option(ChannelOption.SO_BACKLOG,128)
                       .childOption(ChannelOption.SO_KEEPALIVE,true)
                       .handler(new LoggingHandler(LogLevel.INFO))//bossGroup處理handler
                       .childHandler(new ChannelInitializer<SocketChannel>() {//workergroup處理handler
                           @Override
                           protected void initChannel(SocketChannel ch) throws Exception {
                               ChannelPipeline pipeline = ch.pipeline();
                               //每隔5s檢查一下是否有讀事件發(fā)生
                               pipeline.addLast(new IdleStateHandler(5,0,0, TimeUnit.SECONDS));
                               pipeline.addLast(new TestHeartServerHandler());
                           }
                       });
            ChannelFuture channelFuture = bootstrap.bind(9999).sync();
            channelFuture.channel().closeFuture().sync();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

服務(wù)端handler

public class TestHeartServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channelActive");
    }
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf=(ByteBuf) msg;
        System.out.println("客戶端消息:"+buf.toString(StandardCharsets.UTF_8));
        //向客戶端發(fā)送消息
        //ctx.writeAndFlush(Unpooled.copiedBuffer("heart",StandardCharsets.UTF_8));
    }
    /**
     *如果5s沒有讀請求,則向客戶端發(fā)送心跳
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;
        switch (event.state()) {
            case READER_IDLE: //讀空閑
                //如果5s沒有讀請求,則向客戶端發(fā)送心跳
                ctx.writeAndFlush("server send Heartbeat").addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
                break;
            case WRITER_IDLE://寫空閑
                break;
            case ALL_IDLE://讀寫空閑
                break;
        }
    }
}

客戶端

public class TestHeartClient {
    public static void main(String[] args) {
        EventLoopGroup eventExecutors=new NioEventLoopGroup();
        try {
            Bootstrap bootstrap=new Bootstrap();
            bootstrap.group(eventExecutors)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //每隔4s檢查一下是否有寫事件
                            pipeline.addLast(new IdleStateHandler(0,4,0, TimeUnit.SECONDS));
                            pipeline.addLast(new TestHeartClientHandler());
                        }
                    });
            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 9999).sync();
            //向服務(wù)端發(fā)送消息
            channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer("Hello server, i'm online", StandardCharsets.UTF_8));
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            eventExecutors.shutdownGracefully();
        }
    }
}

客戶端Handler

public class TestHeartClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf=(ByteBuf) msg;
        System.out.println("服務(wù)端發(fā)送的消息:"+buf.toString(StandardCharsets.UTF_8));
    }
    /**
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;
        String eventType = null;
        switch (event.state()) {
            //讀空閑
            case READER_IDLE:
                break;
            case WRITER_IDLE://寫空閑
                //如果4s沒有收到寫請求,則向服務(wù)端發(fā)送心跳請求
                ctx.writeAndFlush(Unpooled.copiedBuffer("client send Heartbeat",StandardCharsets.UTF_8)).addListener(ChannelFutureListener.CLOSE_ON_FAILURE) ;
                break;
            case ALL_IDLE://讀寫空閑
                break;
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
         cause.printStackTrace();
         ctx.close();
    }
}

解釋一下代碼的邏輯:

服務(wù)端添加了:

Copypipeline.addLast(new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS));

每隔5s檢查一下是否有讀事件發(fā)生,如果沒有就觸發(fā) handler 中的 userEventTriggered(ChannelHandlerContext ctx, Object evt)邏輯。

客戶端添加了:

Copynew IdleStateHandler(0, 4, 0, TimeUnit.SECONDS)

每隔4s檢查一下是否有寫事件,如果沒有就觸發(fā) handler 中的 userEventTriggered(ChannelHandlerContext ctx, Object evt)邏輯。

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

相關(guān)文章

  • springboot2.x 接入阿里云市場短信發(fā)送的實現(xiàn)

    springboot2.x 接入阿里云市場短信發(fā)送的實現(xiàn)

    本文主要介紹了springboot2.x 接入阿里云市場短信發(fā)送的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java實現(xiàn)實時監(jiān)控目錄下文件變化的方法

    Java實現(xiàn)實時監(jiān)控目錄下文件變化的方法

    今天小編就為大家分享一篇關(guān)于Java實現(xiàn)實時監(jiān)控目錄下文件變化的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • 詳解Java List的擴容機制原理及應(yīng)用

    詳解Java List的擴容機制原理及應(yīng)用

    在Java中,List是一種非常常用的數(shù)據(jù)結(jié)構(gòu),用于存儲有序的元素集合,本文將分析Java List的擴容機制原理,并通過示例代碼和測試代碼來加強闡述內(nèi)容,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • springmvc后臺基于@ModelAttribute獲取表單提交的數(shù)據(jù)

    springmvc后臺基于@ModelAttribute獲取表單提交的數(shù)據(jù)

    這篇文章主要介紹了springmvc后臺基于@ModelAttribute獲取表單提交的數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • java轉(zhuǎn)化為exe程序步驟詳解

    java轉(zhuǎn)化為exe程序步驟詳解

    在本篇內(nèi)容里我們給大家分享了關(guān)于java轉(zhuǎn)化為exe程序的具體步驟和相關(guān)知識點,需要的朋友們學(xué)習(xí)下。
    2019-03-03
  • mybatis使用foreach查詢不出結(jié)果也不報錯的問題

    mybatis使用foreach查詢不出結(jié)果也不報錯的問題

    這篇文章主要介紹了mybatis使用foreach查詢不出結(jié)果也不報錯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Spring Boot集成Java DSL的實現(xiàn)代碼

    Spring Boot集成Java DSL的實現(xiàn)代碼

    這篇文章主要介紹了Spring Boot集成Java DSL的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Netty解決半包和粘包問題的方案

    Netty解決半包和粘包問題的方案

    Netty 是一個高性能、異步事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用框架,廣泛應(yīng)用于各種網(wǎng)絡(luò)通信場景,這篇文章,我們將詳細分析 Netty 是如何解決半包和粘包問題,文中通過代碼示介紹的非常詳細,需要的朋友可以參考下
    2024-08-08
  • Spring?Cloud?Sentinel快速入門步驟

    Spring?Cloud?Sentinel快速入門步驟

    本文介紹了Sentinel,一個用于企業(yè)級微服務(wù)開發(fā)的流量控制、熔斷降級和系統(tǒng)負載保護的組件,Sentinel的核心概念包括資源、規(guī)則和SlotChain,其三大核心功能分別是流量控制、熔斷降級和系統(tǒng)保護,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • mybatis-plus之自動映射字段(typeHandler)的注意點及說明

    mybatis-plus之自動映射字段(typeHandler)的注意點及說明

    這篇文章主要介紹了mybatis-plus之自動映射字段(typeHandler)的注意點及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04

最新評論

哈尔滨市| 高阳县| 温宿县| 图木舒克市| 郧西县| 儋州市| 阿拉善盟| 屯昌县| 黄骅市| 平陆县| 武义县| 汪清县| 弥渡县| 汉川市| 盖州市| 会理县| 乌兰察布市| 沾益县| 读书| 明溪县| 县级市| 镇康县| 潮安县| 临泽县| 合肥市| 应城市| 边坝县| 虞城县| 仁布县| 汶川县| 昌吉市| 伊宁县| 开封市| 瑞安市| 高陵县| 鄂托克前旗| 盘山县| 噶尔县| 古蔺县| 周至县| 镇巴县|