(2012-02-01 18:40:32)     近来线上陆续出现了一些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/u/2015038597

相关链接:http://blog.csdn.net/wireless_tech/article/details/6405755

【转】tcp_tw_recycle和tcp_timestamps导致connect失败问题的更多相关文章

  1. tcp_tw_recycle和tcp_timestamps导致connect失败问题

    把服务里面的net.ipv4.tcp_timestamps这个参数设置为0后已经可以正常telnet通了. 具体设置方法: 在/etc/sysctl.conf  里面加入 net.ipv4.tcp_t ...

  2. tcp_tw_recycle和tcp_timestamps的文章汇总

        临近年关,人会变得浮躁,期间写的代码可谓乱七八糟.不过出来混始终是要还的,这不最近就发现一个PHP脚本时常连不上服务器. 遇到这类问题,我习惯于先用strace命令跟踪了一下看看: shell ...

  3. "错误消息 401.2。: 未经授权: 服务器配置导致登录失败。"的解决办法

    [详细报错如下]: “/”应用程序中的服务器错误. 访问被拒绝. 说明: 访问服务此请求所需的资源时出错.服务器可能未配置为访问所请求的 URL. 错误消息 401.2.: 未经授权: 服务器配置导致 ...

  4. VS2012 asp.net mvc 4 运行项目提示:"错误消息 401.2。: 未经授权: 服务器配置导致登录失败"

    创建mvc4 应用程序发布,运行出错.出现未经授权: 服务器配置导致登录失败.请验证您是否有权基于您提供的凭,后来找得解决方法: 打开点站的web.confg文件,将: <authorizati ...

  5. IIS7部署项目时提示:"错误消息 401.2。: 未经授权: 服务器配置导致登录失败。"的解决办法

    这个错误的定位:你的站点使用了Forms验证,而且在部署在生产环境的时候,设置错误,或者注释了. 解决方法如下: 1.检查Forms配置是否屏蔽. 2.有权限访问的资源是否已经开发. 基本就围绕以上两 ...

  6. Android中连接蓝牙设备时遇到createRfcommSocketToServiceRecord的UUID问题和BluetoothSocket的connect失败

    [问题] 折腾: [记录]编写Android中的蓝牙模块驱动和底层HART设备 期间,参考: Bluetooth | Android Developers – ManagingAConnection ...

  7. 同一个tomcat部署多个项目导致启动失败

    内容描述在同一个tomcat部署多个打包成war包的项目导致启动失败,报错如下: 报错信息Error starting ApplicationContext. To display the condi ...

  8. idea在maven打包时运行Test测试, 导致打包失败, 乱七八糟的错误

    在maven打包时运行Test测试, 导致打包失败, 乱七八糟的错误 在maven projects中图标toggle'skip Tests' Mode //宏杰帮助 网上案例:https://blo ...

  9. swap空间不够导致安装失败解决方法

    在安装Oracle的时候,可能因为我们分配的swap空间不够导致安装失败.处理步骤如下: SWAP空间为2G [root@linux01 oracle]# free            total  ...

随机推荐

  1. iOS应用截屏

    iPhone自从推出后就自带了截屏功能,简单而易用,所以应用就没什么截屏的需求了,不过有些时候我们还是会遇到这个需求.比如,我们开发了一个播放器,用openGL进行video render,此时直接截 ...

  2. Scala的=>作用

    举例: var increase = (x: Int) => x + 1 increase(10) res0: Int = 11 类似于转化符号,=>指明这个函数把左边的东西(任何整数x) ...

  3. 【深度学习笔记】Anaconda及开发环境搭建

    在学习了一段时间台大李宏毅关于deep learning的课程,以及一些其他机器学习的书之后,终于打算开始动手进行一些实践了. 感觉保完研之后散养状态下,学习效率太低了,于是便想白天学习,晚上对白天学 ...

  4. hadoop之 解析HDFS的写文件流程

    文件是如何写入HDFS的 ? 下面我们来先看看下面的“写”流程图:  假如我们有一个文件test.txt,想要把它放到Hadoop上,执行如下命令: 引用         # hadoop fs  - ...

  5. 使用Navicat for Oracle新建表空间、用户及权限赋予 (转)

    Navicat for Oracle是有关Oracle数据库的客户端工具.通过这个客户端,我们可以图形方式对Oracle数据库进行操作. 说明我们此次试验的Oracle数据库版本是Oracle 10G ...

  6. centos下svn的主要常用命令(解决商城系统添加的文件无法自动更新至svn服务器)

    问题描述: 在商城中通过网页上传的png文件无法自动添加到版本库中. 查找过程: 通过程序分析,增加的主要是数据文件,主要分布在data目录中. svn list /home/ggg --depth= ...

  7. requirejs 到底有什么好处?

    无论是在backbone时代,还是angularjs 时代 我都用过requirejs, 后来慢慢全都去掉了, 因为在前端开发requirejs 感觉没有带来任何实质性的好处. 从几个方面说说我的感受 ...

  8. jdk1.8新特性之接口default方法

    众所周知,default是java的关键字之一,使用场景是配合switch关键字用于条件分支的默认项.但自从java的jdk1.8横空出世以后,它就被赋予了另一项很酷的能力——在接口中定义非抽象方法. ...

  9. protobuf接口调用报错:java.nio.charset.MalformedInputException: Input length = 1

    使用protobuf定义的接口api发起http请求报错,日志如下: [-- ::] DEBUG AbstractPool: - server updated, node=, server={ nod ...

  10. Mac下docker搭建lnmp环境 + redis + elasticsearch

    之前在windows下一直使用vagrant做开发, 团队里面也是各种开发环境,几个人也没有统一环境,各种上线都是人肉,偶尔还会有因为开发.测试.生产环境由于软件版本或者配置不一致产生的问题, 今年准 ...