那些年我们踩过的坑之TIME_WAIT调优

原创 2017年01月03日 16:34:34

一、写在前面

  相信很多人都遇到过服务器出现大量TIME_WAIT的情况,大多数的解决办法是sysctl修改如下参数

net.ipv4.tcp_tw_recycle = 1   #快速回收 TIME_WAIT

net.ipv4.tcp_tw_reuse = 1    #reuse TIME_WAIT

net.ipv4.tcp_timestamps = 1  #上述两项生效的前提是TCP连接两端都要启用TCP时间戳

过一会发现TIME_WAIT数量直线下降后,服务貌似也没出问题,ok问题解决!其实不然。想真正理解所谓“大量的TIME_WAIT的问题”,我们要先理解TIME_WAIT。


二、概念解析

  TIME_WAIT是有友好的,不是多余的,是主动关闭TCP连接的一方在调用socker的close操作后最终会进入TIME_WAIT状态。服务器在处理客户端请求的时候,如果你的程序设计为服务器主动关闭,那么你才有可能需要关注这个TIMEWAIT状态过多的问题。如果你的服务器设计为被动关闭,那么你首先要关注的是CLOSE_WAIT。

  换句话说:在一台负载均衡的服务器上(以Nginx为例),客户端向Nginx的请求,作为服务器来看属于被动连接;Nginx向Web服务器的请求属于主动连接。在讨论TIME_WAIT优化时,我们应该关注的是主动连接,即Nginx对Web服务器的连接。


三、TIME_WAIT作用

  1、防止前一个连接延迟的数据被后面复用的连接错误的接收;

  2、可靠的关闭TCP连接;

  关于TIME_WAIT作用的深入理解需要配合Socket连接五元组、RFC 793等概念,本文不重点讨论,感兴趣的童鞋请移步老男孩博客

 

四、TIME_WAIT过多后的性能影响

  内核里有保存所有连接的一个hash table,这个hash table既包含TIME_WAIT状态的连接,也包含其它状态的连接。主要用于有新的数据到来的时候,从这个hash table里快速找到这条连接。还有一个hash  table用来保存所有的bound ports,主要用于可以快速的找到一个可用的端口或者随机端口。

  因此,内核保存这些数据必然会占用一定的内存,同理每次找到一个随机端口需要遍历一遍bound ports,必然需要一些CPU时间! 

  TIME_WAIT很多,既占内存又耗CPU,但其实进一步研究,1万条TIME_WAIT连接,也就多消耗1M左右的内存,对于现在的服务器来说已经不算什么。至于CPU,也不至于因为1万多的hash item就担忧。最起码在TIME_WAIT达到几千的量级上不必过多紧张,因为TIME_WAIT所占用的内存很少很少,同时记录和寻找可用的local port所消耗的CPU也基本可以忽略。



五、打开net.ipv4.tcp_tw_recycle参数的副作用

  TIME_WAIT的存在是很重要的,如果强制忽略TIME_WAIT,还是有很高的机率,造成数据粗乱,或者短暂性的连接失败。比较直接的现象是,通过NAT后的IP大量访问服务的时候容易出现静置几分钟后连接失败或者多个客户端同时访问有的访问频繁失败的情况。

  还有一种情况是:在 客户端-服务器 一对一的时候,没有任何问题,但是当源IP是经过NAT后的地址或服务器在负载均衡器后面时,源地址为同一ip假如恰巧先后两次连接源端口相同,这台服务器先后收到两个包,第一个包的timestamp被服务器保存着,第二个包又来了,一对比,发现第二个包的timestamp比第一个还老——客户端时间不一致。服务器基于PAWS,判断第二个包是重复报文,丢弃之。反映出来的情况就是在服务器上抓包,发现有SYN包,但服务器就是不回ACK包,因为SYN包已经被丢弃了。可用如下命令验证,查看输出里面的packets rejects in established connections because of timestamp一项的数量变化。

netstat -s | grep timestamp


六、net.ipv4.tw_recycle如何配置

  写了这么多,那么tw_recycle参数到底该怎么用呢?在这里,引用老男孩博客里给出的两个典型场景的配置方案作为参考

  方案一:负载均衡服务器首先关闭连接 

  在这种情况下,因为负载均衡服务器对Web服务器的连接(注意,负载均衡器向Web服务器发起的主动连接),TIME_WAIT大都出现在负载均衡服务器上,所以,在负载均衡服务器上的配置:

  • net.ipv4.tcp_tw_reuse = 1 //尽量复用连接

  • net.ipv4.tcp_tw_recycle = 0 //不能保证客户端不在NAT的网络

    在Web服务器上的配置为:

  • net.ipv4.tcp_tw_reuse = 1 //这个配置主要影响的是Web服务器到DB服务器的连接复用

  • net.ipv4.tcp_tw_recycle:
    设置成1和0都没有任何意义。想一想,在负载均衡和它的连接中,它是服务端,但是TIME_WAIT出现在负载均衡服务器上;它和DB的连接,它是客户端,recycle对它并没有什么影响,关键是reuse

     

    方案二:Web服务器首先关闭来自负载均衡服务器的连接

    在这种情况下,Web服务器变成TIME_WAIT的重灾区。负载均衡对Web服务器的连接,由Web服务器首先关闭连接,TIME_WAIT出现在Web服务器上;Web服务器对DB服务器的连接,由Web服务器关闭连接,TIME_WAIT也出现在它身上,此时,负载均衡服务器上的配置:

  • net.ipv4.tcp_tw_reuse:0 或者 1 都行,都没有实际意义

  • net.ipv4.tcp_tw_recycle=0 //一定是关闭recycle

    在Web服务器上的配置:

  • net.ipv4.tcp_tw_reuse = 1 //这个配置主要影响的是Web服务器到DB服务器的连接复用

  • net.ipv4.tcp_tw_recycle=1 //由于在负载均衡和Web服务器之间并没有NAT的网络,可以考虑开启recycle,加速由于负载均衡和Web服务器之间的连接造成的大量TIME_WAIT


