点赞
评论
收藏
分享
举报
Nginx并发优化之TIME-WAIT
发表于2021-09-16 08:18

浏览 4k

文章标签

在Nginx的并发优化中,TIME-WAIT是服务器优化必然会谈到的一个话题,而我们常见的问题就是TIME-WAIT过多怎么处理?


常见的解决方法就是:

1、快速回收

2、链接复用


而这里有个误区就是到底TIME-WAIT要优化到什么程度,有的童鞋甚至看到TIME-WAIT就觉得需要优化,今天就是想聊一下这个话题


要聊明白,还是要从原理来说起


TIME-WAIT是TCP链接的一种状态,之前有写文章介绍过TCP的11中链接状态,有兴趣可以再去看下

这张图整个展示了所有状态的转换过程,总共分为三个部分,上半部分是建立连接的过程,下面部分分成主动关闭和被动关闭的过程


可以看到TIME_WAIT只在主动关闭的过程中出现,实际上TIME_WAIT是TCP为了解决复杂的网络问题提出的一种解决方案


解决什么问题呢?看下面两个场景


  • 四次挥手中,A 发 FIN, B 响应 ACK,B 再发 FIN,A 响应 ACK 实现连接的关闭。而如果 A 响应的 ACK 包丢失,B 会以为 A 没有收到自己的关闭请求,然后会重试向 A 再发 FIN 包。

    如果没有 TIME_WAIT 状态,A 不再保存这个连接的信息,收到一个不存在的连接的包,A 会响应 RST 包,导致 B 端异常响应。

    此时, TIME_WAIT 是为了保证全双工的 TCP 连接正常终止。

  • 我们还知道,TCP 下的 IP 层协议是无法保证包传输的先后顺序的。如果双方挥手之后,一个网络四元组(src/dst ip/port)被回收,而此时网络中还有一个迟到的数据包没有被 B 接收,A 应用程序又立刻使用了同样的四元组再创建了一个新的连接后,这个迟到的数据包才到达 B,那么这个数据包就会让 B 以为是 A 刚发过来的。

    此时, TIME_WAIT 的存在是为了保证网络中迷失的数据包正常过期。

第一种场景下,TIME_WAIT是为了确保被动关闭方收到ACK,连接正常关闭,且不因被动关闭方重传FIN影响下一个连接

第二种场景下,TIME_WAIT保留2个MSL,以确保数据不会丢失

注释:MSL(Maximum Segment Lifetime) 最大分段寿命,它表示一个TCP分段可以存在于互联网系统中的最大时间,由TCP实现,超出这个寿命的分段都会被丢弃,RFC 1122建议是2分钟,但在不同的unix实现上,这个值并不确定

由于以上的两种场景,TCP引入了TIME_WAIT状态来解决,由此可见TIME_WAIT并不是完全不存在才是合理的或以消除TIME_WAIT为优化的一个目标


那么TIME_WAIT具体要怎么优化,什么样的状态是一个合理的状态?


我们还是看常用的两种优化方法,先说不建议使用的一种:快速回收


由上面可知,TIME_WAIT的时长是2MSL,按照RFC建议2分钟的话,就是4分钟,对于高并发的服务器来说,本身local_port就有固定的量,如果4分钟才回收TIME_WAIT,那么端口很快就会被用尽


尽管CentOS系统中,MSL可以通过修改参数tcp_fin_timeout来设置MSL的时间,默认是30s,这样的话,一个四元组(local_ip, local_port, remote_ip,remote_port)会被冻结60s的时间,系统默认可分配端口约30000个,可通一下文件查看过


/proc/sys/net/ipv4/ip_local_port_range


那么从同一个客户端发起请求,并发只能到500QPS左右


所以提出了快速回收的方法,即TCP连接状态在TIME_WAIT状态的时候,立即回收连接,不等待2MSL,以快速回收资源用于新的连接


而快速回收的弊端,相信都有了解,就是关于快速回收引发的SYN无法得到ACK的问题,具体如下:


TCP有一种行为,可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。Linux是否启用这种行为取决于tcp_timestamps和tcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了。在nat环境中会出现时间戳错乱的情况,后面的数据包就被丢弃了,具体的 表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK。因为NAT设备将数据包的源IP地址都改成了一个地址(或者少量的IP地址),但是却基本上不修改TCP包的时间戳,则会导致时间戳混乱


建议:如果前端部署了三/四层NAT设备,尽量关闭快速回收,以免发生NAT背后真实机器由于时间戳混乱导致的SYN拒绝问题


而另一种优化方式就是建议的方式:复用


