https://help.aliyun.com/knowledge_detail/52868.html

    问题现象 原因分析 解决方案
    无法在本地网络环境通过 SSH 连接 Linux 实例,或者访问该 Linux 实例上的 HTTP 业务出现异常。Telnet 测试会被 reset。 如果您的本地网络是 NAT 共享方式上网,该问题可能是由于本地 NAT 环境和目标 Linux 相关内核参数配置不匹配导致。
    尝试通过修改目标 Linux 实例内核参数来解决问题:
    1. 远程连接目标 Linux 实例;
    2. 查看当前配置: cat /proc/sys/net/ipv4/tcp_tw_recyclecat /proc/sys/net/ipv4/tcp_timestamps 查看上述两个配置的值是不是 0,如果为 1的话,NAT 环境下的请求可能会导致上述问题。
    通过如下方式将上述参数值修改为 0:
    1. 执行命令 vi /etc/sysctl.conf
    2. 添加如下内容:net.ipv4.tcp_tw_recycle=0net.ipv4.tcp_timestamps=0
    3. 输入指令 # sysctl -p 使配置生效。
    4. 重新 SSH 登录实例或者业务访问测试。
    服务端 A 与 客户端 B 建立了 TCP 连接,之后服务端 A 主动断开了连接,但是在客户端 B 上仍然看到连接是建立的。 通常是由于修改了服务端内核参数 net.ipv4.tcp_fin_timeout 默认设置所致。 1. 执行命令 vi /etc/sysctl.conf,修改配置:net.ipv4.tcp_fin_timeout=30
    2. 执行命令 # sysctl -p 使配置生效。
    通过 netstat 或 ss 可以看到大量处于 TIME_WAIT 状态的连接。 通过 `netstat -n awk ‘/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}’` 查看 TIME_WAIT 数量。 1. 执行命令 vi /etc/sysctl.conf,修改或加入以下内容:
    1. net.ipv4.tcp_syncookies = 1
      net.ipv4.tcp_tw_reuse = 1
      net.ipv4.tcp_tw_recycle = 1
      net.ipv4.tcp_fin_timeout = 30
    2. 执行命令 /sbin/sysctl -p 使配置生效。 | | 服务器上出现大量 CLOSE_WAIT 状态的连接数。 | 根据实例上的业务量来判断 CLOSE_WAIT 数量是否超出了正常的范围。TCP 连接断开时需要进行四次挥手,TCP 连接的两端都可以发起关闭连接的请求,若对端发起了关闭连接,但本地没有进行后续的关闭连接操作,那么该链接就会处于 CLOSE_WAIT 状态。虽然该链接已经处于半开状态,但是已经无法和对端通信,需要及时的释放该链接。建议从业务层面及时判断某个连接是否已经被对端关闭,即在程序逻辑中对连接及时进行关闭检查。 | 通过命令 netstat -an|grep CLOSE_WAIT|wc -l 查看当前实例上处于 CLOSE_WAIT 状态的连接数。
      Java 语言:
      1. 通过 read 方法来判断 I/O 。当 read 方法返回 -1 时则表示已经到达末尾。
      2. 通过 close 方法关闭该链接。
      C 语言:
      1. 检查 read 的返回值,若是 0 则可以关闭该连接,若小于 0 则查看一下 errno,若不是 AGAIN 则同样可以关闭连接。 | | Linux FIN_WAIT2 状态的 TCP 链接过多。 | HTTP 服务中,SERVER 由于某种原因关闭连接,如 KEEPALIVE 的超时。这样,作为主动关闭的 SERVER 一方就会进入 FIN_WAIT2 状态。但 TCP/IP 协议栈中,FIN_WAIT2 状态是没有超时的(不像 TIME_WAIT 状态),如果 Client 不关闭,FIN_WAIT_2 状态将保持到系统重启,越来越多的 FIN_WAIT_2 状态会致使内核 Crash。 | 1. 执行命令 vi /etc/sysctl.conf,修改或加入以下内容:
    3. net.ipv4.tcp_syncookies = 1
      net.ipv4.tcp_fin_timeout = 30
      net.ipv4.tcp_max_syn_backlog = 8192
      net.ipv4.tcp_max_tw_buckets = 5000
    4. 执行命令 # sysctl -p 使配置生效。 | | 查询服务器 /var/log/message 日志,发现全部是类似如下 kernel: TCP: time wait bucket table overflowt 的报错信息,报错提示 TCP time wait 溢出,见图三。 | TCP 连接使用很高,容易超出限制。 | 1. 执行命令 netstat -anp |grep tcp |wc -l统计 TCP 连接数。
      2. 对比 /etc/sysctl.conf 配置文件的 net.ipv4.tcp_max_tw_buckets 最大值,看是否有超出情况。
      3. 执行命令 vi /etc/sysctl.conf,查询 net.ipv4.tcp_max_tw_buckets 参数。如果确认连接使用很高,容易超出限制。
      4. 调高参数 net.ipv4.tcp_max_tw_buckets,扩大限制。
      5. 执行命令 # sysctl -p 使配置生效。 | | Linux 实例出现间歇性丢包的情况,通过 tracert, mtr 等手段排查,外部网络未见异常。同时,如下图所示,在系统日志中重复出现大量kernel nf_conntrack: table full, dropping packet.错误信息。 | ipconntrack 是 Linux 系统内 NAT 的一个跟踪连接条目的模块。ip_conntrack 模块会使用一个哈希表记录 TCP 通讯协议的 established connection 记录,当哈希表满了的时候,会导致 _nf_conntrack: table full, dropping packet 错误。需要通过修改内核参数来调整 ip_conntrack 限制。 | Centos 5.x 系统
      1. 使用管理终端登录实例。
      2. 执行命令 # vi /etc/sysctl.conf 编辑系统内核配置。
      3. 修改哈希表项最大值参数:net.ipv4.netfilter.ip_conntrack_max = 655350
      4. 修改超时时间参数:net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1200,默认情况下 timeout 是5天(432000秒)。
      5. 执行命令 # sysctl -p 使配置生效。

      Centos 6.x 及以上系统:
      1. 使用管理终端登录实例。
      2. 执行命令 # vi /etc/sysctl.conf 编辑系统内核配置。
      3. 修改哈希表项最大值参数:net.netfilter.nf_conntrack_max = 655350
      4. 修改超时时间参数:net.netfilter.nf_conntrack_tcp_timeout_established = 1200,默认情况下 timeout 是5天(432000秒)。
      5. 执行命令 # sysctl -p 使配置生效。 | | 客户端做了 NAT 后无法访问 ECS、RDS,包括通过 SNAT VPC 访问外网的 ECS 。无法访问连接其他 ECS 或 RDS 等云产品,抓包检测发现远端对客户端发送的 SYN 包没有响应。 | 若远端服务器同时开启 net.ipv4.tcp_tw_recycle 和 net.ipv4.tcp_timestamps,即参数取值为 1 时,服务器会检查每一个报文的时间戳(Timestamp),若 Timestamp 不是递增的关系,则不做处理。做了 NAT 后,服务器看到来自不同的客户端的 IP 相似,但 NAT 前每一台客户端的时间可能会有偏差,在服务器上就会看到 Timestamp 不是递增的情况。 | - 远端服务器为 ECS:
      修改参数 net.ipv4.tcp_tw_recycle 为 0。
      - 远端服务器为 RDS 等 PaaS 服务:
      RDS 无法直接修改内核参数,需要在客户端上修改参数 net.ipv4.tcp_tw_recycle 和 net.ipv4.tcp_timestamps 为 0。 | | | | |