高并发 TCP 的 time_wait 问题。为什么服务器资源会被占满

2020-06-10 09:36:51 +08:00
 Moonkin

一个端口可以建立 2^16 个 TCP 链接吧,为什么讲解 time_wait 的博客大多都是说服务器端口被占满,难道一般情况下设计的服务器是为每一个 TCP 链接单独占用一个端口吗?

所有空闲端口*每个端口 2^16 个链接,差不多可以有 2^30 个链接,这样的话,不会发生 time_wait 过多的问题吧?

所以 time_wait 到底是占用了什么导致后续客户端访问被拒绝的?

3928 次点击
所在节点    问与答
27 条回复
soulzz
2020-06-10 10:02:05 +08:00
他们可能不知道 nio
time_wait 基本都是卡在数据库那里了
如果请求方做了超时处理,这时候就成了 close_wait 了
zjj19950716
2020-06-10 10:02:59 +08:00
cpu fd 内核参数 ?
hopingtop
2020-06-10 10:16:33 +08:00
如果服务是短链接,例如 HTTP 这种,高并发情况下,会创建很多新的 TCP 新链接。当服务器主动发起 FIN 包关闭链接时,会出现 2 个 MSL 的等待时间(此时的 fd 资源是没有释放的),这都是为了安全关闭 TCP 链接所做的机制。可以修改系统参数,适当的缓解 time_wait 这种情况。
fxxkgw
2020-06-10 10:19:42 +08:00
我记得看过的 time_wait 都是基本上说是占用系统资源,没有特别强调说把端口占满这种问题。。。正常端口范围是 1024-65535 之间

不过 time_wait 状态最好的办法就是扩容机器,盲目把 tcp_tw_recycle=1,在 NAT 环境下因为服务器间系统时间不一致,导致包时间戳不一致而产生丢包这种问题能折腾死人。
rrfeng
2020-06-10 10:22:26 +08:00
fd 也是一种资源,一般是受限的( ulimit )
@fxxkgw
Moonkin
2020-06-10 10:45:47 +08:00
@soulzz nio 对 time_wait 过多的问题有哪方面帮助啊? nio 是高并发的时候不需要每个为 socket new 一个处理线程吧。。
Moonkin
2020-06-10 10:48:04 +08:00
@zjj19950716
@hopingtop
@fxxkgw
@rrfeng
我看这个 StackOverflow 上面的回答也是说 TCP 链接数目没有限制,是 fd 限制。。。可能我之前看的博客比较水吧。。。
https://stackoverflow.com/questions/2332741/what-is-the-theoretical-maximum-number-of-open-tcp-connections-that-a-modern-lin
liuminghao233
2020-06-10 10:57:46 +08:00
你要是没用 reuseaddr
timewait 的时候用那个端口是不可用的
如果你几秒钟内把 2^16 个端口都用了
timewait 还没到时间
那么就没有端口用了
Moonkin
2020-06-10 11:05:46 +08:00
@liuminghao233 也就是说,没有 reuseaddr 的话,每个端口只能有一个 TCP 链接吗?
raynor2011
2020-06-10 11:07:36 +08:00
是发起短连接的客户端会有 time_wait 占用端口问题, 服务器不会有这个问题
SAIKAII
2020-06-10 11:17:28 +08:00
1. 首先,每次来一个连接都对应一个套接字,套接字由(local_ip, local_port, remote_ip, remote_port)标志,然后每个新的连接套接字的本地 ip 和 port 不变,变的是 remote 的 ip 和 port 。
2,每个套接字对应一个文件描述符 fd,fd 用完就无法再创建了。wait_time 导致的资源耗尽是 fd 的耗尽,这个资源大小可以修改。
misaka19000
2020-06-10 11:17:28 +08:00
time_wait 一般是短连接太多导致的吧,解决办法是尽量复用 TCP 连接
misaka19000
2020-06-10 11:20:49 +08:00
楼上的一些文字真是让我很诧异,time_wati 和 nio 没关系,和 fd 也没关系

我估计楼主想问的是另一个问题:一个端口可以对应多个 TCP 链接吗?
答案是可以的,因为 client_host:client_port -- server_host:server_port 为一个连接,可见服务器端是可以维护多个连接的,一个连接会占用一个 fd,fd 由操作系统限制并且可以修改
sagaxu
2020-06-10 11:32:14 +08:00
time_wait 的时候,fd 已经 close 掉了,怎么个占用法呢?
Moonkin
2020-06-10 11:53:11 +08:00
@misaka19000 那 time_wait 的危害是什么呢?为什么要减少 time_wait 。。。
Moonkin
2020-06-10 11:56:24 +08:00
@raynor2011 也就是说客户端一个端口只能发起一个 tcp 链接吗?我看 StackOverflow 说“一个端口可以有 64K 个 tcp 链接”,这是说端口在服务器被监听的情况下才可以吗?发起方不能发起 64K 个?
gravitybox
2020-06-10 12:21:37 +08:00
@Moonkin time_wait 会占着端口不放,如果有大量的连接处于 time_wait,那么可能后续无法分配端口了。
misaka19000
2020-06-10 13:11:32 +08:00
@Moonkin #14 一个 time_wait 代表了一个未被释放的 TCP 连接,总归是会占用一些内存的,如果出现了大量的 time_wait 需要考虑是不是系统被攻击了或者有什么可以优化的地方
Moonkin
2020-06-10 16:32:22 +08:00
@gravitybox 只有一个服务器而且只有一个客户端 才会出现端口占满的情况吧,因为这种情况只能客户端改变端口标识唯一 tcp
liuminghao233
2020-06-10 16:56:52 +08:00
@Moonkin
假设你有个 tcp
10.10.10.10:6666—远程 8.8.8.8:80 timewait 了
你就暂时不能用
[10.10.10.10:6666—8.8.8.8:80]
但是有 reuseport 的话
虽然[10.10.10.10:6666—8.8.8.8:80]还是用不了
但是你可以用[10.10.10.10:6666—8.8.8.8:83]
或者是[10.10.10.10:6666—8.8.8.2:80]

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/680225

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX