也说说TIME_WAIT状态
也说说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状态的更多相关文章
- 传输层(2)-TCP连接的建立和终止、TIME_WAIT状态
1.TCP连接的建立和终止 1)三路握手 客户端发送一个SYN(同步)分解,告诉服务器客户将在连接中发送的数据的初始序列号. 服务器发送确认客户的SYN(ACK),同时自己也得发送一个SYN分节,它含 ...
- Linux-TCP/IP TIME_WAIT状态原理
TIME_WAIT状态原理---------------------------- 通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态. 客户端主动关闭连接时,会发送最后一个a ...
- 服务器time_wait状态原因
通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态 TIME_WAIT状态的时间是2倍的MSL(最大生存时间),在TIME_WAIT状态TCP连接实际上已经断掉,但是该插口又不 ...
- TCP/IP TIME_WAIT状态原理
原文转载:http://elf8848.iteye.com/blog/1739571 IME_WAIT状态原理 ---------------------------- 通信双方建立TCP连接后,主动 ...
- TCP/IP TIME_WAIT状态
百度运维部二面面试官问我这个 我直接懵逼了 TIME_WAIT状态是通信双方简历TCP连接后, 主动关闭的一方就会进入TIME_WAIT状态 1.client向server发送FIN(M),clien ...
- LINUX下解决netstat查看TIME_WAIT状态过多问题
来源:多3度热爱 的BLOG 查看连接某服务端口最多的的IP地址 netstat -nat |awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c ...
- TCP释放连接时为什么time_wait状态必须等待2MSL时间
为什么上图中的A在TIME-WAIT状态必须等待2MSL时间呢? 第一,为了保证A发送的最后一个ACK报文能够到达B.这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FI ...
- 为什么建立TCP连接需要三次握手,为什么断开TCP连接需要四次握手,TIME_WAIT状态的意义
为什么建立TCP连接需要三次握手? 原因:为了应对网络中存在的延迟的重复数组的问题 例子: 假设client发起连接的连接请求报文段在网络中没有丢失,而是在某个网络节点长时间滞留了,导致延迟到达ser ...
- tcp netstat用法 TIME_WAIT状态解析 MTU以及MSS
带着问题写博客 问题1:使用netstat查看有源TCP连接的状态时,经常会看到established状态,那么还有哪些状态,这些状态是如何变化的呢? 问题2:TIME_WAIT状态存在的必要? 问题 ...
随机推荐
- angular代码分析之异常日志设计
angular代码分析之异常日志设计 错误异常是面向对象开发中的记录提示程序执行问题的一种重要机制,在程序执行发生问题的条件下,异常会在中断程序执行,同时会沿着代码的执行路径一步一步的向上抛出异常,最 ...
- WCF基础教程之开篇:创建、测试和调用WCF
一转眼,又半个月没有更新博客了.说实话,最近确实是有点忙.不过即使再忙忙,也要抽空来学习一些东西.最近用WCF比较多,就来跟大家分享一下关于WCF的知识吧!为了让大家都能看懂,照顾一些没有学过WCF的 ...
- FB引擎系列-之CloudSand
CloudSand,欲打破之前的集中版本制作的模式, http://code.taobao.org/p/cloudsand包含服务器端代码(php)和客户端代码(unity) EasyDown的时 ...
- Perl重命名当前目录下的文件
下载的zip包解压后,中文都变成了乱码,就写了个脚本重命名文件. use strict; use warnings; use Cwd; sub main { my $dir = getcwd(); o ...
- Java中常量小知识
常量分类:常量分为静态常量,非静态常量(全局常量),局部常量 静态常量:要么定义的时候赋初值,要么在静态代码块中赋值 非静态常量:要么在定义的时候赋初值,要么在代码块中赋值 局部常量:可以在定义时赋初 ...
- salesforce 零基础开发入门学习(六)简单的数据增删改查页面的构建
VisualForce封装了很多的标签用来进行页面设计,本篇主要讲述简单的页面增删改查.使用的内容和设计到前台页面使用的标签相对简单,如果需要深入了解VF相关知识以及标签, 可以通过以下链接查看或下载 ...
- python学习 流程控制语句
##################################### 分支语句 python3.5 #########################################代码的缩进格 ...
- 快速入门系列--CLR--02多线程
最近,由于基础框架的整体升级,因此需要更新所有相关项目的DLL文件.这个过程存在不小的风险,因此也对发布后的生产服务器进行了密切的监控,结果还是出现了个别应用出现异常的情况,很快的占用了大量的服务器内 ...
- OpenCascade Matrix
OpenCascade Matrix eryar@163.com 摘要Abstract:本文对矩阵作简要介绍,并结合代码说明OpenCascade矩阵计算类的使用方法. 关键字Key Words:Op ...
- Android入门(十八)服务
原文链接:http://www.orlion.ga/674/ 一.定义一个服务 创建一个项目ServiceDemo,然后在这个项目中新增一个名为 MyService的类,并让它继承自 Service, ...