网络编程实战
盛延敏
前大众点评云平台首席架构师
44207 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 40 讲
网络编程实战
15
15
1.0x
00:00/00:00
登录|注册

10 | TIME_WAIT:隐藏在细节下的魔鬼

TCP时间戳的统一时钟
最大分组MSL的达成机制
现代Linux系统引入了更安全可控的方案
不要试图使用SO_LINGER设置套接字选项
TIME_WAIT的引入目的
net.ipv4.tcp_tw_reuse
SO_LINGER的设置
调低TCP_TIMEWAIT_LEN
net.ipv4.tcp_max_tw_buckets
对端口资源的占用
内存资源占用
让旧连接的重复分节在网络中自然消失
确保最后的ACK能让被动关闭方接收
升级线上应用服务导致可用性变化
思考题
总结
优化方法
危害
作用
产生场景
TIME_WAIT状态
TCP四次挥手
TCP和UDP的深入理解
本地套接字
UDP协议
TCP协议
C/S编程模型
提高篇
基础篇
网络编程实战的第10讲

该思维导图由 AI 生成,仅供参考

你好,我是盛延敏,这是网络编程实战的第 10 讲,欢迎回来。
在前面的基础篇里,我们对网络编程涉及到的基础知识进行了梳理,主要内容包括 C/S 编程模型、TCP 协议、UDP 协议和本地套接字等内容。在提高篇里,我将结合我的经验,引导你对 TCP 和 UDP 进行更深入的理解。
学习完提高篇之后,我希望你对如何提高 TCP 及 UDP 程序的健壮性有一个全面清晰的认识,从而为深入理解性能篇打下良好的基础。
在前面的基础篇里,我们了解了 TCP 四次挥手,在四次挥手的过程中,发起连接断开的一方会有一段时间处于 TIME_WAIT 的状态,你知道 TIME_WAIT 是用来做什么的么?在面试和实战中,TIME_WAIT 相关的问题始终是绕不过去的一道难题。下面就请跟随我,一起找出隐藏在细节下的魔鬼吧。

TIME_WAIT 发生的场景

