linux的TCP连接数量最⼤不能超过65535个吗,那服务器是如何
应对百万千万的并发的?
⾸先,问题中描述的65535个连接指的是客户端连接数的限制。
在tcp应⽤中,server事先在某个固定端⼝监听,client主动发起连接,经过三路握⼿后建⽴tcp连接。那么对单机,其最⼤并发tcp连接数是多少呢?
如何标识⼀个TCP连接
在确定最⼤连接数之前,先来看看系统如何标识⼀个tcp连接。系统⽤⼀个4四元组来唯⼀标识⼀个TCP连接:{localip,
localport,remoteip,remoteport}。
client最⼤tcp连接数
client每次发起tcp连接请求时,除⾮绑定端⼝,通常会让系统选取⼀个空闲的本地端⼝(local port),该端⼝是独占的,不能和其他tcp连接共享。tcp端⼝的数据类型是unsigned short,因此本地端⼝个数最⼤只
有65536,端⼝0有特殊含义,不能使⽤,这样可⽤端⼝最多只有65535,所以在全部作为client端的情况下,⼀个client最⼤tcp连接数为65535,这些连接可以连到不同的serverip。
server最⼤tcp连接数
server通常固定在某个本地端⼝上监听,等待client的连接请求。不考虑地址重⽤(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端⼝也是独占的,因此server端tcp连接4元组中只有remoteip(也就是clientip)和remote port(客户端port)是可变的,因此最⼤tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最⼤tcp连接数约为2的32次⽅(ip数)×2的16次⽅(port 数),也就是server端单机最⼤tcp连接数约为2的48次⽅。
实际的tcp连接数
上⾯给出的是理论上的单机最⼤连接数,在实际环境中,受到机器资源、操作系统等的限制,特别是sever端,其最⼤并发tcp连接数远不能达到理论上限。在unix/下限制连接数的主要因素是内存和允许的⽂件描述符个数(每个tcp连接都要占⽤⼀定内存,每个socket就是⼀个⽂件描述符),另外1024以下的端⼝通常为保留端⼝。
所以,对server端,通过增加内存、修改最⼤⽂件描述符个数等参数,单机最⼤并发TCP连接数超过10万,甚⾄上百万是没问题的。
这明显是进⼊了思维的误区,65535是指可⽤的端⼝总数,并不代表服务器同时只能接受65535个并发连接。
举个例⼦:
我们做了⼀个⽹站,绑定的是TCP的80端⼝,结果是所有访问这个⽹站的⽤户都是通过服务器的80端⼝访问,⽽不是其他端⼝。可见端⼝是可以复⽤的。即使Linux服务器只在80端⼝侦听服务,也允许有10万、100万个⽤户连接服务器。Linux系统不会限制连接数⾄于服务器能不能承受住这么多的连接,取决于服务器的硬件配置、软件架构及优化。
01
我们知道两个进程如果需要进⾏通讯最基本的⼀个前提是:能够唯⼀的标⽰⼀个进程。在本地进程通讯中我们可以使⽤PID来唯⼀标⽰⼀个进程,但PID只在本地唯⼀,⽹络中的两个进程PID冲突⼏率很⼤。
这时候就需要另辟它径了,IP地址可以唯⼀标⽰主机,⽽TCP层协议和端⼝号可以唯⼀标⽰主机的⼀个进程,这样可以利⽤IP地址+协议+端⼝号唯⼀标⽰⽹络中的⼀个进程。
能够唯⼀标⽰⽹络中的进程后,它们就可以利⽤socket进⾏通信了。socket(套接字)是在应⽤层和传输层之间的⼀个抽象层,它把TCP/IP 层复杂的操作抽象为⼏个简单的接⼝供应⽤层调⽤已实现进程在
⽹络中通信。socket源⾃Unix,是⼀种"打开—读/写—关闭"模式的实现,服务器和客户端各⾃维护⼀个"⽂件",在建⽴连接打开后,可以向⾃⼰⽂件写⼊内容供对⽅读取或者读取对⽅内容,通讯结束时关闭⽂件。
02
唯⼀能够确定⼀个连接有4个东西:
1. 服务器的IP
2. 服务器的Port
3. 客户端的IP
4. 客户端的Port
服务器的IP和Port可以保持不变,只要客户端的IP和Port彼此不同就可以确定⼀个连接数。
⼀个socket是可以建⽴多个连接的,⼀个TCP连接的标记为⼀个四元组(source_ip, source_port, destination_ip, destination_port),即(源IP,源端⼝,⽬的IP,⽬的端⼝)四个元素的组合。只要四个元素的组合中有⼀个元素不⼀样,那就可以区别不同的连接。
举个例⼦:
->你的主机IP地址是1.1.1.1,在8080端⼝监听
->当⼀个来⾃ 2.2.2.2 发来⼀条连接请求,端⼝为5555。这条连接的四元组为(1.1.1.1, 8080, 2.2.2.2, 5555)
->这时2.2.2.2⼜发来第⼆条连接请求,端⼝为6666。新连接的四元组为(1.1.1.1, 8080, 2.2.2.2, 6666)
那么,你主机的8080端⼝建⽴了两条连接;
->(2.2.2.2)发来的第三条连接请求,端⼝为5555(或6666)。第三条连接的请求就⽆法建⽴,因为没有办法区分于上⾯两条连接。
同理,可以在同⼀个端⼝号和IP地址上绑定⼀个TCP socket和⼀个UDP socket
因为端⼝号虽然⼀样,但由于协议不⼀样,所以端⼝是完全独⽴的。
TCP/UDP⼀般采⽤五元组来定位⼀个连接:
source_ip, source_port, destination_ip, destination_port, protocol_type
socket通信在哪一层即(源IP,源端⼝,⽬的IP,⽬的端⼝,协议号)
综上所述,服务器的并发数并不是由TCP的65535个端⼝决定的。服务器同时能够承受的并发数是由带宽、硬件、程序设计等多⽅⾯因素决定的。
所以也就能理解淘宝、腾讯、头条、百度、新浪、哔哔哔哔等为什么能够承受住每秒种⼏亿次的并发访问,是因为他们采⽤的是服务器集。服务器集分布在全国各地的⼤型机房,当访问量⼩的时候会关闭⼀些服务器,当访问量⼤的时候回不断的开启新的服务器。
以上个⼈浅见,欢迎批评指正。
认同我的看法,请点个赞再⾛,感谢!
你这个提问中有⼀些逻辑的错误,我来⼀⼀给你解释⼀下。
第⼀个错误的地⽅是,TCP连接数量和Linux没有关系。不管是Windows还是Linux,只要使⽤TCP/IP,那么单个IP地址连接相同互联⽹服务的TCP连接数,就不会超过65535个,甚⾄在⼀般情况下,我们认为不会超过4万个(注意,这⾥指相同互联⽹服务,即相同⽬的地址和端⼝)。
这个原因是因为,TCP/IP中,⼀个TCP连接,就要耗费源IP地址⼀个TCP端⼝,⽽TCP的端⼝数量也就是65535个,因为协议规定了TCP端⼝的长度也就是16位(⼆进制),所以换成⼗进制也就是1~65535.
这也就意味着,如果你的电脑要访问⼀个⽹站,那么你的电脑只能和这个⽹站建⽴65535个连接,⼀个连接消耗⼀个TCP端⼝。当然这是理想的情况,实际的情况是,有很多端⼝被⼀些知名的协议占据了,或者做了预留,例如80端⼝就属于HTTP的,所以⼀般认为能使⽤的端⼝就是4万个左右。
第⼆个错误是,TCP的端⼝数量和服务器没有关系。因为这⾥所说的4万个TCP的端⼝,是指源端⼝,也就是你访问⽹站时使⽤的个⼈电脑使⽤的端⼝,⽽对于⽬的端⼝,也就是⽹站的端⼝,使⽤的TCP端⼝也就是相同的23端⼝。这个意思也就意味着,4万个连接都连的是这个⽹站的23端⼝,换⼀个⽤户⼜可以⽤4万个连接连接服务器的23端⼝。
所以我们可以粗略估算⼀下,如果是100万个并发连接,在1个⽤户4万个访问的情况下,也就是25个并发的⽤户。当然,实际使⽤时,你的PC机不会有4万个连接访问相同的⽹站,假设我们按照⼀个PC机4个连接访问⽹站计算,100万个并发也就是25万个⽤户访问。
最后回答⼀下你的问题,服务器如何撑住百万千万个TCP连接呢?这个和服务器的资源有关。实际上单个服务器⽀持的TCP连接数的确是有限的,单个服务器所⽀持的TCP连接不可能到达理论值,服务连接⼀多,CPU撑不住内存也顶不住,所以每个服务器都有规格限制,硬件性
能越强,服务器⽀持的TCP连接数越⼤。
但是⼀个⽹站可以有多个服务器啊,可以有集服务器啊,服务器的规模越⼤,⽀持的访问能⼒就越强,所以这个也不是问题。
⽐如阿⾥巴巴是如何撑过双11的?阿⾥云在北上⼴深等很多地⽅都有服务器,⽽且每个地⽅的服务器都是弹性集,这些服务器实时同步保障淘宝上的数据⼀致。所以双11访问淘宝时,有的访问的是北京的服务器,有的访问的是上海的服务器,这样通过分布式服务分布式的存储,⽹站可以应对的并发⾃然就很⼤了。
楼主所理解的65535(端⼝数量)与连接数是⼀个东西,这个是错的。具体原因前⾯已经有不少同⾏⼩伙伴描述的⾮常清楚了,我就不再阐述了。
下⾯我具体来回答⼀下楼主的后半部分:服务器是如何⽀撑百万并发的。
下⾯阐述的观点是:通过优化系统架构提升系统负载能⼒,即提⾼系统并发量。
⼀、什么是⾼并发
⾼并发是互联⽹系统所⾯临的普通问题,也是系统架构时考虑的重要因素之⼀。
【并发与负载】是相对的两个词。
想实现⾼并发,就要提⾼系统负载能⼒。系统负载能⼒强了,⾃然可以处理⾼并发请求。
所以,实现⾼并发,本质就是提⾼系统的负载能⼒。
⼀般对于系统负载能⼒的评估参数有:响应时间、吞吐量、每秒请求数QPS、并发⽤户数。
响应时间:系统对请求做出响应的时间。例如系统处理⼀个HTTP请求需要200ms,这个200ms就是系统的响应时间。
吞吐量:单位时间内处理的请求数量。
QPS:每秒响应请求数,与吞吐量概念类似。
并发⽤户数:同时使⽤系统功能的⽤户数量。
⼆、如何提⾼并发处理能⼒(并发数)
需要说明的是:以下内容不考虑【带宽】和【硬件配置】这两个因素。
很显然,带宽⾼、硬件配置⾼,系统负载能⼒就强,能处理的并发⽤户数就多。
那么如何提⾼并发处理能⼒呢?
答案就是:通过优化系统架构来提⾼并发处理能⼒。
并且系统架构设计是⼀个复杂的过程,不仅涉及到技术层⾯,还包括业务层⾯。
三、通过业务拆分提⾼并发处理能⼒(微服务架构)
将⼀个系统拆分为多个⼦系统,每个⼦系统负责⼀个单独的服务,这就是常说的【服务治理】
拆分为多个⼦系统后,每个⼦系统(服务)独⽴运⾏,每个服务之间通过REST/RPC⽅式调⽤,⽤户也可以直接调⽤这些服务接⼝。
这种设计将⼤化⼩,这种架构也称为【微服务架构】。
举例:商城系统中,可拆分为【订单服务】【⽤户服务】【产品服务】等多个服务接⼝。
四、通过⽔平扩展提⾼并发处理能⼒
这⼀块要分开来讲。
1. 前端部分
使⽤nginx反向代理软件提⾼并发处理量
nginx进⾏⽔平扩展:DNS轮询等
2. 应⽤服务器部分
java中常见的应⽤服务器tomcat为例,它可以实现集和负载均衡。集配置成功后,相当于提供了⼀个“服务器池”,如果想要再提⾼处理能⼒,只需要向“池”中继续添加应⽤服务器即可。另外,集也实现了系统⾼可⽤。
3. 数据库层⾯
常见的分库分表,读写分离都是解决数据库压⼒⼤的⽅法之⼀。
数据库瓶颈是系统在运⾏中最先碰到、最常碰到的问题之⼀。
经常见到的问题就是磁盘IO⾼,导致处理缓慢。
刚才所说⽅法都可以解决这⼀问题。
常见的分表原则有:按范围分,按哈希值分。
4. 缓存层⾯
在系统中添加缓存是当前必选的⽅案。
添加缓存的主要⽬标是减少磁盘IO。
可以缓存的内容很多,例如缓存页⾯内容(HTML,CSS,图⽚),缓存应⽤服务器中数据对象等。
通过设计多级缓存,实现数据的快速获取、请求的快速响应。
在分布式架构中,还要注意分布式缓存的更新⼀致性问题。(不再详述)
五、最后
其实很多系统的并发数都不到百万级,只有少量头部⽹站才会有,例如淘宝。
但我们之所以研究如何解决百万级并发架构,是从中学会和掌握【系统架构演变过程】。
系统架构设计的原则是:适合的就是最好的。不能刚开始架构就要满⾜百万级,因为这样设计会提⾼成本,造成资源浪费。
所以,我们要明⽩:系统架构是演进的。
题主有⼀个概念上的误解,错误的把TCP端⼝号的上限65535理解成了TCP连接数的上限,进⽽认为Linux⽆法实现超过65,535个的并发任务,实际上端⼝号数量和TCP连接数确实有关联,但并⾮⼀⼀对应的关系。
65,535从哪来的,⼲啥的?
要解释好这个问题,就要先说清楚65,535的含义。在Linux系统中,如果两个机器要通信,那么相互之间需要建⽴TCP连接,为了让双⽅互相认识,Linux系统⽤⼀个四元组来唯⼀标识⼀个TCP连接: {local ip, local port, remote ip, remote port},即本机IP、本机端⼝、远程IP、远程端⼝,IP和端⼝就相当于⼩区地址和门牌号,只有拿到这些信息,通信的双⽅才能互相认知。在Linux系统中,表⽰端⼝号(port)的变量占16位,这就决定了端⼝号最多有2的16次⽅个,即65,536个,另外端⼝0有特殊含义不给使⽤,这样每个服务器最多就有65,535个端⼝可⽤。因此,65,535代表Linux系统⽀持的TCP端⼝号数量,在TCP建⽴连接时会使⽤。
TCP怎么建⽴连接,与端⼝号是什么关系?
Linux服务器在交互时,⼀般有两种⾝份:客户端或者服务器端。典型的交互场景是:
(1)服务器端主动创建监听的socket,并绑定对外服务端⼝port,然后开始监听
(2)客户端想跟服务器端通信时,就开始连接服务器的端⼝port
(3)服务端接受客户端的请求,然后再⽣成新的socket
(4)服务器和客户端在新的socket⾥进⾏通信
可以看到,端⼝port主要⽤在服务器和客户端的“握⼿认识”过程,⼀旦互相认识了,就会⽣成的的socket进⾏通信,这时候port就不再需要了,可以给别的socket通信去使⽤,所以很明显TCP连接的数量可以⼤于TCP端⼝号的数量65,535。
考虑⼀下两个极端场景,即某台Linux服务器只作为客户端或者服务器端
(1)Linux服务器只作为客户端
这时候每发起⼀个TCP请求,系统就会指定⼀个空间的本地端⼝给你⽤,⽽且是独占式的,不会被别的TCP连接抢⾛,这样最多可以建⽴65535个连接,每个连接都与不同的服务器进⾏交互。这种场景,就是题主所描述的样⼦,但是由于条件过于苛刻,属于⼩概率事件,所以更多的还是理论上的可能,现实的环境中⼏乎不会出现。
(2)Linux服务器只作为服务端
这种场景下,服务端就会固定的监听本地端⼝port,等着客户端来向它发起请求。为了计算简单,我们假设服务器端的IP跟端⼝是多对⼀的,这样TCP四元组⾥⾯就有remote ip和remote port是可变的,因此最⼤⽀持创建TCP个数为2的32次⽅(IP地址是32位的)乘以2的16次⽅(port是16位的)等于2的48次⽅。
现实中单台Linux服务器⽀持的TCP连接数量
通过前⾯的分析我们知道,在现实场景中,由于存在端⼝port复⽤的情况,服务器可同时⽀持的TCP连接数跟65,535没有⼀⼀对应关系,事实上,真正影响TCP连接数量的,是服务器的内存以及允许单⼀进程同时打开⽂件的数量,因为每创建⼀个TCP连接都要创建⼀个socket句柄,每个socket句柄都占⽤⼀部分系统内存,当系统内存被占⽤殆尽,允许的TCP并发连接数也就到了上限。⼀般来讲,通过增加服务器内存、修改最⼤⽂件描述符个数等,可以做到单台服务器⽀持10万+的TCP并发。
当然,在真实的商⽤场景下,单台服务器都会编⼊分布式集,通过负载均衡算法动态的调度不同⽤户的请求给最空闲的服务器,如果服务器平均内存使⽤超过80%的警戒线,那么就会及时采⽤限流或者扩展集的⽅式来保证服务,绝对不会出现服务器的内存被耗尽的情况,那样就算事故了。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论