Netty——心跳机制与断线重连

news2024/11/13 10:33:30

心跳机制与断线重连

    • 心跳机制
      • IdleStateHandler
      • 客户端
      • 服务端
      • 测试
        • 正常情况
        • 异常情况
      • 总结
    • 断线重连

为了保证系统的稳定性,心跳机制和断线重连可是必不可少的,而这两个在Netty中也是非常好实现的

心跳机制

我们以客户端发送心跳为例,平时我们的心跳实现方式可能是搞个定时器,定时发送是吧,但是在Netty中却不一样,心跳被称为空闲检测,因为心跳的最主要作用就是判断是否存活、是否假死等情况,所以Netty中并不是定时发送,而是空闲的情况下才发送,空闲指的是一段时间内无读写事件的发生,也就是没有信息接收和信息发送啦,这时候我就要检测一下了

所以Netty的机制就是通过监测一段时间内是否有信息的读、写发生,然后产生一个事件,我们可以处理这个事件来达到我们的目的

IdleStateHandler

心跳与其他的数据处理Handler一样,都是建立连接后的数据处理,所以同样都是处理管道中的,IdleStateHandler就是Netty帮我们封装好了的处理类,我们可以直接使用并将它放入管道中,就可以自动检测一段时间内是否有读、写发生了,常用的构造有4个参数:

  • readerIdleTime:读事件检测,该时间内没有信息读取就会产生一个读信息的事件
  • writerIdleTime:写事件检测,该时间内没有信息发送就会产生一个写信息的事件
  • allIdleTime:读写事件检测,该时间内没有信息发送或者读取就会产生一个读写信息的事件
  • unit:时间单位
public IdleStateHandler(long readerIdleTime, long writerIdleTime, long allIdleTime, TimeUnit unit) {
    this(false, readerIdleTime, writerIdleTime, allIdleTime, unit);
}

使用

// 管道中直接添加
// 时间配置为0则代表不检测对应事件
channel.pipeline().addLast(new IdleStateHandler(5,0,0, TimeUnit.SECONDS))

触发的事件类型

  • IdleState.READER_IDLE:读信息的事件
  • IdleState.WRITER_IDLE:写信息的事件
  • IdleState.ALL_IDLE:读写信息的事件

举个例子:假设我们是客户端主动发送心跳,那客户端就要检测一段时间内是否有写信息的操作,如果没有就会触发IdleState.WRITER_IDLE事件,那我们监听这个事件,就做出自己的处理,那就是主动发送心跳包嘛

下面我们就以客户端发送心跳包为例!

客户端

像上面那样直接使用IdleStateHandler,那还需要单独写一个事件处理的类,所以这里我们直接继承IdleStateHandler

ClientHeartbeatHandler 如下:

我们设置5秒,5秒内没有写过信息,我们就发送心跳包(这里消息很随意,图方便)

@Slf4j
public class ClientHeartbeatHandler extends IdleStateHandler {

    // 设置写事件为5s
    // 如果5s没有写事件发生 就会触发下面的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 {
        // 指定时间内没有写事件发送 就会触发 IdleState.WRITER_IDLE 类型事件
        // 我们就可以对该连接进行处理 主动发送心跳
        if(evt.state()== IdleState.WRITER_IDLE){
            log.info("{} 秒内没有发送数据,再不发送小心和服务端断开连接", WRITE_IDLE_TIME);
            ctx.writeAndFlush(new NettyMsg(ServiceCodeEnum.TEST_TYPE,"我还活着,不要断开连接"));
        }
    }
}

NettyClient

管道中加入这个即可,注意要放在编解码之后

在这里插入图片描述

服务端

基本跟客户端一样,但是由于是客户端给我发心跳,所以服务端要监测读事件

ServerHeartbeatHandler

这里我们设置10s,一般会更多因为要给客户端一些容忍度,适量就好,一旦没满足就和客户端断开连接

@Slf4j
public class ServerHeartbeatHandler extends IdleStateHandler {

    // 设置读取事件为10s
    // 如果10s没有读事件发生 就会触发下面的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 {
        // 指定时间内没有读事件发送 就会触发 IdleState.READER_IDLE 类型事件
        // 我们就可以对该连接进行处理 这里是直接关闭
        if(evt.state()== IdleState.READER_IDLE){
            log.info("{} 秒内没有读取到数据,关闭连接", READER_IDLE_TIME);
            ctx.channel().close();
        }
    }
}

NettyServer

在这里插入图片描述

测试

正常情况

服务端

在这里插入图片描述

客户端

在这里插入图片描述

异常情况

我们将客户端心跳拉长

在这里插入图片描述

可以发现时间一到自动断连

在这里插入图片描述

总结

这里是以客户端发送心跳为例,如果是以服务端发送心跳也是一样,主要就是对读写事件的监听,然后做出相应处理,上面其实是很随意的哈,正常情况下心跳包是会用专门的消息类型的,而且服务端也需要做出应答的,心跳应答也会有对应的消息类型

