TCP keepalive长连接心跳保活

摘要:
net.ipv4.tcp_tw_recycle选项可能引起这个问题,于是关闭了这个选项,问题果然得以解决。有些服务器为了避免TIME_WAIT状态占用连接,希望能加快TIME_WAIT状态的回收,通常将net.ipv4.tcp_tw_recycle选项开启。当然这个选项的生效要依赖net.ipv4.tcp_timestamps选项的开启。我们先看下tcp_tw_recycle选项的工作机制:当开启了tcp_tw_recycle选项后,当连接进入TIME_WAIT状态后,会记录对应远端主机最后到达分节的时间戳。

比如:客户端与服务端进行握手时,经常无法握手成功,收不到回复; 需要建立保活机制。

1. 服务端Linux服务器新增系统内核参数配置。

在/etc/sysctl.conf文件中再添加如:

#允许的持续空闲时长,在TCP保活打开的情况下,最后一次数据交换到TCP发送第一个保活探测包的间隔,即允许的持续空闲时长,或者说每次正常发送心跳的周期,默认值为7200s(2h)。
net.ipv4.tcp_keepalive_time=1800#在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包的发送频率,
net.ipv4.tcp_keepalive_intvl=30#在tcp_keepalive_time之后,没有接收到对方确认,继续发送保活探测包次数
net.ipv4.tcp_keepalive_probes=3

执行sysctl -p来使它生效:
检测一下是否已经生效:sysctl -a | grep keepalive

2. Java/netty服务器中配置使用

ServerBootstrap bootstrapHttp =new ServerBootstrap(newNioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
bootstrapHttp.setPipelineFactory(newHttpServerPipelineFactory());
bootstrapHttp.setOption("child.tcpNoDelay", true);
bootstrapHttp.setOption("child.keepAlive", true);bootstrapHttp.bind(newInetSocketAddress(ip, http_port));

3.关闭tcp_timestamps选项

客户在服务端开启了某个端口,但是在客户端telnet确一直不通。通过在服务端抓包发现,客户端的syn分节已经到达,但是服务端并没有应答。
net.ipv4.tcp_tw_recycle选项可能引起这个问题,于是关闭了这个选项,问题果然得以解决。这里分析一下原因。
有些服务器(当然客户端也可以)为了避免TIME_WAIT状态占用连接,希望能加快TIME_WAIT状态的回收,通常将net.ipv4.tcp_tw_recycle选项开启。
当然这个选项的生效要依赖net.ipv4.tcp_timestamps选项的开启。虽然开启这个选项能够加快TIME_WAIT连接的回收,但却引入了另一个问题。我们先看下tcp_tw_recycle选项的工作机制:
当开启了tcp_tw_recycle选项后,当连接进入TIME_WAIT状态后,会记录对应远端主机最后到达分节的时间戳。如果同样的主机有新的分节到达,且时间戳小于之前记录的时间戳,即视为无效,相应的数据包会被丢弃(rfc1323)。
Linux是否启用这种行为取决于tcp_timestamps和tcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了

在/etc/sysctl.conf文件中再添加如:
#不检查请求的时间戳

net.ipv4.tcp_timestamps=0

免责声明:文章转载自《TCP keepalive长连接心跳保活》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#利用RabbitMQ实现点对点消息传输LeetCode刷题笔记(3)Java位运算符与使用按位异或(进制之间的转换)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

QT TCP/IP

QT网络通信(TCP/IP) 服务端: 一、监听新的客户端接入(QTcpServer) 重写函数 incomingConnection(qintptr socketDescriptor) 二、服务端每个客户的监听(QTcpSocket 完成三件事1、监听是否有数据传来。2、监听连接是否中断。3、写数据) 1、数据传来时有readyRead()信号。将都数据...

DISPLAY变量和xhost(原创)

DISPLAY 在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处. 直接登陆图形界面或者登陆命令行界面后使用startx启动图形, DISPLAY环境变量将自动设置为:0:0, 此时可以打开终端, 输出图形程序的名称(比如xclock)来启动程序, 图形将显示在本地窗口上, 在终端上输入printenv查看当前环境变量, 输出结...

snowflake 分布式唯一ID生成器

本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 原文参考运维生存和开源中国上的代码整理 我的环境是python3.5,pip8.2的 一、python版本 前言 由于考虑到以后要动态切分数据,防止将不同表切分数据到同一个表中时出现主键相等的冲突情况,这里我们使用...

Socket 编程中,TCP 流的结束标志与粘包问题

因为 TCP 本身是无边界的协议,因此它并没有结束标志,也无法分包。「包」的界定,是更上层的协议的事了(比如 HTTP)。 socket和文件不一样,从文件中读,读到末尾就到达流的结尾了,所以会返回-1或null,循环结束,但是socket是连接两个主机的桥梁,一端无法知道另一端到底还有没有数据要传输。socket如果不关闭的话,read之类的阻塞函数会一...

DB2时间函数大全(转)

原文出处:http://database.51cto.com/art/201011/232578.htm 1 --获取当前日期: 2 3 select current date from sysibm.sysdummy1; 4 values current date; 5 6 --获取当前日期 7 select cu...

js 时间戳转换为‘yyyy-MM-dd hh:mm’格式(es6语法)

function formatDate(date,fmt) { if(/(y+)/.test(fmt)){ fmt = fmt.replace(RegExp.$1,(date.getFullYear()+'').substr(4-RegExp.$1.length)); } let o = { 'M+':date.getMonth...