NoOps

Ops make no ops | Ops的目标是没有Ops,嗯!

tcp协议timestamp字段导致问题分析

作者: |   12,311 浏览  | 

1.现象 不同主机C1,C2上的相同模块(开启timestamp),通过NAT网关(1个出口ip)访问同一服务S,主机C1 connect成功,而主机C2 connect失败
2.分析 根据现象上述问题明显和tcp timestmap有关;查看linux 2.6.32内核源码,发现tcp_tw_recycle/tcp_timestamps都开启的条件下,60s(timewai时间)内同一源ip主机的socket connect请求中的timestamp必须是递增的。
3.验证
server端当tcp_tw_recycle和tcp_timestamps都是1的时候,会检查收到数据包TCP选项字段中的的timestamp(TS Value),当来自同一个IP地址(任意源端口号)后来的数据包中TCP选项字段如果有timestamp且比前面的数据包中的timestamp小,则server不做ACK响应
4.解决方法
1.服务器端不要将tcp_tw_recycle字段和tcp_timestamps字段同时设为1
2.客户端把tcp_timestamps字段设0,这样不会发送TCP选项字段中的timestamps选项
对于服务提供方1较适合
引用:
个人建议关闭tcp_tw_recycle选项,而不是timestamp;因为 在tcp timestamp关闭的条件下,开启tcp_tw_recycle是不起作用的;而tcp timestamp可以独立开启并起作用。

6 Comments

  1. 2013/05/09 at 12:21 下午

    关闭tcp_tw_recycle + 开启timestamp = 不进行TimeWait回收

    如何解决TimeWait数量高的问题呢? 像淘宝是在内核里加了TimeWait超时时间的设定。

    默认内核TimeWait超阀值就一直报信息出来,都关不掉。

    这问题你们怎么看?

    • siyu
      2013/05/09 at 12:44 下午

      没有经过特别编译的内核没有开放sysctl修改tcp_tw参数
      淘宝内核组自己定制的内核对这个参数进行的修改。如果没记错的话是15s吧
      默认的我看过貌似是120s/30s?可以通过测试查看netstat里的连接状态大致得出

      tcp_max_tw_buckets 可以适当的提高这个值来解决你的问题。

  2. 2013/05/09 at 12:23 下午

    而且在你们的文章“Haproxy作为MySQL中间层如何避免TCP端口耗尽” http://noops.me/?p=252
    中就推荐大家用
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1

    冲突啊冲突!!

  3. netzhou
    2013/07/04 at 7:57 下午

    有用netstat -s|grep rejectd确认过?正确的做法应该是net.ipv4.tcp_timestamps = 0
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_tw_reuse = 1

  4. 张冬生
    2014/01/06 at 4:18 下午

    让应用服务器监听在多个端口上增加服务器IP

  5. 2014/02/13 at 11:06 上午

    昨天发现有台服务器的设置是:
    net.ipv4.tcp_timestamps = 1
    net.ipv4.tcp_tw_recycle = 0
    然后发现:
    telnet 127.0.0.1 80时通时不通,telnet 127.0.0.1 22 却好好的,然后把设置改成:
    net.ipv4.tcp_timestamps = 0
    net.ipv4.tcp_tw_recycle = 0
    问题就消失了,求大神解答。

张冬生 进行回复 取消回复