断线重连

这个就很简单了,肯定是断线后,客户端发起重连嘛,就是在客户端检测到连接断开的时候,重新连接就好了

ClientHeartbeatHandler加上一段:

在这里插入图片描述

看看效果,客户端心跳时间还是12s哈

在这里插入图片描述

能这么随意吗?当然不行啊,别学我,正常会搞多次重连,而且谨慎起见,每次重连还可以加一个时间的间隔,可以学一下nacos里面的高级玩法,随着重连次数的增加,间隔重试的时间也随之增加,比如:

第一次重连是4s,第二次重连是8s,第三次是16s,以此类推
也就是设置重连间隔时间基数为4s,每尝试一次,左移一位(4<<1),连接成功后基数复位为4s

需要设置最大重试次数,最长间隔时间(一直左移后面会很长时间,所以要设置一个上限,超过了就以上限为准)

伪代码如下

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().remoteAddress() + " 已断开连接,开始重连");
        int maxRetryNum=6; //最大重连次数
        int maxRetryTime=60; // 最大重连时间
        int baseRetryTime=4; // 间隔时间基数
        // 开始重连
        for (int i = 1; i <= maxRetryNum; i++) {
            log.info("第{}次重连,间隔{}s后开始",i,baseRetryTime > maxRetryTime ? maxRetryTime:baseRetryTime);
            ctx.channel().eventLoop().schedule(()->{
                // 重连操作
                // .......

                // 判断是否超过隔间上限
            },baseRetryTime > maxRetryTime ? maxRetryTime:baseRetryTime,TimeUnit.SECONDS);
            // 左移扩大一倍
            baseRetryTime = baseRetryTime << 1;

        }
        log.info("这么多次重连都不行寄了吧");
    }

伪代码哈,伪代码!

结果如下

建立连接后,手动关闭服务端,可以看到重连了6次,每次间隔时间翻倍,达到间隔时间上限后,就以上限的时间为准
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/384158.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux常用命令介绍 04 篇——uniq命令使用介绍(Linux重复数据的统计处理)

linux常用命令介绍 04 篇——uniq命令使用介绍&#xff08;Linux重复数据的统计处理&#xff09;1. uniq 使用语法2. sort 简单效果3. uniq 使用例子3.1 不加任何选项3.1.1 不用 sort 效果3.1.2 uniq 结合 sort 一起使用3.2 使用选项例子3.2.1 去重打印&#xff08;或打印不重复…

12 nuxt3学习(配置)

链接: nuxt3官网 nuxt简介 vue3技术栈&#xff1a;Nuxt3 是基于 Vue3 Vue Router Vite 等技术栈&#xff0c;全程 Vue3Vite 开发体验&#xff08;Fast&#xff09;。自动导包&#xff1a;Nuxt 会自动导入辅助函数、组合 API和 Vue API &#xff0c;无需手动导入。 基于规范…

卡方分布、非中心卡方分布详解 (概念、求阈值方法、非中心化参数求解办法等)

