所以,本文也来凑个热闹,来谈谈TIME_WAIT。

为什么要有TIME_WAIT?

TIME_WAIT是TCP主动关闭连接一方的一个状态,TCP断开连接的时序图如下:

当主动断开连接的一方(Initiator)发送FIN包给对方,且对方回复了ACK+FIN,然后Initiator回复了ACK后就进入TIME_WAIT状态,一直将持续2MSL后进入CLOSED状态。

那么,我们来看如果Initiator不进入TIME_WAIT状态而是直接进入CLOSED状态会有什么问题?

考虑这种情况,服务器运行在80端口,客户端使用的连接端口是12306,数据传输完毕后服务端主动关闭连接,但是没有进入TIME_WAIT,而是直接计入CLOSED了。这时,客户端又通过同样的端口12306与服务端建立了一个新的连接。假如上一个连接过程中网络出现了异常,导致了某个包重传并延时到达了服务端,这时服务端就无法区分这个包是上一个连接的还是这个连接的。所以,主动关闭连接一方要等待2MSL,然后才能CLOSE,保证连接中的IP包都要么传输完成,要么被丢弃了。

TIME_WAIT会带来什么问题

系统中TIME_WAIT的连接数很多,会导致什么问题呢?这要分别针对客户端和服务器端来看的。

首先,如果是客户端发起了连接,传输完数据然后主动关闭了连接,这时这个连接在客户端就会处于TIMEWAIT状态,同时占用了一个本地端口。如果客户端使用短连接请求服务端的资源或者服务,客户端上将有大量的连接处于TIMEWAIT状态,占用大量的本地端口。最坏的情况就是,本地端口都被用光了,这时将无法再建立新的连接。

针对这种情况,对应的解决办法有2个: 
1. 使用长连接,如果是http,可以使用keepalive 
2. 增加本地端口可用的范围,比如Linux中调整内核参数:net.ipv4.ip_local_port_range

对于服务器自己,由于服务器是被动等待客户端建立连接的,因此即使服务器端有很多TIME_WAIT状态的连接,也不存在本地端口耗尽的问题。大量的TIME_WAIT的连接会导致如下问题: 
1. 内存占用:因为每一个TCP连接都会有占用一些内存。 
2. 在某些Linux版本上可能导致性能问题,因为数据包到达服务器的时候,内核需要知道数据包是属于哪个TCP连接的,在某些Linux版本上可能会遍历所有的TCP连接,所以大量TIME_WAIT的连接将导致性能问题。不过,现在的内核都对此进行了优化(待确认)。

那系统中处于TIME_WAIT状态的TCP连接数有上限吗?有的,这是通过net.ipv4.tcp_max_tw_buckets参数来控制的,默认值为180000。当超过了以后,系统就开始关闭这些连接,同时会在系统日志中打印日志。此时,可以将这个值调大一些,从这个参数的默认值就可以看出,对服务器自己,处于TIME_WAIT状态的TCP连接多点也没有什么关系,只是多占用些内存而已。

常见的TIMEWAIT错误参数

如果用TIME_WAIT作为关键字到网络上搜索,会得到很多关于如何减少TIME_WAIT数量的建议,其中有些建议是有错误或者有风险的,列举如下:

  1. net.ipv4.tcp_syncookies = 1,这个参数表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击。这个和TIME_WAIT没有什么关系。
  2. net.ipv4.tcp_tw_reuse = 1,这个参数表示重用TIME_WAIT的连接,重用的条件是TCP的4元组(源地址、源端口、目标地址、目标端口)要完全一致,而且开启了net.ipv4.tcp_timestamps,且新建立连接的使用的timestamp要大于当前连接的timestamp。所以,开启了这个参数对减少TIME_WAIT的TCP连接有点用,但条件太苛刻,所以实际用处不大。
  3. net.ipv4.tcp_tw_recycle = 1,这个参数表示开启TIME_WAIT回收功能,开启了这个参数后,将大大减小TIME_WAIT进入CLOSED状态的时间。但是开启了这个功能风险很大,可能会导致处于NAT后面的某些客户端无法建立连接。因为,开启这个功能后,它要求来自同一个IP的TCP新连接的timestamp要大于之前连接的timestamp。
  4. 查看当前配置  sysctl -a |grep net.ipv4.tcp_tw_reuse

TIMEWAIT的“正确”处理方法

简单总结一下我对于TIME_WAIT状态TCP连接的理解和处理方法: 
1. TIME_WAIT状态的设计初衷是为了保护我们的。服务端不必担心系统中有几w个处于TIME_WAIT状态的TCP连接。可以调大net.ipv4.tcp_max_tw_buckets这个参数。 
2. 使用短连接的客户端,需要关注TIME_WAIT状态的TCP连接,建议是采用长连接,同时调节参数net.ipv4.ip_local_port_range,增加本地可用端口的范围。 
3. 可以开启net.ipv4.tcp_tw_reuse这个参数,但是实际用处有限。 
4. 不要开启net.ipv4.tcp_tw_recycle这个参数,它带来的问题比用处大。 
5. 某些Linux的发行版可以调节TIME_WAIT到CLOSED的等待时间(比如Ali的Linux内核提供了参数net.ipv4.tcp_tw_timeout ),可以稍微调小一点这个参数。

 

