{eval=Array;=+count(Array);}

问答专栏Q & A COLUMN

linux的TCP连接数量最大不能超过65535个吗,那服务器是如何应对百万千万的并发的?

edagarliedagarli 回答0 收藏1
收藏问题

10条回答

Blackjun

Blackjun

回答于2022-06-28 09:53

这明显是进入了思维的误区,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

即(源IP,源端口,目的IP,目的端口,协议号)

综上所述,服务器的并发数并不是由TCP的65535个端口决定的。服务器同时能够承受的并发数是由带宽、硬件、程序设计等多方面因素决定的

所以也就能理解淘宝、ucloud、我们、百度、新浪、哔哔哔哔等为什么能够承受住每秒种几亿次的并发访问,是因为他们采用的是服务器集群。服务器集群分布在全国各地的大型机房,当访问量小的时候会关闭一些服务器,当访问量大的时候回不断的开启新的服务器。


以上个人浅见,欢迎批评指正。

认同我的看法,请点个赞再走,感谢!

喜欢我的,请关注我,再次感谢!

评论0 赞同0
  •  加载中...
garfileo

garfileo

回答于2022-06-28 09:53

首先,问题中描述的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/linux下限制连接数的主要因素是内存和允许的文件描述符个数(每个tcp连接都要占用一定内存,每个socket就是一个文件描述符),另外1024以下的端口通常为保留端口。

所以,对server端,通过增加内存、修改最大文件描述符个数等参数,单机最大并发TCP连接数超过10万,甚至上百万是没问题的。

评论0 赞同0
  •  加载中...
zr_hebo

zr_hebo

回答于2022-06-28 09:53

你这个提问中有一些逻辑的错误,我来一一给你解释一下。

第一个错误的地方是,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连接数越大。

但是一个网站可以有多个服务器啊,可以有集群服务器啊,服务器的规模越大,支持的访问能力就越强,所以这个也不是问题。

比如ucloud巴巴是如何撑过双11的?ucloud云在北上广深等很多地方都有服务器,而且每个地方的服务器都是弹性集群,这些服务器实时同步保障淘宝上的数据一致。所以双11访问淘宝时,有的访问的是北京的服务器,有的访问的是上海的服务器,这样通过分布式服务分布式的存储,网站可以应对的并发自然就很大了。

评论0 赞同0
  •  加载中...
bingo

bingo

回答于2022-06-28 09:53

Hi,你好。很高兴看到并回答此问题。如果我的回答对你有帮助,记得点个赞哦~~

下面我结合之前的项目来回答一下。


楼主所理解的65535(端口数量)与连接数是一个东西,这个是错的。具体原因前面已经有不少同行小伙伴描述的非常清楚了,我就不再阐述了。

下面我具体来回答一下楼主的后半部分:服务器是如何支撑百万并发的。


下面阐述的观点是:通过优化系统架构提升系统负载能力,即提高系统并发量。


一、什么是高并发



高并发是互联网系统所面临的普通问题,也是系统架构时考虑的重要因素之一。

并发与负载】是相对的两个词。

想实现高并发,就要提高系统负载能力。系统负载能力强了,自然可以处理高并发请求。

所以,实现高并发,本质就是提高系统的负载能力。

一般对于系统负载能力的评估参数有:响应时间 、吞吐量、每秒请求数QPS、并发用户数。

  • 响应时间:系统对请求做出响应的时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统的响应时间。
  • 吞吐量:单位时间内处理的请求数量。
  • QPS:每秒响应请求数,与吞吐量概念类似。
  • 并发用户数:同时使用系统功能的用户数量。


二、如何提高并发处理能力(并发数)


需要说明的是:以下内容不考虑【带宽】和【硬件配置】这两个因素。

很显然,带宽高、硬件配置高,系统负载能力就强,能处理的并发用户数就多。


那么如何提高并发处理能力呢?

答案就是:通过优化系统架构来提高并发处理能力。

并且系统架构设计是一个复杂的过程,不仅涉及到技术层面,还包括业务层面。



