也说说TIME_WAIT状态

一个朋友问到,自己用go写了一个简单的HTTP服务端程序,为什么压测的时候服务端会出现一段时间的TIME_WAIT超高的情况,导致压测的效果不好呢?

记得老王有两篇文章专门说这个,当时粗粗看了一遍,正好碰上这个问题,又翻出来细细搂了。

第一个要弄懂的,是TIME_WAIT是怎么产生的。

TIME_WAIT状态是怎么产生的

要弄懂TIME_WAIT要从TCP的四次握手的分手协议说起。

上面这个图片展示了TCP从连接建立到连接释放的过程中,客户端和服务端的状态变化图。如果只看连接释放阶段,四次握手

  • 客户端先发送FIN,进入FIN_WAIT1状态
  • 服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态
  • 服务端发送FIN,进入LAST_ACK状态
  • 客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态
  • 客户端TIME_WAIT持续2倍MSL时长,在linux体系中大概是60s,转换成CLOSE状态

当然在这个例子和上面的图片中,使用客户端和服务端来描述是不准确的,TCP主动断开连接的一方可能是客户端,也可能是服务端。所以使用主动断开的一方,和被动断开的一方替换上面的图可能更为贴切。

不管怎么说,TIME_WAIT的状态就是主动断开的一方,发送完最后一次ACK之后进入的状态。并且持续时间还挺长的。

能不能发送完ACK之后不进入TIME_WAIT就直接进入CLOSE状态呢?不行的,这个是为了TCP协议的可靠性,由于网络原因,ACK可能会发送失败,那么这个时候,被动一方会主动重新发送一次FIN,这个时候如果主动方在TIME_WAIT状态,则还会再发送一次ACK,从而保证可靠性。那么从这个解释来说,2MSL的时长设定是可以理解的,MSL是报文最大生存时间,如果重新发送,一个FIN+一个ACK,再加上不定期的延迟时间,大致是在2MSL的范围。

所以从理论上说,网上调试参数降低TIME_WAIT的持续时间的方法是一种以可靠性换取性能的一种方式。嗯,质量守恒定理还是铁律。

服务端TIME_WAIT过多

回到上面的问题,go写了一个HTTP服务,压测发现TIME_WAIT过多。

首先判断是不是压测程序放在服务的同一台机器...当然不会犯这么低级的错误...

那么这个感觉就有点奇怪了,HTTP服务并没有依赖外部mysql或者redis等服务,就是一个简单的Hello world,而TIME_WAIT的是主动断开方才会出现的,所以主动断开方是服务端?

答案是是的。在HTTP1.1协议中,有个 Connection 头,Connection有两个值,close和keep-alive,这个头就相当于客户端告诉服务端,服务端你执行完成请求之后,是关闭连接还是保持连接,保持连接就意味着在保持连接期间,只能由客户端主动断开连接。还有一个keep-alive的头,设置的值就代表了服务端保持连接保持多久。

HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的情况就很正常了。

虽然HTTP默认Connection值为close,但是现在的浏览器发送请求的时候一般都会设置Connection为keep-alive了。所以,也有人说,现在没有必要通过调整参数来使TIME_WAIT降低了。

解决方法

按照HTTP协议的头,我们在压测程序发出的HTTP协议头里面加上connection:keep-alive当然能解决这个问题。

还有的方法就是系统参数调优:

sysctl net.ipv4.tcp_tw_reuse=1

sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_timestamps=1

tcp_tw_reuse

这个参数作用是当新的连接进来的时候,可以复用处于TIME_WAIT的socket。默认值是0。

tcp_tw_recycle和tcp_timestamps

默认TIME_WAIT的超时时间是2倍的MSL,但是MSL一般会设置的非常长。如果tcp_timestamps是关闭的,开启tcp_tw_recycle是没用的。但是一般情况下tcp_timestamps是默认开启的,所以直接开启就有用了。

参考文章

记一次TIME_WAIT网络故障

再叙TIME_WAIT

Time-wait状态(2MSL)一些理解

tcp_tw_recycle和tcp_timestamps导致connect失败问题