由上面的分析可以确定,并发上不去是因为四元组被冻结2MSL时长导致没有新的资源可用,而四元组在被冻结的时间内是不能被使用的,所以提出了复用的方式,但是复用是有前提的,它需要tcp_timestamps同时开启,看下内核关于这部分的代码


reuse的前提是收到最后一个包后超过1s,所以正常的情况下开启reuse是可以达到快速复用TIME_WAIT状态的socket链接的,而且也不会有像recycle那样的“副作用”


除了以上两种解决TIME_WAIT的方式,还有一个参数是必须要关注的,就是tw_buckets,可以通过

cat /proc/sys/net/ipv4/tcp_max_tw_buckets

查看该参数值,这个值是TIME_WAIT可以达到的最大数量,当TIME_WAIT存在的数量和tcp_max_tw_buckets相同时,会处于tw_buckets溢出状态,默认是4096


当弃用reuse的时候,在一个高并发的服务器上,TIME_WAIT并不会快速回收,而是复用之前的链接,这样的情况下TIME_WAIT必然会保持一定的数量,那么tw_buckets就很关键,如果按照local_port在3w左右,那么tw_buckets如果是默认4096的情况下,TIME_WAIT也会很快到达瓶颈,无法再增加


所以应该保持tw_buckets至少在local_port之上,虽然长时间大量TIME_WAIT会消耗一定的内存资源,但是对于现在的服务器,TIME_WAIT所占用的内存是可以容忍的


总结:

    结合上面的分析,recycle在内核4.1以后就被弃用了,所以它并不是TIME_WAIT优化的最好方案,最好的方式就是通过reuse进行复用,复用的前提是开启tcp_timestamps,并且要关注tw_buckets溢出的情况,适当增加tw_buckets,以应对并发量

已修改于2023-03-09 02:05
本作品系原创
创作不易,留下一份鼓励
李俊鹏

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
李俊鹏
这家伙很懒还未留下介绍~
4
文章
0
问答
2
粉丝
相关文章
介绍nginx网页配置工具QQ技术交流群1:1106758598QQ技术交流群2:560797506邮箱: cym1102@qq.com官网地址: http://www.nginxwebui.cn码云: https://gitee.com/cym1102/nginxWebUIgithub: https://github.com/cym1102/nginxWebUI功能特点nginxWebUI也可管理多个nginx服务器集群,随时一键切换到对应服务器上进行nginx配置,也可以一键将某台服务器配置同步到其他服务器,方便集群管理.部署此项目后,配置nginx再也不用上网各种搜索配置代码,再也不用手动申请和配置ssl证书,只需要在本项目中进行增删改查就可方便的配置和启动nginx。技术说明本项目是基于springBoot的web系统,数据库使用sqlite,因此服务器上不需要安装任何数据库项目启动时会释放一个.sqlite.db到系统用户文件夹中,注意进行备份本系统通过Let'sencrypt申请证书,使用acme.sh脚本
点赞 6
浏览 6.4k
  前三周学习了陶辉老师的“NGINX基础培训系列课程”,感觉受益良多,在这里想把一些知识点记录一下,和大家分享一下知识点,也方便日后的随手查看,温故知新。  首先,我们了解到了Nginx的版本,Nginx发布版本分为主线版本和稳定版本,区分两个版本也非常简单,主线版本版本号为单数,比如1.19,稳定版本为双数,比如1.18,今天我要说的是稳定版本,这个版本会尽量少的减少Nginx的bug问题,适用于生产环境,这里我不建议使用Nginx和其他软件一样在生产环境中落后一个或多个大版本使用,之前生产环境做过漏扫,发现我们编译自带的Nginx版本为:nginx/1.13.3(查询命令为nginx-V),结果出现了多个漏洞,四个高危和一个中危漏洞:        通过升级Nginx到稳定版最新版本后修复!  其次,是Nginx发行版本的选择,目前比较流行的有:nginx、nginxplus、Tengine、openresty、ope
点赞 1
浏览 3.5k
感谢您参加“NGINX从入门到精通进阶系列培训”!以下为培训的问答、课件和录像,希望您能通过此培训学有所得,祝学习进步!>问与答:- 基础篇+高级篇 - 应用篇+实战篇(New)>课件(PPT):基础篇:-NGINX概要、安装、配置:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-Setup.pdf-NGINX日志、运维:https://interact.f5.com/rs/653-SMC-783/images/cnfeb22-nginxcorecourse-maintenance.pdf高级篇:-NGINX变量、API:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-API.pdf-NGINXSSL、NJS:https://interact.f5.com/rs/653-SMC-783/images/CNFEB22-NginxCoreCourse-SSL.pdf
点赞 10
浏览 4.9k