linux内核net.ipv4.tcp_tw_recycle调优记录

之前nginx服务器老是503,搭建了gitlab 为了优化服务器,内核做了一些参数调优,其中一条如下

net.ipv4.tcp_tw_recycle = 1

作用就是:开启TCP连接中TIME-WAIT sockets的快速回收
开启这个参数之后服务器对于高并发TCP连接有了更高的处理性能,但是会出来一个新的问题:
在公司内网linux客户端curl访问nginx网站,有一部分机器正常,另外一部分会出现偶尔curl失败的情况。
服务器端抓包只能抓到syn请求,但服务器不响应。
最后找了很多资料,发现是这个参数的问题,关掉之后故障瞬间消失。

tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
              Enable fast recycling of TIME_WAIT sockets.  Enabling this option is not recommended since this causes problems when working with NAT (Network Address
              Translation).

开启tcp_tw_recycle会启用tcp time_wait的快速回收,这个参数不建议在NAT环境中启用,它会引起相关问题。
故障原理:
tcp_tw_recycle是依赖tcp_timestamps参数的,在一般网络环境中,可能不会有问题,但是在NAT环境中,问题就来了。一般办公室的外网地址只有一个,所有人访问后台都会通过路由器做SNAT将内网地址映射为公网IP,由于服务端和客户端都默认启用了tcp_timestamps,因此TCP头部中增加时间戳信息,而在服务器看来,同一客户端的时间戳必然是线性增长的,但是,由于客户端网络环境是NAT,因此每台主机的时间戳都是有差异的,在启用tcp_tw_recycle后,一旦有客户端断开连接,服务器可能就会丢弃那些时间戳较小的客户端的SYN包,这也就导致了网站访问极不稳定。