谈谈TCP中的TIME_WAIT的更多相关文章

  1. TCP中的TIME_WAIT状态

    TIME_WAIT的存在有两大理由 1.可靠地实现TCP全双工连接的终止 2.允许老的可重复分节在网络中消失. 对于理由1,我们知道TCP结束需要四次挥手,若最后一次的客户端的挥手ACK丢失(假设是客 ...

  2. 谈谈 TCP 的 TIME_WAIT

    由来 最近有同事在用 ab 进行服务压测,到 QPS 瓶颈后怀疑是起压机的问题,来跟我借测试机,于是我就趁机分析了一波起压机可能成为压测瓶颈的可能,除了网络 I/O.机器性能外,还考虑到了网络协议的问 ...

  3. TCP协议中的TIME_WAIT详细说明

    文章目录 4.3设置TIME_WAIT状态的目的 4.3.1 实现TCP全双工连接的关闭 4.3.2 使过时的重复报文段失效 4.3.3 TIME_WAIT状态的自结束 4.3.4 TIME_WAIT ...

  4. tcp十种状态;关于tcp中time_wait状态(2MSL问题)

    tcp十种状态 注意: 当一端收到一个FIN,内核让read返回0来通知应用层另一端已经终止了向本端的数据传送 发送FIN通常是应用层对socket进行关闭的结果 关于tcp中time_wait状态的 ...

  5. TCP连接(Time_Wait、Close_Wait)说明

    修改Time_Wait和CLOSE_WAIT时间 修改Time_Wait参数的方法 (在服务端修改)Windows下在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlS ...

  6. TCP连接和 time_wait、close_waite

    TCP连接和 time_wait.close_waite tags:time_wait close_waite RST TCP 引言:前两天朋友公司的服务器垮掉了,最后查出的原因是发现大量的time_ ...

  7. TCP连接的TIME_WAIT和CLOSE_WAIT 状态解说【转】

    相信很多运维工程师遇到过这样一个情形: 用户反馈网站访问巨慢, 网络延迟等问题, 然后就迫切地登录服务器,终端输入命令"netstat -anp | grep TIME_WAIT | wc ...

  8. TCP连接的TIME_WAIT和CLOSE_WAIT 状态解说

    相信很多运维工程师遇到过这样一个情形: 用户反馈网站访问巨慢, 网络延迟等问题, 然后就迫切地登录服务器,终端输入命令"netstat -anp | grep TIME_WAIT | wc ...

  9. TCP 中的三次握手和四次挥手

    Table of Contents 前言 数据报头部 三次握手 SYN 攻击 四次挥手 半连接 TIME_WAIT 结语 参考链接 前言 TCP 中的三次握手和四次挥手应该是非常著名的两个问题了,一方 ...

随机推荐

  1. [国家集训队2]Tree I

    https://www.zybuluo.com/ysner/note/1294263 题面 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解 ...

  2. [loj6089]小Y的背包计数问题

    https://www.zybuluo.com/ysner/note/1285358 题面 小\(Y\)有一个大小为\(n\)的背包,并且小\(Y\)有\(n\)种物品. 对于第\(i\)种物品,共有 ...

  3. nginx 静态目录配置规则,路径匹配与本地资源

    经常配了nginx静态目录,死活访问不了,每次访问404.查看文档后,发现nginx配置静态目录使 用以下规则 假如nginx是在本机,静态目录也是在本机, 1.子目录匹配 如下配置 location ...

  4. sql的where条件中包含中文,查询不出来的处理方法

    SELECT  * FROM phonenumber_info where PROVANCE=N'广东' and  CITY=N'中山市'

  5. [TYVJ1391]走廊泼水节

    Description 话说,中中带领的OIER们打算举行一次冬季泼水节,当然这是要秘密进行的,绝对不可以让中中知道.不过中中可是老江湖了,当然很快就发现了我们的小阴谋,于是他准备好水枪迫不及待的想要 ...

  6. AOP面向方面编程---postsharp

    PostSharp是一个用于在.NET平台上实现AOP(Aspect-Oriented Programming,面向方面编程)的框架,现通过简单的示例代码来演示如何使用postsharp. 1.新建一 ...

  7. Android 性能优化(6)网络优化( 2) Analyzing Network Traffic Data:分析网络数据

    Analyzing Network Traffic Data 1.This lesson teaches you to Analyze App Network Traffic Analyze Netw ...

  8. 利用 nodeJS 搭建一个简单的Web服务器(转)

    下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...

  9. SCRIPT70: 没有权限

    主要原因:iframe安全而引发的问题,浏览器中js是没有垮域访问的权限的.如果用到iframe首先确保不垮域,或者不用iframe以绕开这个问题. 另外在jquery的早期版本中如:jquery-1 ...

  10. IIS网站部署步骤以及常见异常解决方案

    一. 简述 如果VS调试代码每次都使用浏览器打开,修改脚本和样式等还可以刷新页面显示最新修改,但是修改后台代码的话就需要停止调试再重新使用浏览器打开才能显示后台的最新修改,就比较麻烦.这里推荐附加到I ...