让我们先从一例线上故障说起。在一次升级线上应用服务之后,我们发现该服务的可用性变得时好时坏,一段时间可以对外提供服务,一段时间突然又不可以,大家都百思不得其解。运维同学登录到服务所在的主机上,使用 netstat 命令查看后才发现,主机上有成千上万处于 TIME_WAIT 状态的连接。
经过层层剖析后,我们发现罪魁祸首就是 TIME_WAIT。为什么呢?我们这个应用服务需要通过发起 TCP 连接对外提供服务。每个连接会占用一个本地端口,当在高并发的情况下,TIME_WAIT 状态的连接过多,多到把本机可用的端口耗尽,应用服务对外表现的症状,就是不能正常工作了。当过了一段时间之后,处于 TIME_WAIT 的连接被系统回收并关闭后,释放出本地端口可供使用,应用服务对外表现为,可以正常工作。这样周而复始,便会出现了一会儿不可以,过一两分钟又可以正常工作的现象。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了网络编程中的TIME_WAIT状态对应用服务可用性的影响以及解决方法。通过描述一个线上故障案例,作者详细解释了TCP连接终止时主机进入TIME_WAIT状态的原因和作用,以及可能带来的危害。此外,作者提出了优化TIME_WAIT状态的方法,包括调整系统参数和设置套接字选项。文章还介绍了Linux系统提供的更安全的选择`net.ipv4.tcp_tw_reuse`选项,并解释了其安全可控的使用条件。最后,作者提出了两个思考题,引发读者对TCP时间戳和最大分组MSL的思考。整体而言,本文通过实际案例和技术原理深入浅出地介绍了TIME_WAIT状态的重要性和解决方法,对于网络编程领域的从业者具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《网络编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(77)

  • 最新
  • 精选
  • geraltlaush
    置顶
    net.ipv4.tcp_tw_recycle是客户端和服务器端都可以复用,但是容易造成端口接收数据混乱,4.12内核直接砍掉了,老师是因为内核去掉了所以没提了嘛

    作者回复: BINGO。太多了,大家也不好接受,我想我还是不求面面俱到,但求有所启发和引领。

    2019-08-23
    2
    32
  • 何某人
    老师,那么通过setsockopt设置SO_REUSEADDR这个方法呢?网上资料基本上都是通过设置这个来解决TIME_WAIT。这个方法有什么优劣吗?

    作者回复: 这个是解决端口复用的问题,并不是解决TIME_WAIT,这个是告诉内核,即使TIME_WAIT状态的套接字,我也可以继续使用它做为新的套集字使用。

    2019-08-23
    6
    34
  • 雷神的盛宴
    net.ipv4.tcp_tw_reuse 要慎用,当客户端与服务端主机时间不同步时,客户端的发送的消息会被直接拒绝掉

    作者回复: 学到了

    2019-12-20
    7
    30
  • AnonymousUser
    TIME_WAIT的作用: 1) 确保对方能够正确收到最后的ACK,帮助其关闭; 2) 防迷走报文对程序带来的影响。 TIME_WAIT的危害: 1) 占用内存; 2) 占用端口。

    作者回复: 总结很到位。

    2019-09-04
    2
    22
  • 张天屹
    文中的问题有个前提,必须是监听的端口。我看有评论提到80,8080这种服务,是否只能同时访问一次?答案是否定的。因为网络中的服务分为监听端口和连接端口,当建立一个连接之后,监听端口是不被占用的,此时会用一个新的端口来建立连接,而且就算是新的端口,一个TCP连接也是(客户端ip,客户端端口 ,服务端ip,服务端端口)共同决定的,不冲突。

    作者回复: 帮我回答了,赞

    2020-03-30
    5
    15
  • 蛮野
    Reuse只适用于连接发起方(C/S 模型中的客户端),但目前要解决的是服务端连接不足问题,这个方法要如何发挥作用呢?

    作者回复: 这里针对的TIME_WAIT是指主动关闭的一方,不一定是客户端或者服务器端,如果服务器端主动关闭连接,也是属于这样的范畴的。

    2019-12-13
    11
  • 丹枫无迹
    由于引入了时间戳,我们在前面提到的 2MSL 问题就不复存在了,因为重复的数据包会因为时间戳过期被自然丢弃。 这个没理解,为什么 2MSL 问题就不存在了?老师能解释下吗?

    作者回复: 这是因为时间戳会告诉我们报文发送的时间,这样在迷走报文和正确报文同时到达的情况下,我们就可以很方便的分辨出应该丢弃掉那个报文,并不会对最后收到的报文产生任何不利的影响。

    2020-02-02
    3
    10
  • 吴光庆
    为什么是2MSL,不是3 MSL,4 MSL。

    作者回复: 因为是一来一返。

    2019-08-26
    2
    10
  • JasonZhi
    SO_REUSEADDR和SO_REUSEPORT可以详细说下作用吗?有点迷糊,文章都没有说明这两个参数,评论区就冒出一大堆关于这两个参数的评论。

    作者回复: 哈哈,提前剧透啊。 这是为了解决如何快速复用处于TIME_WAIT的连接,如果不设置这个选项,处于TIME_WAIT的连接是不能被快速复用的,必须等待系统回收连接才可以,如果这个时候开启服务器端口,会报地址已被占用的错误。 这块在第15讲里会有详细阐述。

    2019-09-10
    7
  • pc
    先说点其他的吧:看完了基础篇,收获了很多,也更加期待后面的内容(本来就是冲着time_wait和epoll来到这个课程)。当然其中也遇到很多问题,其中也在评论区提了两个。本来以为这么长时间了老师也不会再回复了,周末一看,竟然回复了我的问题!其实一边是开心,另一边是得到答案的开心(其实自己也搜索过,但是感觉搜到文章都不是我想问的内容)。 【提问啦~】 1、看到评论区的“通过setsockopt设置SO_REUSEADDR这个方法”,感觉和net.ipv4.tcp_tw_reuse选项的作用也很像,都是端口复用,只是后者是在安全可控的基础上---这样理解对吗? 2、老师在文中说的“过了2MLS这个时间之后,主机 1 就进入 CLOSED 状态”,我自己还是没有总结出答案,是评论区所说的“去时ACK的最大存活时间(MSL)+来时FIIN的最大存活时间(MSL) = 2MSL”这个原因吗? 3、TIME_WAIT=2MLS和TCP_TIMEWAIT_LEN有啥关系?是:TIME_WAIT实际上是由TCP_TIMEWAIT_LEN控制,然后只不过其值约等于2MLS来控制迷走报文的消亡 这样么? 4、文中说TCP_TIMEWAIT_LEN、net.ipv4.tcp_tw_reuse都是linux的选项,但是客户端来说的话,有android、ios、windows各种系统吧?是每个系统都有类似的控制选项么?

    作者回复: 我一直都在回复的哦,和大家在一起自己也学到不少,哈哈。 以下试着回答你的问题: 1、看到评论区的“通过setsockopt设置SO_REUSEADDR这个方法”,感觉和net.ipv4.tcp_tw_reuse选项的作用也很像,都是端口复用,只是后者是在安全可控的基础上---这样理解对吗? 我认为不对哦,前者是针对服务端连接地址被占用的情况,后者是针对连接发起方; 2、老师在文中说的“过了2MLS这个时间之后,主机 1 就进入 CLOSED 状态”,我自己还是没有总结出答案,是评论区所说的“去时ACK的最大存活时间(MSL)+来时FIIN的最大存活时间(MSL) = 2MSL”这个原因吗? 你的意思是为什么要制定2MSL这个时间段才CLOSED是么?如果是这样,评论去的"去时ACK的最大存活时间(MSL)+来时FIIN的最大存活时间(MSL) = 2MSL"算是一个靠谱的理解吧。 3、TIME_WAIT=2MLS和TCP_TIMEWAIT_LEN有啥关系?是:TIME_WAIT实际上是由TCP_TIMEWAIT_LEN控制,然后只不过其值约等于2MLS来控制迷走报文的消亡 这样么? TIME_WAIT是一个抽象的定义,而TCP_TIMEWAIT_LEN是Linux默认的值,是一个常量。你的认识是对的 4、文中说TCP_TIMEWAIT_LEN、net.ipv4.tcp_tw_reuse都是linux的选项,但是客户端来说的话,有android、ios、windows各种系统吧?是每个系统都有类似的控制选项么? Android是裁剪过的Linux,应该可以复用;其他两个我不是很清楚,想必应该有自己的控制选项。

    2020-05-25
    6
收起评论
显示
设置
留言
77
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部