一台服务器最多能创建多少个TCP链接
最多能创建65535个TCP连接,这其实是错误的理解
port_range
我们都知道linux下本地随机端口范围由参数控制,也就是listen、connect时候如果没有指定本地端口,那么就从下面的port range中随机取一个可用的
[root@iZ2ze3wkkxook36ezx5zykZ opt]# cat /proc/sys/net/ipv4/ip_local_port_range 32768 65535
port range的上限是65535,所以也经常看到这个误解:一台机器上最多能创建65535个TCP连接
到底一台机器上最多能创建多少个TCP连接
先说结论:在内存、文件句柄足够的话可以创建的连接是没有限制的(每个TCP连接至少要消耗一个文件句柄)。
那么/proc/sys/net/ipv4/ip_local_port_range指定的端口范围到底是什么意思呢?
核心规则:一个TCP连接只要保证四元组(src-ip src-port dest-ip dest-port)唯一就可以了,而不是要求src port唯一
后面所讲都遵循这个规则,所以在心里反复默念:四元组唯一 五个大字,就能分析出来到底能创建多少TCP连接了。
比如如下这个机器上的TCP连接实际状态:
# netstat -ant |grep 18089 tcp 0 0 192.168.1.79:18089 192.168.1.79:22 ESTABLISHED tcp 0 0 192.168.1.79:18089 192.168.1.79:18080 ESTABLISHED tcp 0 0 192.168.0.79:18089 192.168.0.79:22 TIME_WAIT tcp 0 0 192.168.1.79:22 192.168.1.79:18089 ESTABLISHED tcp 0 0 192.168.1.79:18080 192.168.1.79:18089 ESTABLISHED
从前三行可以清楚地看到18089被用了三次,第一第二行src-ip、dest-ip也是重复的,但是dest port不一样,第三行的src-port还是18089,但是src-ip变了。他们的四元组均不相同。
所以一台机器能创建的TCP连接是没有限制的,而ip_local_port_range是指没有bind的时候OS随机分配端口的范围,但是分配到的端口要同时满足五元组唯一,这样 ip_local_port_range 限制的是连同一个目标(dest-ip和dest-port一样)的port的数量(请忽略本地多网卡的情况,因为dest-ip为以后route只会选用一个本地ip)。
存在误解的两个因素:
- 如果是listen服务,那么肯定端口不能重复使用,这样就跟我们的误解对应上了,一个服务器上最多能监听65535个端口。比如nginx监听了80端口,那么tomcat就没法再监听80端口了,这里的80端口只能监听一次(如果有个连接用了80连别人,这里80还是不能被listen……想想)。
- 另外如果我们要连的server只有一个,比如:1.1.1.1:80 ,同时本机只有一个ip的话,那么这个时候即使直接调connect 也只能创建出65535个连接,因为四元组中的三个是固定的了。
我们在创建连接前,经常会先调bind,bind后可以调listen当做服务端监听,也可以直接调connect当做client来连服务端。
bind(ip,port=0) 的时候是让系统绑定到某个网卡和自动分配的端口,此时系统没有办法确定接下来这个socket是要去connect还是listen. 如果是listen的话,那么肯定是不能出现端口冲突的,如果是connect的话,只要满足4元组唯一即可。在这种情况下,系统只能尽可能满足更强的要求,就是先要求端口不能冲突,即使之后去connect的时候四元组是唯一的。
但如果我只是个client端,只需要连接server建立连接,也就不需要bind,直接调connect就可以了,这个时候只要保证四元组唯一就行。
tcp_max_tw_buckets
tcp_max_tw_buckets: 在 TIME_WAIT 数量等于 tcp_max_tw_buckets 时,新的连接断开不再进入TIME_WAIT阶段,而是直接断开,并打印warnning.
实际测试发现 在 TIME_WAIT 数量等于 tcp_max_tw_buckets 时 新的连接仍然可以不断地创建和断开,这个参数大小不会影响性能,只是影响TIME_WAIT 数量的展示(当然 TIME_WAIT 太多导致local port不够除外), 这个值设置小一点会避免出现端口不够的情况