一、相关概念 1、卡方分布 若n个 相互独立 的随机变量 ξ₁、ξ₂、……、ξn ,均服从 标准正态分布N(0,1),则这n个服从标准正态分布的随机变量的 平方和 构成一新的随机变量,其分布规律称为卡方分布(chi-squaredistribution);其中参数n称为自由度(通俗讲,样本中独立…

有关数据库的一级、二级、三级封锁协议

一级封锁协议 一级封锁协议是指&#xff0c;事务T在修改数据R之前必须先对其加X锁&#xff0c;直到事务结束才释放。事务结束包括正常结束&#xff08;COMMIT&#xff09;和非正常结束&#xff08;ROLLBACK).一级封锁协议可防止丢失修改&#xff0c;并保证事务T是可恢复的。在…

SpringBoot热部署

启动热部署 关于热部署 重启&#xff08;Restart&#xff09;&#xff1a;自定义开发代码&#xff0c;包含类、页面、配置文件等&#xff0c;加载位置restart类加载器重载&#xff08;ReLoad&#xff09;&#xff1a;jar包&#xff0c;加载位置base类加载器开启开发者工具 导…

gma 地理空间绘图:(1) 绘制简单的世界地图-2.设置经纬网

内容回顾 gma 地理空间绘图&#xff1a;(1)绘制简单的世界地图-1.地图绘制与细节调整 方法 AddGridLines(LONRange (-180, 180, 15), LATRange (-90, 90, 15), ShowLON True, ShowLAT True, LineColor ‘gray’, LineStyle (0, (6, 6)), LineWidth 0.3) 功能&#xf…

10种常见网站安全攻击手段及防御方法

在某种程度上&#xff0c;互联网上的每个网站都容易遭受安全攻击。从人为失误到网络罪犯团伙发起的复杂攻击均在威胁范围之内。 网络攻击者最主要的动机是求财。无论你运营的是电子商务项目还是简单的小型商业网站&#xff0c;潜在攻击的风险就在那里。 知己知彼百战不殆&…

MOA-30kV氧化锌避雷器泄露电流测试仪

一、概述 用于检测10kV及以下电力系统用无间隙氧化锌避雷器MOA阀电间接触不良的内部缺陷&#xff0c;测量MOA的直流参考电压&#xff08;U1mA&#xff09;和0.75 U1mA下的泄漏电流。该仪器将直流高压电源、测量和控制系统组成一体&#xff0c;元件浓缩在一个机箱内&#xff0c…

JS混淆加密:Eval的未公开用法

JavaScript奇技淫巧&#xff1a;Eval的未公开用法 作者&#xff1a;http://JShaman.com w2sft&#xff0c;转载请保留此信息很多人都知道&#xff0c;Eval是用来执行JS代码的&#xff0c;可以执行运算、可以输出结果。 但它还有一种未公开的用途&#xff0c;想必很少有人用过。…

【计算机网络】数据链路层:组帧,奇偶校验,CRC循环冗余校验,海明码详解

数据链路层 一、校验 1. 奇偶校验 偶校验 数据位和为偶数&#xff1a;校验位为0&#xff1b;数据位和为奇数&#xff1a;校验位为1&#xff1b; 奇校验 数据位和为奇数&#xff1a;校验位为0&#xff1b;数据位和为偶数&#xff1a;校验位为1&#xff1b; 缺点是会存在误判…

【Autoware】采集实验数据bag包并仿真运行

文章目录1. 官方demo包2. 控制底层地图采集3. 感知定位4. 规划控制5. 仿真或实车运行1. 官方demo包 wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_data.tar.gz wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_150324.tar.gz官方示例包的网上…

iPhone屏蔽APP广告的方法

iPhone怎么屏蔽网站(域名)&#xff1f; 操作步骤&#xff1a;“设置” -> “屏幕使用时间” -> “打开屏幕使用时间” -> “内容和隐私访问限制” -> “内容访问限制” -> “网页内容” -> “限制成人网站” -> “永不允许”, 添加需要屏蔽的网站或者域名…

项目开发过程中实际遇到的几个问题处理

1、今天开发环境运行的时候出现下面问题 The project cannot be built until build path errors are resolved. 出现报错情况&#xff0c;之前也没有遇到过。 根据字面意思“在解决生成路径的错误之前&#xff0c;无法生成项目”&#xff0c;也就是说项目的路径位置配置错误…

【论文速递】CVPR2021 - 基于自引导和交叉引导的小样本分割算法

【论文速递】CVPR2021 - 基于自引导和交叉引导的小样本分割算法 【论文原文】&#xff1a;Self-Guided and Cross-Guided Learning for Few-Shot Segmentation 【作者信息】&#xff1a;Bingfeng Zhang, Jimin Xiao , Terry Qin 获取地址&#xff1a;https://openaccess.the…

来香港饮茶吹水先,免费报名Zabbix Meetup香港站!

Zabbix Meetup 来到香港啦&#xff01; 春暖花开&#xff0c;Zabbix计划5月来到香港&#xff0c;和你一起饮茶吹水&#xff01; 时间&#xff1a;5月某日&#xff0c;周几方便&#xff1f; 预计14:00-17:00 形式&#xff1a;线下交流会&#xff0c;免费&#xff0c;线下&…

测评自养号优势,亚马逊,速卖通、美客多、Newegg等跨境卖家必看!

随着跨境电商的发展&#xff0c;越来越多有实力的商家加入到跨境电商的行列&#xff0c;导致行业竞争越来越大&#xff0c;成本投入也越来越高&#xff0c;原来的跨境蓝海已经变红海&#xff0c;卖家都不得不靠“烧钱”来提升排名&#xff0c;吸引流量从而维持销量。那么卖家如…

企业电子招投标采购系统——功能模块功能描述

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…

Python数据工程师与数据分析有什么区别?

不少朋友都很困惑&#xff0c;大数据工程师和Python的数据分析师有什么区别&#xff0c;哪一个的就业好薪资高&#xff1f;现在我们一起来探讨下这个问题。 首先我们来区别下大数据工程师和数据分析师&#xff1a; 1、概念区别 Python数据分析师培训出来的数据分析师&#x…

1-springboot基础-练习

1-spring stater project创建 设置springboot项目的下载地址&#xff1a;https://start.aliyun.com/ 创建项目 创建HelloController RestController publicclass HelloController {GetMapping("/hello")public String hello() {return "hello Spring Boot"…

AcWing蓝桥杯辅导课:第三讲 数学与简单DP

AcWing 1205. 买不到的数目 思路&#xff1a; 裴蜀定理: 对任何整数aaa、bbb&#xff0c;存在整数xxx、yyy&#xff0c;使得axby(a,b)ax by (a, b)axby(a,b)&#xff0c; (a,b)(a, b)(a,b)表示aaa、bbb的最大公因数&#xff0c;令d(a,b)d(a, b)d(a,b)。若 d1d 1d1&#xff…