TIME_WAIT的产生原因

因为TCP连接是双向的,所以在关闭连接的时候,两个方向各自都需要关闭。先发FIN包的一方执行的是主动关闭;后发FIN包的一方执行的是被动关闭。主动关闭的一方会进入TIME_WAIT状态,并且在此状态停留两倍的MSL时长。

MSL指的是报文段的最大生存时间,如果报文段在网络活动了MSL时间,还没有被接收,那么会被丢弃。关于MSL的大小,RFC 793协议中给出的建议是两分钟,不过实际上不同的操作系统可能有不同的设置,以Linux为例,通常是半分钟,两倍的MSL就是一分钟,也就是60秒,并且这个数值是硬编码在内核中的,也就是说除非你重新编译内核,否则没法修改它。
TIME_WAIT状态存在的必要性。为什么主动关闭的一端不直接进入closed状态,而是要先进入time_wait并且停留两倍的MSL时长呢?这是因为TCP是建立在不可靠网络上的可靠协议。如果主动关闭的一端收到被动关闭一端的发出的FIN包后,返回ACK包,同时进入TIME_WAIT,但是由于网络的原因,主动关闭一端发送的ACK包可能会延迟,从而触发被动关闭一方重传FIN包,这样一来一回极端情况正好是2MSL。如果主动关闭的一端直接close或者不到两倍MSL时间就关闭,那么被动关闭发出重传FIN包到达,可能出现的问题是:旧的连接不存在,系统只能返回RST包;新的TCP连接已经建立,延迟包可能会干扰新连接。这都可能导致TCP不可靠。T状态存在的必要性。为什么主动关闭的一端不直接进入closed状态,而是要先进入time_wait并且停留两倍的MSL时长呢?这是因为TCP是建立在不可靠网络上的可靠协议。如果主动关闭的一端收到被动关闭一端的发出的FIN包后,返回ACK包,同时进入TIME_WAIT,但是由于网络的原因,主动关闭一端发送的ACK包可能会延迟,从而触发被动关闭一方重传FIN包,这样一来一回极端情况正好是2MSL。如果主动关闭的一端直接close或者不到两倍MSL时间就关闭,那么被动关闭发出重传FIN包到达,可能

TIME_WAIT过多的危害

在生产过程中,如果服务器使用短连接,那么完成一次请求后会主动断开连接,就会造成大量time_wait状态。因此我们常常在系统中会采用长连接,减少建立连接的消耗,同时也减少TIME_WAIT的产生,但实际上即使使用长连接配置不当时,当TIME_WAIT的生产速度远大于其消耗速度时,系统仍然会累计大量的TIME_WAIT状态的连接。TIME_WAIT状态连接过多就会造成一些问题。如果客户端的TIME_WAIT连接过多,同时它还在不断产生,将会导致客户端端口耗尽,新的端口分配不出来,出现错误。如果服务器端的TIME_WAIT连接过多,可能会导致客户端的请求连接失败,这在接下来举例说明。

请TIME_WAIT问题定位

案例一:将nginx作为反向代理时,后连tomcat等服务器。测试中不同并发压力下多次、反复出现nginx服务器端口资源耗尽的问题。表现为nginx服务器出现大量time_wait状态连接,端口资源耗尽(nginx报错:cannot assign requested address )。首先检查nginx开启了长连接keepalive,但是系统仍然出现了大量的TIME_WAIT,这就和之前提到的当系统产生TIME_WAIT的速度大于其消耗速度时,就会累计TIME_WAIT。原因是:keepalive取配置太小,将其增大后问题得以解决。(PS:nginx总的keepalive连接池大小 = keepalive取值 * nginx worker数)

案例二:

某应用其中一层系统架构Nginx+Tomcat,客户端发出的请求为HTTP HEAD,客户端TPS有段时间接近为0,返回Connection time out错误。

观察大部分错误请求响应时间刚好是30s,这正好是nginx的连接超时时间配置,Tomcat没有收到这些错误请求,这意味着请求Nginx连接Tomcat都没有成功。这是为什么呢?Tomcat的连接池不够用吗? 实际上Tomcat work线程不到200个,远小于MaxThread(1024)的值,同时还观察到Tomcat上的TIME_WAIT连接数量不正常,达到了近两万个。

系统是设置了长连接的,为什么还有这么多TIME_WAIT,难道长连接没有生效吗?