七、参考和引用资料

http://blog.oldboyedu.com/tcp-wait/

http://blog.chinaunix.net/uid-24517549-id-4048652.html

http://blog.chinaunix.net/uid-28337979-id-4107112.html 


    写在最后,内核的优化不能想当然,需要配合相应的业务场景。当然,这是一个长期积累的过程,需要不断的研究摸索,也需要众位同道多多分享多多赐教!与君共勉!

   

本文出自 “曳尾于涂” 博客,请务必保留此出处http://cangzihu.blog.51cto.com/6671848/1888622

版权声明:本文为博主原创文章,未经博主允许不得转载。

致Android-那些年,我们一起踩过的坑

大爷的,从搞android至今,踩过的坑倒是不少,MD,要是同一个坑,踩一次也就算了,踩两次、多次那就显得狠low了…记录那些年,希望跟我踩同一个坑的同胞们一些帮助(主要是怕自己踩同一个坑,哈哈~~)...
  • yiluyoufeng
  • yiluyoufeng
  • 2016年06月18日 23:29
  • 512

架构真经 | 那些年,我们踩过的缓存坑

在码农的世界里,一直以来都有一个信仰:只要应用使用了缓存,性能就会翻倍;用上缓存的应用就像是打通任督二脉的武林高手,内力生生不息。但是今天我想跟各位猿类朋友聊一聊自己在使用缓存时遇到的那些坑,这里主要...
  • qq_35246620
  • qq_35246620
  • 2017年05月05日 12:27
  • 1947

那些年,在nodejs上踩过的坑

原文:http://cnodejs.org/topic/4fc7789a8be5d070121141cd ----------------------------------------------...
  • zengmingen
  • zengmingen
  • 2016年05月12日 18:32
  • 418

前端总结:踩过的坑以及一些冷知识

主要是指css样式这一块。1、行内元素(比如img)默认会在末尾留白,无法去除。只能通过display:block;让其以块级元素进行显示。...
  • linysuccess
  • linysuccess
  • 2016年12月02日 10:56
  • 486

那些年踩过的mysql的坑

那些年踩过的mysql的坑 锁机制带来的锁死 一 不是通过主键来删除,而是通过其他的字段来删除,那么会导致表级锁,其他insert无法操作。 二 update 的时候,也会有锁表的情况,同...
  • gningh
  • gningh
  • 2016年11月25日 19:13
  • 759

Android开发踩过的坑

1.Fresco加载本地图片的问题在小米note 6.0手机上加载裁剪过的图片,发现有一个隐形的Bug,具体我也不清楚,只知道立即对裁剪过的图片地址进行加载的时候,加载失败,需要等待几秒后,重新加载就...
  • u011692041
  • u011692041
  • 2016年10月20日 10:15
  • 525

angularjs 容易踩到的坑

在Angular群里回答新手问题一段时间了,有一些Angular方面的坑留在这里备查,希望能对各位有所帮助。这个文章将来会随时更新,不会单独开新章,欢迎各位订阅。Q1. 错在哪里? 如果你这么写过,会...
  • nineteen73
  • nineteen73
  • 2016年08月27日 21:57
  • 396

那些年踩过的CSS坑(永久更新)

1、img 标签中的alt 与title的区别: alt  alt属性的实质作用是在图片无法正确显示时起到文本替代的作用,不过在IE6下还起到了title的作用。 title 鼠标滑过时显示的文字提示...
  • x_chengqq
  • x_chengqq
  • 2016年04月22日 21:11
  • 875

说说学习jquery时大伙都喜欢踩的七个坑,看看你中了几个

微句语录 2017-04-26 16:54 大伙学习中难免都会走歪路,今天就给大伙说说学习jquery时容易走的七个坑 这里还是要说一下我的前端学习群:594959296,从我一个人到...
  • u011277123
  • u011277123
  • 2017年04月27日 17:48
  • 331

那些年踩过的坑

以下内容都是我这半年来遇到的错误及解决方案,一些很快就解决了的错误我是不记录的,下面记录的都是或多或少花费了一些时间才搞定了而且觉得有必须记住,免得下次再犯类似的错。在这里记录一下,备忘.....在阿...
  • sdksdk0
  • sdksdk0
  • 2016年10月12日 22:47
  • 1414
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:那些年我们踩过的坑之TIME_WAIT调优
举报原因:
原因补充:

(最多只允许输入30个字)