三、通过业务拆分提高并发处理能力(微服务架构)



将一个系统拆分为多个子系统,每个子系统负责一个多带带的服务,这就是常说的【服务治理】


拆分为多个子系统后,每个子系统(服务)独立运行,每个服务之间通过REST/RPC方式调用,用户也可以直接调用这些服务接口。

这种设计将大化小,这种架构也称为【微服务架构】。


举例:商城系统中,可拆分为【订单服务】【用户服务】【产品服务】等多个服务接口。



四、通过水平扩展提高并发处理能力

这一块要分开来讲。


1. 前端部分



使用nginx反向代理软件提高并发处理量

nginx进行水平扩展:DNS轮询等


2. 应用服务器部分



java中常见的应用服务器tomcat为例,它可以实现集群和负载均衡。集群配置成功后,相当于提供了一个“服务器池”,如果想要再提高处理能力,只需要向“池”中继续添加应用服务器即可。另外,集群也实现了系统高可用。


3. 数据库层面

常见的分库分表,读写分离都是解决数据库压力大的方法之一。

数据库瓶颈是系统在运行中最先碰到、最常碰到的问题之一。

经常见到的问题就是磁盘IO高,导致处理缓慢。

刚才所说方法都可以解决这一问题。

常见的分表原则有:按范围分,按哈希值分。


4. 缓存层面



在系统中添加缓存是当前必选的方案。

添加缓存的主要目标是减少磁盘IO。

可以缓存的内容很多,例如缓存页面内容(HTML,CSS,图片),缓存应用服务器中数据对象等。

通过设计多级缓存,实现数据的快速获取、请求的快速响应。

在分布式架构中,还要注意分布式缓存的更新一致性问题。(不再详述)


五、最后


其实很多系统的并发数都不到百万级,只有少量头部网站才会有,例如淘宝。

但我们之所以研究如何解决百万级并发架构,是从中学会和掌握【系统架构演变过程】


系统架构设计的原则是:适合的就是最好的。不能刚开始架构就要满足百万级,因为这样设计会提高成本,造成资源浪费。

所以,我们要明白:系统架构是演进的。


只有当我们经历了从【单一架构】至【分布式架构】这一过程,才能真正理解架构的能力。在这过程中,你的架构能力也会飞快增长。



我是一名Java全栈开发工程师、系统架构师,从业15年。曾带领小团队完成多个数百万级项目。我正在写一些关于互联网行业及开发技术方面的文章。关注我,你一定会有所收获。


如果有项目开发、行业及求职方面的问题,都可以在评论区留言或私信我。(关注后私信我,向你免费分享行业级学习资料)

评论0 赞同0
  •  加载中...
ZweiZhao

ZweiZhao

回答于2022-06-28 09:53

你好,IT行业的码农前来答题。

题主有一个概念上的误解,错误的把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%的警戒线,那么就会及时采用限流或者扩展集群的方式来保证服务,绝对不会出现服务器的内存被耗尽的情况,那样就算事故了。


总之,65,535只是Linux系统中可使用端口port数量的上限,端口port数量与TCP连接数量并非完全一一对应的关系,服务器支持的TCP并发连接数量主要跟服务器的内存以及允许单个进程同时打开的文件数量有关系,通过端口复用及调整服务器参数等手段,单台服务器支持的TCP并发连接数是可以高于65,535的。

评论0 赞同0
  •  加载中...
waltr

waltr

回答于2022-06-28 09:53

TCP/IP 协议规定了端口数占两个字节,所以 65535 是端口数的上限,但是和连接数不是一个意思。

一个 TCP 连接(会话)用四元组来标识:

客户端IP : 源端口 -> 服务器 IP : 目的端口

TCP 连接大概有这么几种场景:

1,服务端需要监听特定的端口(socket listen),比如 WEB 需要监听 80 和 8080 端口,监听的端口是独占的,也就是说同一 IP 的端口绑定数量上限是 65535;

2,客户端连接服务器,系统会自动分配本地空闲端口,本地端口也是独占的,所以传出连接数(Outgoing)上限是 65535;

