线上个别机器访问公网地址时出现tcp请求超时或无响应处理方案

问题描述:

线上环境有多个实例,分别在不同的机房。正常情况下没问题,但每当同机房下,添加新的实例服务器后,在这台新的实例上就会偶发出现请求超时或无响应的情况。并发量越大,出现的概率越高。ping正常。curl或正常http请求时,就会偶发出现该问题。

故障定位

首先,梳理网络流程。服务器在访问公网地址时,会经过nat网关转换到公网的地址,然后再去访问目标地址。

其次,分别在服务器,nat服务器,目标服务器通过tcpdump抓包。通过分析出现问题时的数据包发现,服务器,nat服务器都是只有发送的syn包,而没有收到目标服务返回的ack确认包。由于没有收到ack确认包,服务器一直重试发送syn包。

最后,通过调研内核参数,发现参数net.ipv4.tcp_timestamps用来校验同源公网Ip的时间戳。经过nat之后,如果前面相同的端口被使用过,且时间戳大于这个链接发出的syn中的时间戳,服务器上就会忽略掉这个syn,不返会syn-ack消息,表现为用户无法正常完成tcp 3次握手,导致连接超时或无响应。
在业务闲时,如果用户nat的端口没有被使用过时,就可以正常打开;业务忙时,nat端口重复使用的频率高,很难分到没有被使用的端口,从而产生这种问题。

解决方案

net.ipv4.tcp_timestamps 默认值为1,即开启时间戳的校验。并且只有客户端服务和服务端都开启时,才会出现该问题。

于是,将服务端的net.ipv4.tcp_timestamps设置为0后,解决该问题。

你可能感兴趣的:(nginx)