最近将一个业务迁移到阿里云VPC虚拟专网下,但是迁移后发现从公司网络下访问阿里云的80端口业务频繁出现连接不通的问题,抓包发现存在大量从公司IP到阿里云虚拟专网IP的TCP Retransmission出现。
从图中可以看到从我们办公网络访问80端口大量SYN重传,这也就是说在三次握手的第一步中就被重传了。换言之在主动发起SYN后如果没有收到服务器放的ACK确认,就会导致重传的发生,因为客户端机器认为远程机器没有收到包,而发生重新发送SYN包的事件。
既然在服务器上抓包能捕获SYN的请求,那就说明服务器端接收到了请求但是没有回应ACK包,于是想起了以前nat环境下tw_recyle的坑,当多个客户端使用同一个外网IP通过NAT访问内网服务器的时候,服务器如果在内核参数中打开了net.ipv4.tcp_tw_recycle = 1
就有可能导致服务器收到SYN但是不会向客户端发送SYN+ACK包。因为打开recyle参数后会识别这些包的时间戳(net.ipv4.tcp_timestamps = 1),但是nat过来的数据包又因为时间戳有可能不是顺序的,导致服务器认为包不可信而丢弃。
故当我们在使用阿里云的VPC虚拟专网的时候,使用弹性IP接入,一定要注意NAT的问题,在服务器参数上关闭net.ipv4.tcp_tw_recycle。 否则从一个ip来的不同客户端请求很有可能导致大量请求失败