前言:
现时姐妹们对“nginx代理转发慢”大致比较关切,同学们都想要知道一些“nginx代理转发慢”的相关知识。那么小编同时在网摘上汇集了一些对于“nginx代理转发慢””的相关文章,希望看官们能喜欢,兄弟们一起来了解一下吧!新上线的门户Web系统,发现偶尔打开缓慢甚至打不开,SA通过检查后台Nginx发现一切正常,单独访问Nginx的URL也是正常,于是怀疑是硬件负载故障或者网络故障导致。
怀疑的很合理,于是这个问题通知了NE去检查网络,从故障现象来分析,机房内其他业务系统均运行正常,只有新上线的门户系统出现故障,并且是时好时坏,初步认定机房整体网络正常,负载硬件正常,怀疑是硬件负载针对门户系统的配置有问题,可能是某个member配置错了?登录硬件负载一顿检查配置,发现没问题啊,这就头大了。
这时我们找到了陈局,听完故障现象后,陈局说:"网络交互的问题,是没有抓包定位不到的。"于是我们开始了抓包的动作。
首先我们先看一下门户系统的架构图示意图:
用户通过互联网访问门户系统,门户系统通过硬件负载轮询分发用户请求到4台Nginx,中规中矩的拓扑信息。我们同时在硬件负载和Nginx上抓包(涉及公司服务器IP地址就不上图了),发现在客户端的TCP三次握手已经发送到硬件负载,硬件负载上往后台Nginx转发了SYN报文,服务器没有响应,负载重传了三次后,服务器仍然没有响应,负载就把与客户端的链接RST掉了。
同时在Nginx上抓包可以发现,服务器也确实收到了SYN报文,但就是不响应,这是为什么呢?
通过如下命令检查发现reject在不断增长。
# netstat -s | grep reject23499 passive connections rejected because of time stamp12727 packets rejects in established connections because of timestamp# netstat -s | grep reject23615 passive connections rejected because of time stamp12745 packets rejects in established connections because of timestamp
陈局突然一拍大腿,可能是TCP快速回收导致的,于是通过如下命令检查:
# cat /proc/sys/net/ipv4/tcp_tw_recycle1# cat /proc/sys/net/ipv4/tcp_timestamps1
果不其然,tcp_timestamps和tcp_tw_recycle同时开启了,陈局当场安排SA把TCP快速回收关闭:
sysctl -w net.ipv4.tcp_tw_recycle=0
再次通过命令netstat -s | grep reject被拒绝的报文数,发现已经不再增长,门户访问也正常了。
TCP快速回收为何会导致服务器拒绝TCP SYN的报文呢,我们来分析一下。
中有如下一段描述:
上述意思是TCP链接会缓存检查时间戳,当同一个TCP链接后到的报文比先到的报文时间戳还要小的话,将会丢弃该报文。当然Linux的这种行为是基于tcp_timestamps、tcp_tw_recycle同时开启的情况,Linux默认开启tcp_timestamps,当手动开启tcp_tw_recycle时,就可能会触发该问题。
当然这个故障还有一个重要的因素,就是"同一个TCP链接后到的报文比先到的报文时间戳还要小"。这又是什么原因导致的呢,这里就不卖关子了,NAT导致的。多台客户端经过NAT设备时,源地址会被转换成同一个或者多个地址池地址,甚至会发生端口复用的情况,对于服务端而言就会误认为这是一条TCP链接。客户端的时间戳可能是不一致的,NAT设备又不会去修改tcp时间戳,所以导致在服务端角度看到的tcp时间戳错乱。
结合我们这个案例,了解硬件负载的同学都知道,正常的组网模式下经过负载的报文都会做一次源NAT地址转换,以保证服务器回包时能够回到负载设备上。
好的,那这个时候又有同学会问,tcp time_wait是做什么的?为什么要开tcp_tw_recycle,不开tcp_tw_recycle会有什么问题吗?
如上图所示,TIME_WAIT是出现在TCP断链时主动发起FIN、ACK报文一侧设备的(不一定是服务器端),TIME_WAIT的时间在RFC里定义为2MSL,但实际上服务器是设定的固定值,在生产环境中见过30s、60s、90s。
TIME_WAIT存在的意义有两点:
1、 以上图为例,当Server端收到Client端发来的FIN,ACK后,如果没有TIME_WAIT定时器,直接回复ACK后关闭链接,但是这个ACK在网络中丢失了,Client端收不到ACK的话链接将无法正常关闭;而TIME_WAIT定时器存在的意义就是等待一段时间,如果Client收到ACK了就不会有其他动作,而没有收到ACK的话,就会重传FIN,ACK。
2、 防止lost duplicate对后续新建正常链接的传输造成破坏。简单来说,就是担心在建立TCP三次握手时,SYN报文在网络中由于某种原因在网络中兜圈子,迟迟未到服务器端,在这个迟迟未到的时间里,客户端重传SYN建立链接,并且完成了本次业务交互。没有TIME_WAIT的情况下,这个tcp链接很快就会被释放掉,此时在网络中兜圈子的SYN报文到达服务器端(实际已经没有意义了),但是服务器并不知道,于是浪费了服务器的资源。
TIME_WAIT过多主要会导致以下两个问题:
1. 占用连接资源:在TIME_WAIT时间内,相同五元组(源地址,源端口,目标地址,目标端口,协议)的连接无法创建,通常Linux一个ip可以开启的端口为指定的32768-61000,也就是大约30000个,如果TIME_WAIT状态过多,会导致无法创建新连接。
2. 占用内存资源:这点其实可以忽略,占用的内存资源非常少。
开启tcp_recycle的主要目的就是减少TIME WAIT的时间,但是上文也描述了,在NAT的场景下会引发网络不可达的故障,下面给出几点优化建议:
1、 通过修改参数tcp_max_tw_buckets = 262144 配置TIME WAIT的最大上限;
2、 如果挂载了硬件负载,增加硬件负载源NAT地址池的数量;
3、 调整大net.ipv4.ip_local_port_range
有的同学说我们的组网模式下没有NAT,但是你不能保证客户端没有做源NAT转换,总之非常不建议在生产环境中打开tcp_recycle。
--喜欢的同学请点击@IT管理局关注哦--
本局精彩文章:
Wireshark数据包分析三板斧 人人都能掌握的Chrome使用技巧一文秒懂 TCP/IP实际五层结构(上篇)
标签: #nginx代理转发慢