3,当服务端收到传入的连接请求(socket accept)并建立连接,对于服务端而言,传入连接并不会产生新的端口占用,连接数量不受端口限制,而是操作系统和系统资源限制。

评论0 赞同0
  •  加载中...
Batkid

Batkid

回答于2022-06-28 09:53

首先,问题中描述的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/linux下限制连接数的主要因素是内存和允许的文件描述符个数(每个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

即(源IP,源端口,目的IP,目的端口,协议号)

综上所述,服务器的并发数并不是由TCP的65535个端口决定的。服务器同时能够承受的并发数是由带宽、硬件、程序设计等多方面因素决定的。

所以也就能理解淘宝、ucloud、我们、百度、新浪、哔哔哔哔等为什么能够承受住每秒种几亿次的并发访问,是因为他们采用的是服务器集群。服务器集群分布在全国各地的大型机房,当访问量小的时候会关闭一些服务器,当访问量大的时候回不断的开启新的服务器。

以上个人浅见,欢迎批评指正。

认同我的看法,请点个赞再走,感谢!

你这个提问中有一些逻辑的错误,我来一一给你解释一下。

第一个错误的地方是,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连接数越大。

但是一个网站可以有多个服务器啊,可以有集群服务器啊,服务器的规模越大,支持的访问能力就越强,所以这个也不是问题。

比如ucloud巴巴是如何撑过双11的?ucloud云在北上广深等很多地方都有服务器,而且每个地方的服务器都是弹性集群,这些服务器实时同步保障淘宝上的数据一致。所以双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%的警戒线,那么就会及时采用限流或者扩展集群的方式来保证服务,绝对不会出现服务器的内存被耗尽的情况,那样就算事故了。

总之,65,535只是Linux系统中可使用端口port数量的上限,端口port数量与TCP连接数量并非完全一一对应的关系,服务器支持的TCP并发连接数量主要跟服务器的内存以及允许单个进程同时打开的文件数量有关系,通过端口复用及调整服务器参数等手段,单台服务器支持的TCP并发连接数是可以高于65,535的。


评论0 赞同0
  •  加载中...
elisa.yang

elisa.yang

回答于2022-06-28 09:53

作为一个资深的Layer4-7层网络测试人员,回答你的问题:)

其实这个问题,根源在于你不理解服务器是使用IP+端口号方式工作的,看我下面的解释。

Linux的TCP连接数量最大不能超过65535个

首先,这个说法是正确的,但是有限定。它指的是Linux系统作为client,从它自身发起的连接不能超过65535个,并且用的是源端口号。

而对于一台电脑上来说,一个端口号就表示一个进程,所以一台电脑的最大进程个数为65535。

请看下图:

这个就是TCP的报文格式,它的头部一般为20字节,而用来表示源/目端口的字段都是2字节,即16bits,所以2的16次方,最大值为65535(从0开始)。

其实不仅是Linux系统,现在存在的Windows、MAC、Android等系统,都是一样的。

服务器如何应对百万千万的并发?

看下面的两张图片,是否理解了呢?

第一张:三台PC同时访问服务器,向服务器发送连接请求:

  • 三台PC发送报文时,他们的源IP地址都不相同
  • 三台PC发送报文时,他们的目的IP和目的端口号都相同
  • 服务器只监听一个端口号

第二张图片:服务器回复3台PC的连接请求:



  • 服务器回复3台PC时,源IP和源端口号都相同;
  • 服务器回复3台PC时,目的IP地址不同;

看到这里,各位小伙伴应该明白为啥服务器能够处理百万千万的并发了吧?

因为服务器处理数据时,会同时使用 IP和端口号,而不是只单纯的使用端口号;

IPv4地址理论上有4,294,967,296,在加上每一台PC可以有65535个源端口,这样它们的乘积完全是一个天文数字,完全没有必要为服务器担心。

服务器只使用一个IP+一个端口就可以实现百万千万的并发

看完上面的内容,小伙伴只需要记住,服务器在实现连接时,并不只使用端口号,还需要使用IP地址,而IP地址理论是有43亿左右的,这样完全不用担心不够用的问题。