Nginx作为反向代理,长连接配置主要有三项,upstream中的keepalive设置单个worker最大请求数,参数proxy_http_version  1.1强制转换为http1.1协议(默认支持长连接),proxy_set_header Connection将请求头部connection为空(http1.0请求默认connection头部为close)

upstream backend_nosfs {

server 10.10.10.10:8185;

keepalive 1024;

#keepalive_requests;

}

proxy_http_version 1.1;

proxy_set_header Connection "";

Tomcat端增加配置maxKeepAliveRequests=“10000”,表示一个连接上最大请求数达到10000才会断开。

定位长连接问题,最简单直接的方法就是抓包,通过wireshark分析Nginx和Tomcat直接连接果然没有生效,一条连接只处理了一个请求。

为什么设置了长连接相关的配置,还是没有生效呢?经过排查发现,proxy_http_version 1.1;

为什么设置了长连接相关的配置,还是没有生效呢?经过排查发现,proxy_http_version 1.1;
proxy_set_header Connection ""这两项配置放在Nginx的Http域中,实际上他们要放在server域才会生效,将其位置修改后,长连接生效了,所有问题都解决了。但是我们不禁会尝试疑问TIME_WAIT出现在Tomcat而不是在Nginx上?从抓包可以看出Nginx发送给Tomcat包头部Connection为close,所以Tomcat在处理完head请求后就主动关闭,所以TIME_WAIT出现在Tomcat服务器。 配置修改后,问题解决了,TPS也上去了,之前出现的连接失败问题也没有了。

但是为什么Tomcat服务器上的TIME_WAIT过多会导致Nginx连接失败呢?理论上说,服务器只监听在一个端口,但是会new出很多socket去处理请求,难道是socket不够用吗?再观察资源使用发现虽然TIME_WAIT连接数多,但是句柄数并不多,而socket的数量是受制于句柄数。那真正的原因是什么呢?在系统TIME_WAIT较多时,Dmesg系统出错日志为:
nf_conntrack: table full, dropping packet
     真相大白了,Conntrack表用于记录每个连接的状态,在tcp协议中用源ip/port+目的ip/port唯一标识一个连接。记录TCP连接状态的表满了导致请求失败。查看系统ip_contrack_max配置为
65536,在极端的情况下超出了其配置所有导致连接失败。

如何控制TIME_WAIT数量

通过以上的TIME_WAIT问题,我们可以看到TIME_WAIT这个状态不存在不行,但是过多就对系统会造成困扰。那么我们应该如何控制TIME_WAIT的数量呢?
长连接
对于反向代理和应用服务器,最好是要配置成支持keepalive长连接,否则在系统并发增加时会导致一系列的连接问题。对于nginx+tomcat长连接的配置前面有一些介绍可以参考,其它服务器一般也是提供支持长连接配置的,设置后建议抓包测试验证。
一般来说长连接设置正确了TIME_WAIT数量不会暴涨,但是长连接最大请求数也是有效的,但如果应用的处理速度很快导致TIME_WAIT的产生的速度远快于TIME_WAIT的消耗速度时系统就会累计TIME_WAIT状态连接。这时候可能就要修改一些系统配置了。
ip_conntrack
用于跟踪TCP连接。一旦激活了此模块,就能在系统参数里发现很多用来控制网络连接状态超时的设置,其中自然也包括TIME_WAIT,默认ip_conntrack_max最大为65536,可以将其设置得更大一些。一般不建议此模块,如果系统安装使用iptable会启动该模块。
tcp_tw_recycle
在网上搜索TIME_WAIT问题的解决方法,大多都会提到这个参数,不过官方网站上不建议开启这个参数,原因是会导致一些安全问题。例如,当多个客户端通过NAT方式联网并与服务端交互时,服务端看到的是同一个IP,由于这些客户端的时间戳可能存在差异,所以从服务端的视角看,便可能出现时间戳错乱的现象,进而直接导致时间戳小的数据包被丢弃。
tcp_tw_reuse
当创建新连接的时候,如果可能的话会考虑复用相应的TIME_WAIT连接。官方文档里提到的是如果从协议视角看它是安全的,那么就可以使用。这个很难判定这个参数是否应该开启,不到万不得已的时候,即使我们要开启这个参数复用连接,也应该在连接的发起方使用,而不能在被连接方使用。
tcp_max_tw_buckets
用于控制TIME_WAIT总数。这个选项是为了阻止一些简单的DoS攻击,平常不要人为的降低它。如果TIME_WAIT已经成为最棘手的问题,那么即便此时并不是DoS攻击的场景,也可以尝试通过设置它来减少TIME_WAIT数量。

