一个端口可以建立 2^16 个 TCP 链接吧,为什么讲解 time_wait 的博客大多都是说服务器端口被占满,难道一般情况下设计的服务器是为每一个 TCP 链接单独占用一个端口吗?
所有空闲端口*每个端口 2^16 个链接,差不多可以有 2^30 个链接,这样的话,不会发生 time_wait 过多的问题吧?
所以 time_wait 到底是占用了什么导致后续客户端访问被拒绝的?
1
soulzz 2020-06-10 10:02:05 +08:00
他们可能不知道 nio
time_wait 基本都是卡在数据库那里了 如果请求方做了超时处理,这时候就成了 close_wait 了 |
2
zjj19950716 2020-06-10 10:02:59 +08:00 via iPhone
cpu fd 内核参数 ?
|
3
hopingtop 2020-06-10 10:16:33 +08:00
如果服务是短链接,例如 HTTP 这种,高并发情况下,会创建很多新的 TCP 新链接。当服务器主动发起 FIN 包关闭链接时,会出现 2 个 MSL 的等待时间(此时的 fd 资源是没有释放的),这都是为了安全关闭 TCP 链接所做的机制。可以修改系统参数,适当的缓解 time_wait 这种情况。
|
4
fxxkgw 2020-06-10 10:19:42 +08:00
我记得看过的 time_wait 都是基本上说是占用系统资源,没有特别强调说把端口占满这种问题。。。正常端口范围是 1024-65535 之间
不过 time_wait 状态最好的办法就是扩容机器,盲目把 tcp_tw_recycle=1,在 NAT 环境下因为服务器间系统时间不一致,导致包时间戳不一致而产生丢包这种问题能折腾死人。 |
6
Moonkin OP @soulzz nio 对 time_wait 过多的问题有哪方面帮助啊? nio 是高并发的时候不需要每个为 socket new 一个处理线程吧。。
|
7
Moonkin OP @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 |
8
liuminghao233 2020-06-10 10:57:46 +08:00 via iPhone
你要是没用 reuseaddr
timewait 的时候用那个端口是不可用的 如果你几秒钟内把 2^16 个端口都用了 timewait 还没到时间 那么就没有端口用了 |
9
Moonkin OP @liuminghao233 也就是说,没有 reuseaddr 的话,每个端口只能有一个 TCP 链接吗?
|
10
raynor2011 2020-06-10 11:07:36 +08:00
是发起短连接的客户端会有 time_wait 占用端口问题, 服务器不会有这个问题
|
11
SAIKAII 2020-06-10 11:17:28 +08:00 via iPhone
1. 首先,每次来一个连接都对应一个套接字,套接字由(local_ip, local_port, remote_ip, remote_port)标志,然后每个新的连接套接字的本地 ip 和 port 不变,变的是 remote 的 ip 和 port 。
2,每个套接字对应一个文件描述符 fd,fd 用完就无法再创建了。wait_time 导致的资源耗尽是 fd 的耗尽,这个资源大小可以修改。 |
12
misaka19000 2020-06-10 11:17:28 +08:00
time_wait 一般是短连接太多导致的吧,解决办法是尽量复用 TCP 连接
|
13
misaka19000 2020-06-10 11:20:49 +08:00
楼上的一些文字真是让我很诧异,time_wati 和 nio 没关系,和 fd 也没关系
我估计楼主想问的是另一个问题:一个端口可以对应多个 TCP 链接吗? 答案是可以的,因为 client_host:client_port -- server_host:server_port 为一个连接,可见服务器端是可以维护多个连接的,一个连接会占用一个 fd,fd 由操作系统限制并且可以修改 |
14
sagaxu 2020-06-10 11:32:14 +08:00 via Android
time_wait 的时候,fd 已经 close 掉了,怎么个占用法呢?
|
15
Moonkin OP @misaka19000 那 time_wait 的危害是什么呢?为什么要减少 time_wait 。。。
|
16
Moonkin OP @raynor2011 也就是说客户端一个端口只能发起一个 tcp 链接吗?我看 StackOverflow 说“一个端口可以有 64K 个 tcp 链接”,这是说端口在服务器被监听的情况下才可以吗?发起方不能发起 64K 个?
|
17
gravitybox 2020-06-10 12:21:37 +08:00
@Moonkin time_wait 会占着端口不放,如果有大量的连接处于 time_wait,那么可能后续无法分配端口了。
|
18
misaka19000 2020-06-10 13:11:32 +08:00
@Moonkin #14 一个 time_wait 代表了一个未被释放的 TCP 连接,总归是会占用一些内存的,如果出现了大量的 time_wait 需要考虑是不是系统被攻击了或者有什么可以优化的地方
|
19
Moonkin OP @gravitybox 只有一个服务器而且只有一个客户端 才会出现端口占满的情况吧,因为这种情况只能客户端改变端口标识唯一 tcp
|
20
liuminghao233 2020-06-10 16:56:52 +08:00 via iPhone
@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] |
21
liuminghao233 2020-06-10 16:58:37 +08:00 via iPhone
打错了 是 reuseaddr
|
22
Moonkin OP @liuminghao233 #20 嗯,懂啦,谢谢大佬。查了查 so_reuseaddr 和 so_reuseport,感觉我这个问题还是得事先说清楚是不是 reuse
https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ |
24
catror 2020-06-10 18:20:58 +08:00 via Android
time_wait 是客户端的状态……占用的我是客户端的资源
|
25
julyclyde 2020-06-11 10:36:08 +08:00
“讲解 time_wait 的博客大多都是说服务器端口被占满”的主要原因是文盲
|
26
wanguorui123 2020-06-12 08:48:40 +08:00 via iPhone
修改 Linux 的参数,time_wait 都杀掉
|
27
gravitybox 2020-06-13 19:25:58 +08:00
“一个端口可以建立 2^16 个 TCP 链接吧”
答:一个端口可以建立不只 2^16 个 TCP 连接。标识一个 tcp 套接字是四元组,你现在只限定了源 ip 和源端口。 你这里的语境应该是: 1 、有一组固定的客户端 A 和服务端 B,即源 ip 和目的 ip 是固定的 2 、有服务端端口 6379,例如 B 上运行着 Redis 服务,绑定端口 6379 那么客户端 A 最多能和服务端 B 同时建立 65535-1024 个 tcp 连接。 “为什么讲解 time_wait 的博客大多都是说服务器端口被占满” 答:time_wait 是最先发 FIN 包的那一端才会有的状态,一般服务端不会主动断连,大多是客户端主动挥手,断开连接。 “难道一般情况下设计的服务器是为每一个 TCP 链接单独占用一个端口吗?” 答:服务端不会为每个 tcp 连接再分配端口。服务端为每个新的 tcp 连接会创建一个套接字,tcp 套接字是以四元组标识的,新的 tcp 连接,即对应不同的客户端 ip 或客户端端口。 |