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 keepalive2. Java/netty服务器中配置使用
ServerBootstrap bootstrapHttp =new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));bootstrapHttp.setPipelineFactory(new HttpServerPipelineFactory());bootstrapHttp.setOption("child.tcpNoDelay", true);bootstrapHttp.setOption("child.keepAlive", true);bootstrapHttp.bind(new InetSocketAddress(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