zoukankan      html  css  js  c++  java
  • 服务端tcp syn无响应,无回复

    说一下现象是用tpcping 域名 443端口会时断时续的,还很有规律,web页面登录状态也会不断的失效,通过客户端,网关出口,clb,后端 rs抓包查看发现,客户端到clb都正常,clb把tcp syn请求转发给后端rs, rs没有回应

    通过查阅资料,发现tcp_timestamps默认是开启,如果再把tcp_tw_recycle设置为1,则60s内同一源ip主机的socket connect请求中的timestamp必须是递增的。
    也就是说服务器打开了 tcp_tw_reccycle了,就会检查时间戳,如果对方发来的包的时间戳是乱跳的或者说时间戳是滞后的,这样服务器肯定不会回复,
    所以服务器就把带了“倒退”的时间戳的包当作是“recycle的tw连接的重传数据,不是新的请求”,于是丢掉不回包,就出现了开始说的syn不响应。 经过nat之后,如果前面相同的端口被使用过,且时间戳大于这个链接发出的syn中的时间戳,服务器上就会忽略掉这个syn,不返会syn
    -ack消息,表现为用户无法正常完成tcp3次握手,
    从而不能打开web页面。在业务闲时,如果用户nat的端口没有被使用过时,就可以正常打开;业务忙时,nat端口重复使用的频率高,很难分到没有被使用的端口,从而产生这种问题。 只有客户端和服务端都开启时间戳的情况下,才会出现能ping通不能建立tcp三次握手的情况 netstat
    -s | grep timestamp

    在nat环境下,因为tcp_tw_recycle=1和net.ipv4.tcp_timestamps=1引起 Nginx upstream timed out 

    故障情况:

    阿里云账号A的A机房,内网里面部署两台Nginx,通过网络出口(NAT),代理用户访问到阿里云账号B的B机房服务。A机房的Nginx出现:upstream timed out 。

    故障的诱因是:net.ipv4.tcp_timestamps=1

    2015的捉包图为:

    直接上当年的笔记:

    先看看TCP IP 对tw的一些解析:
    RFC 1323里有这样的定义:
    An additional mechanism could be added to the TCP, a per-host
    cache of the last timestamp received from any connection.
    This value could then be used in the PAWS mechanism to reject
    old duplicate segments from earlier incarnations of the
    connection, if the timestamp clock can be guaranteed to have
    ticked at least once since the old connection was open. This
    would require that the TIME-WAIT delay plus the RTT together
    must be at least one tick of the sender's timestamp clock.
    Such an extension is not part of the proposal of this RFC.
    大概的中文意思就是:TCP协议中有一种机制,缓存了每个主机(即ip)过来的连接最新的timestamp值。这个缓存的值可以用于PAWS(Protect Against Wrapped Sequence numbers,是一个简单的防止重复报文的机制)中,来丢弃当前连接中可能的旧的重复报文。而Linux实现这个机制的方法就是同时启用net.ipv4.tcp_timestamps和net.ipv4.tcp_tw_recycle 这两个选项。
    这种机制在 客户端-服务器 一对一的时候,没有任何问题,但是当服务器在负载均衡器后面时,由于负载均衡器不会修改包内部的timestamp值,而互联网上的机器又不可能保持时间的一致性,再加上负载均衡是会重复多次使用同一个tcp端口向内部服务器发起连接的,就会导致什么情况呢:

    负载均衡通过某个端口向内部的某台服务器发起连接,源地址为负载均衡的内部地址——同一假如恰巧先后两次连接源端口相同,这台服务器先后收到两个包,第一个包的timestamp被服务器保存着,第二个包又来了,一对比,发现第二个包的timestamp比第一个还老——客户端时间不一致。服务器基于PAWS,判断第二个包是重复报文,丢弃之。

    反映出来的情况就是在服务器上抓包,发现有SYN包,但服务器就是不回ACK包,因为SYN包已经被丢弃了。为了验证这一结果,可以执行netstat -s | grep timestamp 命令,看输出里面passive connections rejected by timestamp 一项的数字变化。

    解决办法:

    tcp_tw_recycle=0 或(和)net.ipv4.tcp_timestamps=0

    查看配置
    cat /proc/sys/net//ipv4/tcp_timestamps
    cat /proc/sys/net//ipv4/tcp_tw_recycle
    
    修改配置
    sysctl -w net.ipv4.tcp_timestamps=0
    sysctl -w net.ipv4.tcp_tw_recycle=0
  • 相关阅读:
    beta分布
    python中os.walk浏览目录和文件
    (zz)Linux下Gcc生成和使用静态库和动态库详解
    GNU scientific library
    python 字典有序无序及查找效率,hash表
    Python代码分析工具之dis模块
    python里的坑。http://www.pythoner.com/356.html
    python实现单向链表
    Python 执行字符串表达式函数(eval exec execfile)
    版本管理神器git上手
  • 原文地址:https://www.cnblogs.com/52py/p/13255095.html
Copyright © 2011-2022 走看看