欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

理解Netty的keepalive和idle检测机制

最编程 2024-08-02 18:56:34
...

1 为什么需要keepalive ?

  • 类比如下场景

网络异常,图片无法展示
|

网络异常,图片无法展示
|

2 怎么设计keepalive

以TCP keepalive为例

TCP keepalive 核心参数:

# sysctl -algrep tcp_ keepalive
net.ipv4.tcp_ keepalive_ time = 7200 问题出现概率小,没有必要频繁
net.ipv4.tcp_ keepalive_ intvl= 75
net.ipv4.tcp_ keepalive_ probes= 9 判断需谨慎,不能武断

当启用( 默认关闭) keepalive 时,TCP在连接没有数据通过的7200秒后发送keepalive消息,当探测没有确认按75秒的重试频率重发,一直发 9个探测包都没有确认,连接失效。


所以总耗时一般为: 2小时11分钟(7200秒+xxs)


当启用( 默认关闭) keepalive 时,TCP在连接没有数据通过的7200秒后发送keepalive消息,当探测没有确认按75秒的重试频率重发,一直发 9个探测包都没有确认,连接失效。


所以总耗时一般为: 2小时11分钟(7200秒+xxs)


3 为什么还需要应用层keepalive?

协议分层

各层关注点不同:

  • 传输层关注是否“通”
  • 应用层关注是否可服务
    类比前面的电话订餐例子,电话能通,不代表有人接
    服务器连接在,但是不一定可以服务(例如服务不过来等)。

TCP层的keepalive默认关闭

且经过路由等中转设备keepalive包可能会被丢弃。

TCP层的keepalive时间太长

默认>2小时,虽然可改,但属于系统参数,改动影响所有应用。


HTTP属于应用层协议,但是常常听到名词“HTTP Keep-Alive "指的是对长连接和短连接的选择:


  • Connection : Keep-Alive长连接(HTTP/1.1默认长连接,不需要带这个header)
  • Connection : Close短连接

4 Idle监测

为何要有 idle 检测

假设你开个饭店,客户订餐电话通后,订餐的说了订餐要求,说着说着对方就不讲话了。

你并不会立马问:你还在吗?而是会稍微等待一定的时间, 在这个时间内看看对方还会不会说话(Idle 检测) 。

如果还不说,认定对方存在问题(Idle) ,于是开始


  • 问“你还在么?”(keepalive )
  • 或者问都不问干脆直接挂机(关闭连接)


ldle监测,只是负责诊断,诊断后,做出不同的行为,决定ldle监测的最终用途:

发送keepalive :一般用来配合keepalive,减少keepalive消息

Keepalive设计演进 V2


  • V1定时keepalive消息:keepalive消息与服务器正常消息交换完全不关联,定时就发送
  • V2空闲监测:有其他数据传输的时候,不发送keepalive,无数据传输超过一定时间,判定为Idle,再发keepalive

什么是 idle

如果是直接关闭连接

  • 快速释放损坏的、恶意的、很久不用的连接,让系统时刻保持最好的状态
  • 简单粗暴,客户端可能需要重连。

所以在实际应用 Netty 会结合起来使用。按需keepalive,保证不会空闲,如果空闲,关闭连接。

5 Netty中开启TCP keepalive和Idle检测

开启keepalive:

Server 端开启 TCP keepalive

bootstrap.childOption(ChannelOption.S0_ KEEPALIVE,true)
bootstrap.childOption(NioChannelOption.of(StandardSocketOptions.SO_KEEPALIVE), true)

提示: .option(ChannelOption.SO_KEEPALIVE,true) 存在但是无效

开启不同的 idle Check:

ch.pipeline().addLast( "idleCheckHandler", newldleStateHandler(0, 
                    20, 0, TimeUnit.SECONDS));

网络异常,图片无法展示
|

推荐阅读