也说说TIME_WAIT状态的更多相关文章

  1. 传输层(2)-TCP连接的建立和终止、TIME_WAIT状态

    1.TCP连接的建立和终止 1)三路握手 客户端发送一个SYN(同步)分解,告诉服务器客户将在连接中发送的数据的初始序列号. 服务器发送确认客户的SYN(ACK),同时自己也得发送一个SYN分节,它含 ...

  2. Linux-TCP/IP TIME_WAIT状态原理

    TIME_WAIT状态原理---------------------------- 通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态. 客户端主动关闭连接时,会发送最后一个a ...

  3. 服务器time_wait状态原因

    通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态 TIME_WAIT状态的时间是2倍的MSL(最大生存时间),在TIME_WAIT状态TCP连接实际上已经断掉,但是该插口又不 ...

  4. TCP/IP TIME_WAIT状态原理

    原文转载:http://elf8848.iteye.com/blog/1739571 IME_WAIT状态原理 ---------------------------- 通信双方建立TCP连接后,主动 ...

  5. TCP/IP TIME_WAIT状态

    百度运维部二面面试官问我这个 我直接懵逼了 TIME_WAIT状态是通信双方简历TCP连接后, 主动关闭的一方就会进入TIME_WAIT状态 1.client向server发送FIN(M),clien ...

  6. LINUX下解决netstat查看TIME_WAIT状态过多问题

     来源:多3度热爱 的BLOG   查看连接某服务端口最多的的IP地址 netstat -nat |awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c ...

  7. TCP释放连接时为什么time_wait状态必须等待2MSL时间

    为什么上图中的A在TIME-WAIT状态必须等待2MSL时间呢? 第一,为了保证A发送的最后一个ACK报文能够到达B.这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FI ...

  8. 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义

    为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...

  9. tcp netstat用法 TIME_WAIT状态解析 MTU以及MSS

    带着问题写博客 问题1:使用netstat查看有源TCP连接的状态时,经常会看到established状态,那么还有哪些状态,这些状态是如何变化的呢? 问题2:TIME_WAIT状态存在的必要? 问题 ...

随机推荐

  1. mongoDB研究笔记:复制集概述

    自我学习,仅供参考: 数据库总是会遇到各种失败的场景,如网络连接断开.断电等,尽管journaling日志功能也提供了数据恢复的功能,但journaling通常是针对单个节点来说的,只能保证单节点数据 ...

  2. gulp插件(gulp-jmbuild),用于WEB前端构建

    源码地址:https://github.com/jiamao/gulp-jmbuild https://github.com/jiamao/gulp-jmbuild gulp-jmbuild gulp ...

  3. DataPager 分页样式(css)

    <asp:DataPager ID="> <Fields> <asp:NextPreviousPagerField ShowFirstPageButton=&q ...

  4. React Native移动框架功能研究

    React Native移动框架功能研究 此篇只研究React Native框架的功能. 一.React Natvie是什么 React Native是使用React(或者说JS)来开发原生APP的框 ...

  5. 使用JS或jQuery模拟鼠标点击a标签事件

    <a id="alink" href="abc.aspx"  style="visibility: hidden;">下一步&l ...

  6. 可在广域网部署运行的QQ高仿版 -- GG2014 完美版!新增支持:聊天记录、好友分组、托盘闪动消息提醒、登录状态、GIF动态表情

    距上次GG V3.7版本(可在广域网部署运行的QQ高仿版 -- GG叽叽V3.7,优化视频聊天.控制更多相关细节)的发布,已经有50天了,这50天对于GG来说,是一个重大的飞跃.因为这段时间通过一些基 ...

  7. 细说angular Form addControl方法

    在本篇博文中,我们将接触angular的验证.angular的验证是由form 指令和ngModel协调完成的.今天博主在这里想要说的是在验证在的一种特殊情况,当验证控件没有没有name属性这是不会被 ...

  8. PS 多次剪裁同一图片

    一个图品里面有两个小图,要分别抠出来. 我以前的做法是,先扣一个,重新打开文件,再扣另外一个. 今天发现一个简单的办法,不用重新打开文件. 就是在扣完第一个的时候,打开历史记录面板,双击 打开 动作, ...

  9. [源码]NumberToUpper 数字转中文

    使用时需开启unsafe选项 构造函数有4个参数 number : 数字文本 isSimplified : 是否只使用简体中文,默认:false isMoney : 是否是金额模式(忽略小数点后3位, ...

  10. 网络异步编程(C#)团购课

    新生命开发团队大石头讲解网络异步编程(C#) 内容:网络编程基础.IOCP.APM.SAEA 时长:2~3小时 价格:20元,20人及以上成团,http://item.taobao.com/item. ...