这两天遇到一个奇怪的TCP连接超时问题:
org.apache.http.conn.ConnectTimeoutException: Connect to xxxxxx.com:80 [xxxxxxx.com/122.2.334.233] failed: connect timed out

咋一看,这就是网络不通呀!但是ping测试和Telnet测试都没问题,而且time out是偶发的,这就奇怪了,难道是网络抖动?
又看了眼网络监控,出口没有任何丢包,那就只能在服务器上面抓包分析了:
[TCP Retransmission]连接问题_连接超时
通过上面抓出来包,发现出现连接超时的时候有大量的[TCP Retransmission]连接,说明是服务端没有回包呀!为什么没有回包呢?遂上网查了一下,发现有一种情况跟我们很类似,我们使用的是阿里云的VPC网络,客户端有三台都是走的同一个IP的NAT网关出公网,数据包通过NAT网关后源IP会变成NAT地址,如果服务端开启了net.ipv4.tcp_tw_recycle=1(tcp快速回收),数据包到达服务端后发出的TPC/IP时间戳不连续,服务端就会识别错乱丢弃连接;
之后询问了服务端的人员,果然是这个原因!修改后就好了。

 

【案例分析2】

网上的帖子,大多都写开启net.ipv4.tcp_tw_recycle这个开关,可以快速回收处于TIME_WAIT状态的socket(针对Server端而言)。

 

而实际上,这个开关,需要net.ipv4.tcp_timestamps(默认开启的)这个开关开启才有效果。
更不为提到却很重要的一个信息是:当tcp_tw_recycle开启时(tcp_timestamps同时开启,快速回收socket的效果达到),对于位于NAT设备后面的Client来说,是一场灾难——会导到NAT设备后面的Client连接Server不稳定(有的Client能连接server,有的Client不能连接server)。也就是说,tcp_tw_recycle这个功能,是为“内部网络”(网络环境自己可控——不存在NAT的情况)设计的,对于公网,不宜使用。

通常,“回收”TIME_WAIT状态的socket是因为“无法主动连接远端”,因为无可用的端口,而不应该是要回收内存(没有必要)。即,需求是“Client”的需求,Server会有“端口不够用”的问题吗?除非是前端机,需要大量的连接后端服务——即充当着Client的角色。
正确的解决这个总是办法应该是:
net.ipv4.ip_local_port_range = 9000 65535 #默认值范围较小
net.ipv4.tcp_max_tw_buckets = 10000 #默认值较小,还可适当调小
net.ipv4.tcp_tw_reuse = 1 #
net.ipv4.tcp_fin_timeout = 10 #
————————————————
版权声明:本文为CSDN博主「天府云创」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/enweitech/article/details/79261439