tcp_tw_recycle和tcp_timestamps导致connect失败问题

本文分析了线上出现的connect失败问题,发现与proc参数tcp_tw_recycle/tcp_timestamps相关。通过对Linux内核源码的深入研究,明确了问题原因,并提出了关闭tcp_tw_recycle的解决方案。

近来线上陆续出现了一些connect失败的问题,经过分析试验,最终确认和proc参数tcp_tw_recycle/tcp_timestamps相关;

1. 现象

第一个现象:

模块A通过NAT网关访问服务S成功,而模块B通过NAT网关访问服务S经常性出现connect失败,抓包发现:服务S端已经收到了syn包,但没有回复synack;另外,模块A关闭了tcp timestamp,而模块B开启了tcp timestamp;

第二个现象:

不同主机上的模块C(开启timestamp),通过NAT网关(1个出口ip)访问同一服务S,主机C1 connect成功,而主机C2 connect失败;

2. 分析

根据现象上述问题明显和tcp timestmap有关;查看linux 2.6.32内核源码,发现tcp_tw_recycle/tcp_timestamps都开启的条件下,60s内同一源ip主机的socket connect请求中的timestamp必须是递增的。
源码函数:tcp_v4_conn_request(),该函数是tcp层三次握手syn包的处理函数(服务端);
源码片段:

if (tmp_opt.saw_tstamp &&
        tcp_death_row.sysctl_tw_recycle &&
        (dst = inet_csk_route_req(sk, req)) != NULL &&
        (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
        peer->v4daddr == saddr) {
        if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
            (s32)(peer->tcp_ts - req->ts_recent) >
                        TCP_PAWS_WINDOW) {
            NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
            goto drop_and_release;
        }
    }
    tmp_opt.saw_tstamp:该socket支持tcp_timestamp
    sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项
    TCP_PAWS_MSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内
    TCP_PAWS_WINDOW:1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于 本次tcp

分析:主机client1和client2通过NAT网关(1个ip地址)访问serverN,由于timestamp时间为系统启动到当前的时间,因此,client1和client2的timestamp不相同;根据上述syn包处理源码,在tcp_tw_recycle和tcp_timestamps同时开启的条件下,timestamp大的主机访问serverN成功,而timestmap小的主机访问失败;

参数:

  • /proc/sys/net/ipv4/tcp_timestamps - 控制timestamp选项开启/关闭
  • /proc/sys/net/ipv4/tcp_tw_recycle - 减少timewait socket释放的超时时间

3. 解决方法

echo 0 > /proc/sys/net/ipv4/tcp_tw_recycle;

tcp_tw_recycle默认是关闭的,有不少服务器,为了提高性能,开启了该选项;
为了解决上述问题,个人建议关闭tcp_tw_recycle选项,而不是timestamp;因为 在tcp timestamp关闭的条件下,开启tcp_tw_recycle是不起作用的;而tcp timestamp可以独立开启并起作用。

源码函数: tcp_time_wait()
源码片段:

if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
    recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
......

if (timeo < rto)
    timeo = rto;

if (recycle_ok) {
    tw->tw_timeout = rto;
} else {
    tw->tw_timeout = TCP_TIMEWAIT_LEN;
    if (state == TCP_TIME_WAIT)
        timeo = TCP_TIMEWAIT_LEN;
}

inet_twsk_schedule(tw, &tcp_death_row, timeo,
           TCP_TIMEWAIT_LEN);

timestamp和tw_recycle同时开启的条件下,timewait状态socket释放的超时时间和rto相关;否则,超时时间为TCP_TIMEWAIT_LEN,即60s;

内核说明文档 对该参数的介绍如下:
tcp_tw_recycle - BOOLEAN
Enable fast recycling TIME-WAIT sockets. Default value is 0.
It should not be changed without advice/request of technical
experts.

转载地址:http://blog.sina.com.cn/s/blog_781b0c850100znjd.html

### `tcp_tw_reuse` `tcp_tw_recycle` 的区别 `tcp_tw_reuse` 允许将处于 `TIME_WAIT` 状态的套接字重新用于新的 TCP 连接,前提是该连接的四元组(源IP、源端口、目的IP、目的端口)未发生变化,并且新连接的时间戳大于旧连接的最后时间戳。这种机制特别适用于客户端频繁发起短连接的场景,可以有效减少因大量 `TIME_WAIT` 状态连接导致的资源占用问题。此功能在启用时不需要依赖于对端 IP 的时间戳单调性[^3]。 而 `tcp_tw_recycle` 则是通过更激进的方式快速回收 `TIME_WAIT` 状态的连接。它基于 per-host 的 PAWS(Protect Against Wrapped Sequence)机制,即服务端会缓存每个远程 IP 地址的最新时间戳值。当收到同一 IP 的新数据包时,如果其携带的时间戳小于之前记录的值,则认为这是一个过期的数据包并将其丢弃,从而提前终止 `TIME_WAIT` 状态[^2]。这种方式可以在一定程度上加速连接的关闭过程,但存在一定的使用限制。 两者的主要区别在于: - **作用粒度不同**:`tcp_tw_reuse` 是针对连接的四元组进行检查复用;而 `tcp_tw_recycle` 是基于对端 IP 地址级别的检查[^2]。 - **适用环境不同**:`tcp_tw_reuse` 更加通用,适合大多数网络环境;相比之下,`tcp_tw_recycle` 在 NAT 环境下可能会出现问题,因为多个客户端共享相同的公网 IP 地址,它们之间的时间戳可能不一致,这会导致服务器错误地丢弃合法的新连接请求[^2]。 - **安全性与稳定性考虑**:由于 `tcp_tw_recycle` 对时间戳的要求更为严格,在某些情况下可能导致连接失败率上升,尤其是在客户端设备时间不同步的情况下。因此,在实际部署中通常建议优先使用 `tcp_tw_reuse` 而谨慎对待 `tcp_tw_recycle`[^1]。 ### 配置方法 要临时开启或关闭这些功能,可以通过修改对应的内核参数文件实现: ```bash # 开启 tcp_tw_reuse echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse # 关闭 tcp_tw_reuse echo 0 > /proc/sys/net/ipv4/tcp_tw_reuse # 开启 tcp_tw_recycle echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle # 关闭 tcp_tw_recycle echo 0 > /proc/sys/net/ipv4/tcp_tw_recycle ``` 为了使配置永久生效,应将相应的设置写入 `/etc/sysctl.conf` 文件中,并执行 `sysctl -p` 命令加载新的配置。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值