10 | TIME_WAIT:隐藏在细节下的魔鬼
10 | TIME_WAIT:隐藏在细节下的魔鬼
讲述:冯永吉
时长10:57大小10.04M
TIME_WAIT 发生的场景
TIME_WAIT 的作用
TIME_WAIT 的危害
如何优化 TIME_WAIT?
net.ipv4.tcp_max_tw_buckets
调低 TCP_TIMEWAIT_LEN,重新编译系统
SO_LINGER 的设置
net.ipv4.tcp_tw_reuse:更安全的设置
总结
思考题
赞 31
提建议
精选留言(76)
- Leon📷置顶2019-08-23net.ipv4.tcp_tw_recycle是客户端和服务器端都可以复用,但是容易造成端口接收数据混乱,4.12内核直接砍掉了,老师是因为内核去掉了所以没提了嘛
作者回复: BINGO。太多了,大家也不好接受,我想我还是不求面面俱到,但求有所启发和引领。
共 2 条评论30 - 何某人2019-08-23老师,那么通过setsockopt设置SO_REUSEADDR这个方法呢?网上资料基本上都是通过设置这个来解决TIME_WAIT。这个方法有什么优劣吗?
作者回复: 这个是解决端口复用的问题,并不是解决TIME_WAIT,这个是告诉内核,即使TIME_WAIT状态的套接字,我也可以继续使用它做为新的套集字使用。
共 6 条评论34 - 雷神的盛宴2019-12-20net.ipv4.tcp_tw_reuse 要慎用,当客户端与服务端主机时间不同步时,客户端的发送的消息会被直接拒绝掉
作者回复: 学到了
共 6 条评论27 - 许童童2019-08-231. MSL的意思是最长报文段寿命。IP头部中有个TTL字段意思是生存时间。TTL每经过一个路由器就减1,到0就会被丢弃,而MSL是由RFC里面规定的2分钟,但实际在工程上2分钟太长,因此TCP允许根据具体的情况配置大小,TTL与MSL是有关系的但不是简单的相等关系,MSL要大于TTL。MSL内部应该就是一个普通的定时器实现的。 2.不需要统一时钟,可以在第一次交换双方的时钟,之后用相对时间就可以了。共 1 条评论23
- AnonymousUser2019-09-04TIME_WAIT的作用: 1) 确保对方能够正确收到最后的ACK,帮助其关闭; 2) 防迷走报文对程序带来的影响。 TIME_WAIT的危害: 1) 占用内存; 2) 占用端口。展开
作者回复: 总结很到位。
共 2 条评论21 - 张天屹2020-03-30文中的问题有个前提,必须是监听的端口。我看有评论提到80,8080这种服务,是否只能同时访问一次?答案是否定的。因为网络中的服务分为监听端口和连接端口,当建立一个连接之后,监听端口是不被占用的,此时会用一个新的端口来建立连接,而且就算是新的端口,一个TCP连接也是(客户端ip,客户端端口 ,服务端ip,服务端端口)共同决定的,不冲突。
作者回复: 帮我回答了,赞
共 4 条评论15 - alan2019-08-23TIME_WAIT的作用: 1. 确保主动断开方的最后一个ACK成功发到对方 2. 确保残留的TCP包自然消亡共 1 条评论10
- 丹枫无迹2020-02-02由于引入了时间戳,我们在前面提到的 2MSL 问题就不复存在了,因为重复的数据包会因为时间戳过期被自然丢弃。 这个没理解,为什么 2MSL 问题就不存在了?老师能解释下吗?
作者回复: 这是因为时间戳会告诉我们报文发送的时间,这样在迷走报文和正确报文同时到达的情况下,我们就可以很方便的分辨出应该丢弃掉那个报文,并不会对最后收到的报文产生任何不利的影响。
共 2 条评论9 - 云师兄2019-12-13Reuse只适用于连接发起方(C/S 模型中的客户端),但目前要解决的是服务端连接不足问题,这个方法要如何发挥作用呢?
作者回复: 这里针对的TIME_WAIT是指主动关闭的一方,不一定是客户端或者服务器端,如果服务器端主动关闭连接,也是属于这样的范畴的。
9 - 吴光庆2019-08-26为什么是2MSL,不是3 MSL,4 MSL。
作者回复: 因为是一来一返。
共 2 条评论9 - JasonZhi2019-09-10SO_REUSEADDR和SO_REUSEPORT可以详细说下作用吗?有点迷糊,文章都没有说明这两个参数,评论区就冒出一大堆关于这两个参数的评论。
作者回复: 哈哈,提前剧透啊。 这是为了解决如何快速复用处于TIME_WAIT的连接,如果不设置这个选项,处于TIME_WAIT的连接是不能被快速复用的,必须等待系统回收连接才可以,如果这个时候开启服务器端口,会报地址已被占用的错误。 这块在第15讲里会有详细阐述。
7 - pc2020-05-25先说点其他的吧:看完了基础篇,收获了很多,也更加期待后面的内容(本来就是冲着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,应该可以复用;其他两个我不是很清楚,想必应该有自己的控制选项。
5 - tongmin_tsai2019-09-30老师,我有疑问的是,IP包中TTL每经过一次路由就少1,那么2MSL怎么确保可以一定大于TTL的?
作者回复: 只要每次经过一跳的时间肯定大于1秒以上就可以了,实际处理的时间肯定大于这个值的。 2MSL设置的为60秒,TTL设置为60,只有每次一跳都大于1秒,那么肯定时间总和大于60秒了。
共 5 条评论5 - magicnum2019-09-011.记录一个值,比如60s,经过一个网关就减去一定短值,值=0的时候网关决定丢弃; 2.不需要。timestamp不需要交互,只是发送方使用的共 3 条评论4
- Geek_9a01802019-08-23印象中是当一端关闭socket连接,另一端如果尝试从TCP连接中读取数据,则会报connect reset,如果偿试向连接中写入数据,则会报connect reset by peer,好像和老师说的正相反,还请老师帮忙解答一下,谢谢:)
作者回复: 首先,我不明白connect reset和connect reset by peer有啥区别哎,这两个不是一回事么?都是RST信号。 其次,我确认读的时候会读到FIN报文,连续写则会得到RST结果。
共 2 条评论4 - Dovelol2019-08-23老师好,想问个问题,一般我们服务器上运行一个服务,比如tomcat,zk这种,然后监听8080或2181端口,这时候外部直连(不再经过web服务器转发)的话,虽然有很多连接但服务端应该都是只占用一个端口,也就是说netstat -anp命令看到的本机都是ip+固定端口,那么此时如果服务端主动关闭一些连接的话,也会有大量time_wait问题对吧,但此时好像并没有消耗更多端口,那这个影响对于服务端来说是什么呢?老师讲的出现大量time_wait应该都是在客户端的一方吧,因为客户端发起请求会占用一个新端口,主动关闭到time_wait阶段就相当于这个新的端口一直被占用。我还有个疑问是,这种大量time_wait在连接数多的情况下是肯定会出现的,是不是可以从减少连接的方向去解决问题呢,比如用连接池这种技术可以解决吗?展开
作者回复: 这个时候你看到的连接都是服务器端被动建立的连接,本地端口都是服务器监听的端口,类似 <127.0.0.1, 80, ip1, 51231> <127.0.0.1, 80, ip2, 51331> ... 所以,不会存在我讲到的那个问题,这些个连接过了一段时间自然会被回收。 连接池是为了多个线程复用连接,减少TCP连接的数量,是为了更高效的使用TCP,确实也客观减少了连接的数量。
共 4 条评论4 - 列夫托尔斯泰克洛伊来...2020-07-08这个可控优化的方法没明白,是复用端口的意思吗?不过复用端口数据不混乱了?
作者回复: 不是端口复用,是复用处于 TIME_WAIT 的套接字为新的连接所用。前提在文中也提到了,是通过TCP时间戳来解决2MSL的问题。
3 - Liam2019-08-24老师好,我又2个问题不明白: 1 为什么说time_wait会占用过多端口,难道不是占用socket而已吗?比如一个server与多个client建立多个连接,对于server而言只会占用一个端口吧 2 什么是报文的自然消亡,指的是报文发送到对方或报文正常丢弃吗?然后对连接化身这段看不明白展开
作者回复: 1. 我说的情况是主动断开连接的一方,比如一个客户端每次对外建立一个连接,这是要消耗一个本地端口的,只不过这个端口在我们建立连接的时候由内核帮我们选好了; 2. 报文的自然消亡,就是TTL时间为0了,不会在网络中继续传播,到了某个网络设备,报文会被丢弃掉。
3 - Initiative Thinker2021-08-24复用后的套接字,如何恢复旧连接的FIN呢?
作者回复: 是说"回复"吧? 处于 TIME_WAIT 的套接字为新的连接所用,通过时间戳可以知道旧连接的FIN是一个无效的FIN,从而直接回复RST,让旧连接直接出错退出。
2 - Geek_9edd4f2021-03-02“第二是对端口资源的占用,一个 TCP 连接至少消耗一个本地端口。要知道,端口资源也是有限的,一般可以开启的端口为 32768~61000 ,也可以通过net.ipv4.ip_local_port_range指定,如果 TIME_WAIT 状态过多,会导致无法创建新连接。这个也是我们在一开始讲到的那个例子。” 这里不是很理解,服务端提供服务应该就只用一个端口号吧?而客户端请求服务应该也是只使用一个端口号吧?普通个人客户就发起一个请求只用一个端口号,为什么会出现端口号不够用的情况?难道指的的为客户服务的代理服务器可能会端口号不够用吗?因为代理服务器要处理来自成千上万的客户请求,需要选择不同的端口号为客户服务,将请求发给服务器吗?展开
作者回复: 这个例子是客户端发起连接过多,每次发起连接都会占用一个端口。客户端和服务端是相对,比如一个应用程序对于客户的请求是服务端,同时为了服务这个客户请求,又要向另一个服务发起调用请求(典型的例子是向数据库发起连接请求)。
2