一个Web服务器可以处理多少个套接字连接?

169

如果我考虑选择共享、虚拟或独立主机,我从某处了解到一台服务器/计算机在同一时间只能处理64,000个TCP连接,这是真的吗?不考虑带宽,任何类型的主机可以承载多少连接?我假设HTTP是基于TCP协议的。

这是否意味着只有64,000个用户可以连接到网站,如果我想提供更多连接,就必须转移到Web Farm上?


3
对于回复者,我很抱歉,我像龙卷风一样扫过了这个帖子。对于我来说,有太多不正确的答案,而且仍然没有直接的答案。我经常使用stackoverflow,并找到许多高质量的答案。我希望其他人能够找到这个帖子并找到一个有用的、明智的回答。 - Kind Contributor
嗨,David,你找到这个问题的正确答案了吗? - coretechie
服务器单个IP支持64000个TCP连接。您可以升级服务器网络以扩展并支持超过64000个连接。 - Airy
我猜这里有你正在寻找的答案。https://serverfault.com/questions/533611/how-do-high-traffic-sites-service-more-than-65535-tcp-connections - Nirav Chavda
8个回答

160
简而言之: 您应该能够在同时拥有百万级别的TCP连接以及扩展的HTTP请求中实现最大的性能表现,这告诉您,在正确的平台和正确的配置下,您可以期望什么样的最大性能表现。
今天,我担心IIS与ASP.NET是否支持100个并发连接(查看我的更新,旧版ASP.Net Mono版本预计每秒将有大约10k个响应)。当我看到这个问题/答案时,我忍不住自己回答,这里的许多问题答案都是完全不正确的。
最佳情况 回答这个问题必须只考虑最简单的服务器配置,以避免与众多可能的下游变量和配置产生耦合。
因此,考虑以下场景作为我的回答:
1.除了保持活动状态的数据包之外,没有任何TCP会话流量(否则您显然需要相应数量的网络带宽和其他计算机资源)。 2.软件使用异步套接字和编程来设计,而不是使用池中的每个请求的硬件线程。(即IIS、Node.js、Nginx等具有异步设计的Web服务器[但不是Apache]与应用程序软件) 3.良好的性能/价格比CPU / RAM。今天,任意地说,我们假设i7(4核)配备8GB的RAM。 4.匹配的良好防火墙/路由器。 5.没有虚拟极限/管理器-即Linux somaxconn,IIS web.config... 6.不依赖于其他较慢的硬件-不从硬盘读取,因为它将成为最低公共分母和瓶颈,而不是网络IO。
详细回答 相对于异步IO实现,同步线程绑定设计往往是性能最差的。
WhatsApp可以在单个Unix平台机器上处理带流量的100万个连接-https://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/。最后,这篇文章 http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html,详细探讨了如何实现甚至达到1000万并发连接。服务器通常具备硬件TCP卸载引擎,这是专门设计用于此目的比通用CPU更高效的ASIC芯片。

良好的软件设计选择

异步IO设计会因操作系统和编程平台而异。Node.js是以异步为设计思路。您应该至少使用Promise,并在ECMAScript 7推出后使用async/await。C#/.Net已经像node.js一样完全支持异步。无论选择哪个操作系统和平台,异步都应该表现非常好。无论选择哪种语言,都应该寻找“异步”关键字,大多数现代语言都会提供一些支持,即使是某种添加组件。

对WebFarm?

无论你的特定情况有什么限制,使用WebFarm是一个好的扩展解决方案。有许多实现这一点的架构。其中一种使用负载均衡器(托管提供商可以提供这些,但是即使这些也有限制,以及带宽极限),但我不青睐这个选项。对于具有长时间运行连接的单页面应用程序,我更喜欢拥有一个开放的服务器列表,客户端应用程序将在启动时随机选择并重用应用程序的生命周期。这消除了单点故障(负载均衡器),并允许通过多个数据中心进行扩展,从而拥有更多的带宽。

打破一个神话——64K端口