Time_wait问题小结的更多相关文章

  1. TCP小结

    TCP/IP协议实现了不同主机,不同操作系统之间信息交流.由4层构成,从上往下依次为: 1.应用层,包括http,ftp等协议,用于实现某一项具体的功能. 2.传输层,包括TCP和UDP,一个可靠,一 ...

  2. GopherChina第一天小结

    GopherChina第一天小结 今天参加了Asta举办的第五届GopherChina,第一天参加完,颇有感受,晚上回来趁着还有记忆,来做一下记录. 写在前面 一早从9点开始,一天下来一共八个主题,各 ...

  3. 谈谈 TCP 的 TIME_WAIT

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

  4. 【TCP/IP详解 卷一:协议】TCP的小结

    前言:TCP学习的综述 在学习TCP/IP协议的大头:TCP协议 的过程中,遇到了很多机制和知识点,详解中更是用了足足8章的内容介绍它. TCP协议作为 应用层 和 网络层 中间的 传输层协议,既要为 ...

  5. 从零开始编写自己的C#框架(26)——小结

    一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...

  6. Python自然语言处理工具小结

    Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...

  7. java单向加密算法小结(2)--MD5哈希算法

    上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...

  8. [Nginx笔记]关于线上环境CLOSE_WAIT和TIME_WAIT过高

    运维的同学和Team里面的一个同学分别遇到过Nginx在线上环境使用中会遇到TIME_WAIT过高或者CLOSE_WAIT过高的状态 先从原因分析一下为什么,问题就迎刃而解了. 首先是TIME_WAI ...

  9. iOS--->微信支付小结

    iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...

随机推荐

  1. Redis3

    Redis到底该如何利用 上两篇受益匪浅,秉着趁热打铁,不挖到最深不罢休的精神,我决定追加这篇.上一篇里最后我有提到实现分级缓存管理应该是个可行的方案,因此今天特别实践了一下.不过缓存分级之后也发现了 ...

  2. 安装Visual Source Safe 2005 - 初学者系列 - 学习者系列文章

    本文介绍微软的文档管理工具Visual Source Safe 2005的安装 从下列地址获取该工具: ed2k://|file|en_vss_2005.iso|108048384|C4BEC1EC3 ...

  3. 使用rem设计移动端自适应页面一(转载)

    1.困扰多时的问题 在这之前做Web App开发的的时候,在自适应方面一般都是宽度通过百分比,高度以iPhone6跟iPhone5之间的一个平衡值写死,我们的设计稿都是iPhone5的640 * 11 ...

  4. mvc @html.editor怎么修改宽度 和其他属性

    <style type="text/css"> #dob { width:6em; } </style> @using (Html.BeginForm()) ...

  5. awk学习点滴

    1,常量 ARGC:命令行参数个数 包括awk本身命令,但awk的自带option不算在内. ARGV:命令行参数数组 ARGV[0]是awk本身,其他依次提取就好. $ awk -F ' ' 'BE ...

  6. 飘逸的python - 命令行漂亮的显示json数据

    之前做的一个脚本把信息用json格式存到文本中.这样的好处是简便,易编辑,并且拥有强大的表达能力. 不过从文本cat出来的是一堆很难看的字符串,没换行和缩进.这时候就在想,如果有个类似于IDE的格式化 ...

  7. Blend4开发:会飞的小鸟

    1,绘图,动画制作: 2,运行截图: 源码:http://files.cnblogs.com/yuanli/Animals.zip 动画效果参见源码.

  8. 关于iTunes随机播放和我所不知道的自己

    无意中看到这套题,很有意思,自己做了一下. 规则是这样的:打开你的播放器,我的是iTunes,不管是哪个,总之打开最全的那个播放列表,开启随机播放,按顺序把每首歌名写在下面每道题的后面,比如第一首歌是 ...

  9. java web项目基础

      listener,filter,servlet的初始化顺序 web.xml中可以配置如下信息: context-param,listener,filter,servlet. 他们的加载顺序和在we ...

  10. Vijos1055 奶牛浴场(极大化思想求最大子矩形)

    思路详见 王知昆<浅谈用极大化思想解决最大子矩形问题> 写得很详细(感谢~....) 因为不太会用递推,所以用了第一种方法,时间复杂度是O(n^2),n为枚举的点数,对付这题绰绰有余 思路 ...