Netty 进阶(七)—— 心跳机制

  • Netty 是如何保持长连接的(心跳)(Netty保证的,应该是使用了TCP的长连接特性)
  • 如何实现心跳保持(IDLE编解码器监听事件)

一、什么是心跳

所谓 心跳, 即在 TCP 长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线,以确定TCP连接的有效性

二、为什么需要心跳

因为网络的不可靠性

有可能在 TCP 保持长连接的过程中, 由于某些突发情况, 例如网线被拔出, 突然掉电等, 会造成服务器和客户端的连接中断. 在这些突发情况下, 如果恰好服务器和客户端之间没有交互的话, 那么它们是不能在短时间内发现对方已经掉线的. 为了解决这个问题, 我们就需要引入 心跳 机制.

三、如何实现心跳

1.使用 TCP 协议层面的 keepalive 机制

基于TCP的keepalive机制,由具体的TCP协议栈来实现长连接的维持。如在netty中可以在创建channel的时候,指定ChannelOption.SO_KEEPALIVE, true参数来实现。

优点:

  1. 使用 TCP 层面的 keepalive 机制比自定义的应用层心跳机制节省流量

缺点:

  1. 它不是 TCP 的标准协议, 并且是默认关闭的
  2. 发送心跳包检测的时间间隔,默认为7200s,即空闲后,每2小时检测一次。①如果客户端在这2小时内断开了,那么服务端也要维护这个连接2小时,浪费服务端资源;②对于需要实时传输数据的场景,客户端断开了,服务端也要2小时后才能发现。
  3. TCP keepalive 与 TCP 协议绑定, 因此如果需要更换为 UDP 协议时, keepalive 机制就失效了

2.在应用层上基于Netty实现自定义的心跳机制

Netty是基于IdleStateHandler实现的,IdleStateHandler是ChannelDuplexHandler的一个实现类,可以对读写IO进行空闲检测。

实例化一个 IdleStateHandler 需要提供三个参数:

  • readerIdleTimeSeconds, 读超时. 即当在指定的时间间隔内没有从 Channel 读取到数据时, 会触发一个 READER_IDLE 的 IdleStateEvent 事件.
  • writerIdleTimeSeconds, 写超时. 即当在指定的时间间隔内没有数据写入到 Channel 时, 会触发一个 WRITER_IDLE 的 IdleStateEvent 事件.
  • allIdleTimeSeconds, 读/写超时. 即当在指定的时间间隔内没有读或写操作时, 会触发一个 ALL_IDLE 的 IdleStateEvent 事件.
public IdleStateHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) {
    this((long)readerIdleTimeSeconds, (long)writerIdleTimeSeconds, (long)allIdleTimeSeconds, TimeUnit.SECONDS);
}

第四个参数表示当前的时间单位。

所以这里可以分别控制读,写,读写超时的时间,单位为秒,如果是0表示不检测,所以如果全是0,则相当于没添加这个 IdleStateHandler,连接是个普通的短连接。

IdleStateHandler 是实现心跳的关键, 它会根据不同的 IO idle 类型来产生不同的 IdleStateEvent 事件, 而这个事件的捕获, 其实就是自定义捕获心跳处理类,然后在 userEventTriggered 方法中实现的.

 四、参考

Netty源码分析-基于Netty的心跳检测机制IdleStateHandler实现长连接_netty长连接多久失效-CSDN博客

Netty 中的心跳机制_netty 心跳-CSDN博客 

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值