为了回答关于“64,000”这个组件的问题,这是一个误解。一个服务器可以连接到超过65535个客户端。请参见https://networkengineering.stackexchange.com/questions/48283/is-a-tcp-server-limited-to-65535-clients/48284 顺便说一句,在Windows上,Http.sys允许多个应用程序在HTTP URL模式下共享同一个服务器端口。它们各自注册单独的域绑定,但最终只有一个服务器应用程序将请求代理到正确的应用程序。
更新2019-05-30: 这里是最快的HTTP库的最新比较 - https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext
  • 测试日期:2018年6月6日
  • 使用的硬件:Dell R440 Xeon Gold + 10 GbE
  • 领先者每秒拥有约7M个纯文本响应(响应不是连接)
  • 第二名的golang Fasthttp宣传具有1.5M并发连接 - 请参见https://github.com/valyala/fasthttp
  • 领先的语言是Rust、Go、C++、Java、C,甚至C#排名第11(每秒6.9M)。Scala和Clojure排名较低。Python以每秒2.7M的速度排名第29。
  • 在列表底部,我注意到laravel和cakephp、rails、aspnet-mono-ngx、symfony、zend等。所有这些都低于每秒10k。请注意,这些大多数框架都是为动态页面构建的,而且相当古老,可能会有新的变体在列表中排名更高。
  • 请记住,这是HTTP明文传输的内容,而不是专为Websocket优化的特殊协议:许多来到这里的人可能会对支持Websocket的并发连接感兴趣。

  • 4
    感谢您包含链接,让人们可以了解如何实现它的经验分享。 - Rick Smith
    如果客户端连接的单个服务器崩溃了怎么办?如果你的所有SPA随机连接到一个服务器并使其超载呢?使用负载均衡器的想法不仅是使用1个,您可以根据需要使用多个。 - user1124403
    3
    客户将随机选择服务器。所有客户端随机连接到一个服务器的可能性几乎为零。虽然可以跟进客户端计数,如果某个服务器过于拥挤,服务器可以要求客户端移动到另一个服务器。 - Kind Contributor
    2
    关于64K限制 - 你所说的是正确的,但是服务器应用程序通常会通过代理请求到一些后端服务中,在这种情况下,“服务器”现在变成了“客户端”,可能需要担心短暂端口耗尽问题(例如:https://www.nginx.com/blog/overcoming-ephemeral-port-exhaustion-nginx-plus/)。我相信你知道这一点,但为其他人提及一下(: - jwd
    @jwd 好观点,对于在 Web 应用程序上下文中的 Nginx 来说是很有必要的,但是对于基本的网站来说,这种代理不是必须的。同样,通过 TCP 连接到数据库也可以这样说。理论上,这可以通过使用 127...* 范围内的所有地址来解决,但实际上我不知道这是否是可行的选项。 - Kind Contributor
    显示剩余2条评论

    63

    这是一个相当困难的问题。实际上,机器能够拥有的活动连接数量并没有真正的软件限制,尽管某些操作系统的限制比其他操作系统更为严格。问题变成了资源的问题。例如,假设单个机器想要支持64,000个同时连接。如果服务器每个连接使用1MB的RAM,则需要64GB的RAM。如果每个客户端都需要读取文件,则磁盘或存储阵列访问负载比这些设备可以处理的要大得多。如果服务器需要为每个连接fork一个进程,那么操作系统将花费大量时间进行上下文切换或使进程饿死。

    C10K问题页面对此问题进行了非常好的讨论。


    3
    有点复杂的答案。原帖似乎是在讨论最优情况,并提到如何达到最优,而不是找到最坏情况并参考可能有解决方案的文章。注意磁盘瓶颈很有用。使用异步IO可以达到非常高的并发客户端数量。 - Kind Contributor
    你怎么能说没有真正的软件限制,因为端口大小本身就是16位,这使得在任何时刻可用的最大端口数量最多只有65.5K。我认为你的答案是不正确的。 - आनंद
    你的计算机可以拥有多个 IP 地址,因此可以提供超过 2^16 个端口。 - Arman Ordookhani

    12

    补充一下,一个进程可以在 Linux 系统中同时打开等于此数字的已连接套接字数量的多个套接字(/proc/sys/net/core/somaxconn)。

    cat /proc/sys/net/core/somaxconn

    此数字可以即时更改(当然只能由 root 用户更改)。

    echo 1024 > /proc/sys/net/core/somaxconn

    但是,真正可以连接到系统之前崩溃的套接字数量完全取决于服务器进程、机器硬件和网络。


    1
    虽然这可能适用于Linux,但它指的是虚拟限制,而不是可能性的基准。这个答案有点太具体了,没有提供任何并发连接数量的数字或指示。尽管你很努力,但它并不是非常有用。也许你可以自问一个问题并回答:"为什么我在Linux上不能提供超过X个并发TCP连接?" - Kind Contributor
    4
    据我所知,这是错误的。 somaxconn 是一个打开的套接字上已排队连接的最大数量(即它是listen(int socket, int backlog)函数中 backlog 参数的最大值)。它与进程可以打开的套接字数量无关。 - Timmmm

    10

    如果你有一台强大的服务器,你的服务器软件进行了优化,并且你有足够的客户端,那么答案至少是1200万。如果你从一个客户端测试到一个服务器,客户端上的端口号数量将是明显的资源限制之一(每个TCP连接都由源IP和端口号以及目标IP和端口号的独特组合来定义)。

    (你需要运行多个客户端,否则你首先会遇到64K端口号限制)

    归根结底,这是一个经典的机智格言的例子,“理论和实践之间的差距在实践中比在理论中更大” - 在实践中,实现更高的数字似乎是一个循环过程:a.提出具体的配置/架构/代码更改,b.测试直到达到极限,c.我完成了吗?如果没有,那么d.确定是什么因素限制了,e.回到步骤a(反复操作)。

    这里有一个例子,使用2百万个TCP连接连接到一台强大的服务器(128GB RAM和40个核心),运行Phoenix http://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections - 他们最终需要50多个相当显著的服务器来提供客户端负载(他们最初的较小客户端很快达到极限,例如“在4核/15GB的服务器上达到45万客户端的极限”)。

    这里是另一个参考,这次是使用Go语言实现10百万个连接: http://goroutines.com/10m

    这似乎是基于Java的,并且支持12百万个连接:https://mrotaru.wordpress.com/2013/06/20/12-million-concurrent-connections-with-migratorydata-websocket-server/


    伟大的新链接,正确理解问题。我喜欢克服障碍的一般建议->修复障碍。每个人都有不同的具体情况,但至少他们在这里有一个经济/实际可行性的指示。我们不应该承诺客户很快就能为每台服务器提供1亿的服务。 - Kind Contributor

    6
    请注意,HTTP通常不会保持TCP连接的打开状态超过向客户端传输页面所需的时间;而用户阅读网页通常需要比下载页面更长的时间...... 当用户查看页面时,他根本不会对服务器造成任何负载。
    因此,可以同时查看您的网站的人数要比它可以同时提供的TCP连接数量大得多。

    18
    这完全没有回答问题。无论你所说的准确性如何,在任何给定时间都会有一定数量的并发TCP连接,最多能有多少?这才是问题的核心。 - Kind Contributor
    4
    如果你有值得贡献的东西,托德,请毫不犹豫地去做。 - Jeremy Friesner
    9
    我已经在3月28日回答了这个问题,你可能错过了。在现代的单页应用程序中,长轮询和Web Socket连接使得HTTP连接不总是短暂的。但即使它是短暂的,仍然存在最大并发连接数。尝试解释这个问题并不是我的答案。这个回答更适合作为对问题的评论,它确实有用,但问题涉及“socket连接”,而不是“人”。如果需要关于比率(用户:活动连接)的问题,请提出一个单独的问题。 - Kind Contributor
    1
    自上个千年以来,HTTP TCP连接的保持活动状态一直存在并被浏览器请求 - 连接是否保持活动状态以及空闲超时时间是由服务器决定的。允许保持活动状态可以减少一组请求(例如HTML页面及其相关资源)的延迟,但会增加服务器的资源使用率。 - iheggie

    2

    对于IPv4协议,只有一个IP地址且仅监听一个端口的服务器可以处理2^32个IP地址x 2^16个端口,因此有2^48个唯一的套接字。如果您将服务器视为物理机器,并且能够利用所有2^16个端口,则一个IP地址最多可以有2^48 x 2^16 = 2^64个唯一的TCP / IP套接字。请注意,某些端口保留供操作系统使用,因此此数字会更低。总之:

    1个IP和1个端口-> 2^48个套接字

    1个IP和所有端口-> 2^64个套接字

    宇宙中所有唯一的IPv4套接字-> 2^96个套接字


    1

    这里有两个不同的讨论:一个是有多少人可以连接到您的服务器。这个问题已经得到其他人的充分回答,所以我不会深入探讨。

    另一个是您的服务器可以监听多少个端口?我相信这就是64K数字的来源。实际上,TCP协议使用16位标识符来表示一个端口,这相当于65536(略大于64K)。这意味着您可以在每个IP地址上拥有那么多不同的“监听器”。


    为了您的利益,我在我的回答中添加了一个额外的部分来解决您的误解。此外,这个问题涉及到“套接字连接”,而不是“人”,这在这个问题的背景下是一个重要的区别。 - Kind Contributor
    如果我们只是在谈论一台服务器和一台路由器,我认为这个答案是正确的。但是@Todd提到了一组服务器机器,用户可以通过负载均衡器随机连接到其中任何一台。 - Amr
    @amr,那是不正确的。我的答案是关于单台机器的。"Webfarm?" 部分是为了对比和建议超越,并得出结论:在良好的架构下,负载均衡器是不必要的。你还没有仔细阅读我的答案。 - Kind Contributor

    0

    我认为一个Web服务器可以处理的并发套接字连接数量在很大程度上取决于每个连接消耗的资源量以及服务器上可用的总资源量,除非有其他Web服务器资源限制配置。

    举个例子,如果每个套接字连接消耗1MB的服务器资源,并且服务器有16GB的可用RAM(理论上),这意味着它只能处理(16GB / 1MB)并发连接。我认为这就是这么简单...真的!

    因此,无论Web服务器如何处理连接,每个连接最终都会消耗一些资源。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接