欢迎关注我,一起学习和讨论网络知识,共同进步,共同成长!

评论0 赞同0
  •  加载中...
mdluo

mdluo

回答于2022-06-28 09:53

你的理解有误。65535这个最大值指的是你作为客户端去连别人,而你作为服务器,别人来连你,理论上是没有限制的。注意,仅仅理论上。

65535是怎么来的?是TCP协议规定的端口字段的最大范围,2个字节,16比特,每一比特有0和2种状态,按照排列组合,2的16次方,一共就是65536,端口0预留不用,就是65535。

客户端每发起一次TCP连接,要消耗一个端口,并独占该端口,最大只能同时发起65535个TCP连接,实际上65535这个最大值只是TCP协议的规定,操作系统还有限制呢,发起主动连接前1024个端口号(0-1023)都不给用,真实最大只有64512个。

说完客户端再说服务端。服务端一般都监听某一个端口,比如80的web端口,比如22的ssh端口,比如3306的mysql端口,都是在被动等待别人来连,所以没有限制。

你如果真要算最大值也能算。TCP连接的唯一性靠四元组,源目的IP,源目的端口,假设服务端只有一个IP,开了一个端口,相当于把两个固定了,另两个的范围一个是0.0.0.0-255.255.255.255,一个是0-65535,一乘就是最大连接数。其实按照比特数最好算,2的32次方乘上个2的16次方,作为服务端最大连接数就是2的48次方。有意义吗?没有意义!

前面为什么又说是理论上无限制呢,因为最大的限制不在TCP连接数上,而在硬件上,主要是CPU和内存,一个连接占几k内存。一个市面上现在普通的物理服务器,最大也就十几万并发连接吧。

题主所述服务器如何应对百万千万的并发,现在没什么好办法,其实就是堆服务器,一台十万,十台百万,百台千万……我们给这一堆服务器一个高大上的名字,“集群”。

评论0 赞同0
  •  加载中...
zhangwang

zhangwang

回答于2022-06-28 09:53

本来不想回答这个问题,因为太简单,但是上下浏览了下,竟然没一个人答到点子上,不得不说一句。

这个问题说道点子上其实挺简单。

那就是服务器百万,千万并发,并不是同时你认为的“同时”连接。

而是依次排队通讯。

只是因为服务器性能高,排队速度很快,所以看似并发。

那个连接数跟多少万并发没任何关系。

是指不同的服务端口。

而讲服务器能支持多少万并发的性能,讲的是同一个服务,在同一个端口上的并发。

是通过高速排队实现的。

至于你说单台服务器性能不够,出现了排队延迟,无法让人觉得是并发。那就涉及到服务器阵列的问题了。

这是另一个话题。

本质上是通过多台服务器联合工作打破单台服务器硬件性能瓶颈。

跟这个话题实质上并不是同一个话题。

换句话说,所谓的百万级并发,千万级并发,通常意义上来讲,都是假并发,实质是排队通讯。

都是有先来后到的。

只是说,因为性能足够高,以在多少排队限度内,让用户感觉是在并发。那就是这个服务器能实现多少级别的“并发”。

至于你说,要做到真并发。

这就是同时处理。

这在实践上是不科学的,因为真并发之后,为了保障分布部署的服务器的数据一致性,同步数据的数据带来的处理量会超过真并发带来的“好处”。

当然。

实践中,可以用两个一千万级“假并发”真排队通讯,通过互相之间的数据同步的“真并发”,把原本只能实现一千万级假并发的两个服务器,组合成两千万级的假并发。

在硬件性能达到极限的情况下。

这种组合可以让并发数实现极限突破。

ucloud云的上亿级别的并发技术就是这样实现的。

评论0 赞同0
  •  加载中...

最新活动

您已邀请0人回答 查看邀请

我的邀请列表

  • 擅长该话题
  • 回答过该话题
  • 我关注的人
向帮助了您的网友说句感谢的话吧!
付费偷看金额在0.1-10元之间
<