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,修改或加入以下内容: |
- net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30 - 执行命令
/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,修改或加入以下内容: - 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 - 执行命令
# 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。 | | | | |
