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

假设我要获得共享、虚拟或专用主机,我在某处读到一台服务器/机器一次只能处理64,000个 TCP 连接,这是真的吗?不管带宽如何,任何类型的主机能够处理多少个?我假设 HTTP 在 TCP 上工作。

这是否意味着只有64,000个用户可以连接到该网站,如果我想提供更多服务,我就必须搬到一个网络农场?

146153 次浏览

请注意,HTTP 通常不会保持 TCP 连接的开放时间超过将网页传输到客户端所需的时间; 用户阅读网页通常比下载网页花费更多的时间... ... 当用户浏览网页时,他根本不会给服务器增加任何负载。

因此,可以同时浏览您的网站的人数远远超过它可以同时提供服务的 TCP 连接的数量。

这是一个相当难的问题。虽然有些操作系统比其他操作系统受到更多的限制,但是对于一台计算机可以拥有的活动连接的数量并没有真正的软件限制。问题变成了资源之一。例如,假设一台机器希望支持64,000个并发连接。如果服务器每个连接使用1MB RAM,那么它将需要64GB RAM。如果每个客户端都需要读取一个文件,那么磁盘或存储阵列访问负载将大大超出这些设备的处理能力。如果一个服务器需要为每个连接分叉一个进程,那么操作系统将花费大部分时间进行上下文切换,或者让进程不能占用 CPU 时间。

C10K 问题页面对这个问题进行了很好的讨论。

为了增加我的见解,一个进程可以同时打开与这个数字相等的多个套接字(在 Linux 类型系统中)/proc/sys/net/core/somaxFoxconn

Cat/proc/sys/net/core/somaxconi

这个数字可以动态修改(当然只能由 root 用户修改)

Echo 1024 >/proc/sys/net/core/somaxconi

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

简而言之: 您应该能够在 数百万中实现同时活动的 TCP 连接和通过扩展 HTTP 请求。这将告诉您使用正确的平台和正确的配置所能期望的最大性能。

今天,我担心带有 ASP.NET 的 IIS 是否能够支持100个并发连接(看看我的更新,预计在旧版 ASP.Net Mono 上每秒会有10000个响应)。当我看到这个问题/答案的时候,我情不自禁地回答了自己,这个问题的许多答案都是完全错误的。

最好的情况

这个问题的答案必须只与最简单的服务器配置有关,以便与下游可能出现的无数变量和配置解耦。

因此,考虑下面的情况,我的答案是:

  1. TCP 会话上没有流量,除了保持活动的数据包(否则显然需要相应数量的网络带宽和其他计算机资源)
  2. 设计用于使用异步套接字和编程的软件,而不是使用来自池的每个请求的硬件线程。(即。IIS,Node.js,Nginx... webserver [但不包括 Apache ]和异步设计的应用软件)
  3. 性能良好/CPU/RAM。今天,我们随意地假设 i7(4内核)有8GB 内存。
  4. 一个很好的防火墙/路由器匹配。
  5. 没有虚拟限制/调控器-即。
  6. 不依赖其他较慢的硬件-不从硬盘读取,因为这将是最小公分母和瓶颈,而不是网络 IO。

详细答案

相对于异步 IO 实现,同步线程绑定设计的性能往往最差。

WhatsApp 可以在一台 Unix 风格的操作系统机器 https://blog.whatsapp.com/index.php/2012/01/1-million-is-so-2011/上处理100万个 WITH 流量。

最后,这一个,http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html,进入了很多细节,探索如何甚至1000万可以实现。服务器通常有硬件 TCP 卸载引擎,专门为这一特定角色设计的 ASIC 比通用 CPU 更有效。

良好的软件设计选择

异步 IO 设计将因操作系统和编程平台而异。Js 的设计考虑到了 异步的。你应该至少使用承诺,当 ECMAScript 7出现时,async/await。C #/.Net 已经有了像 node.js 这样的完全异步支持。无论操作系统和平台如何,异步应该能够很好地执行。无论您选择哪种语言,请查找关键字“异步”,大多数现代语言都会有一些支持,即使它是某种附加组件。

去 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-06-06
  • 硬件使用: 戴尔 R440至强金 + 10 GbE
  • 领导者每秒钟有约7M 个明文响应(响应不是连接)
  • 第二个针对 golang 的 Fastttp 广告了150万个并发连接——参见 https://github.com/valyala/fasthttp
  • 最主要的语言是 Rust、 Go、 C + + 、 Java、 C,甚至 C # 排名为11(每秒6.9 M)。Scala 和 Clojure 的排名更低。Python 以每秒2.7 M 的速度排在第29位。
  • 在列表的底部,我注意到 laravel 和 cakephp、 ails、 aspnet-mono-ngx、 symfony、 zend。都在每秒一万以下。注意,这些框架大部分都是为动态页面构建的,而且相当老旧,可能会有更新的变体在列表中位置更高。
  • 请记住,这是 HTTP 明文,而不是 Websocket 专长: 许多来这里的人可能会对 Websocket 的并发连接感兴趣。

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

其他是你的服务器可以监听多少端口?我相信这就是64K 号码的来源。实际上,TCP 协议使用16位标识符作为端口,即转换为65536(略高于64K)。这意味着在每个 IP 地址的服务器上可以有许多不同的“监听器”。

看起来答案至少是1200万,如果你有一个强大的服务器,你的服务器软件为它进行了优化,你有足够的客户端。如果您从一个客户机到一个服务器进行测试,客户机上的端口号将是明显的资源限制之一(每个 TCP 连接由源和目的地的 IP 和端口号的唯一组合来定义)。

(您需要运行多个客户端,否则将首先触及端口号的64K 限制)

归根结底,这是一个典型的俏皮话的例子,“理论和实践之间的差异在实践中比在理论上大得多”-在实践中实现更高的数字似乎是一个循环的 a 提出具体的配置/架构/代码变化,b 测试它直到你达到一个极限,c 我完成了吗?如果没有,那么 d 找出什么是限制因素,例如回到步骤 a (清洗和重复)。

这里有一个例子,200万 TCP 连接到一个强大的盒子(128 GB 内存和40个核心)运行 Phoenix http://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections-他们最终需要50个左右合理的重要服务器,只是为了提供客户端负载(他们最初的小客户端最大化到早期,例如“最大化我们的4core/15gb box@450k 客户端”)。

这里是另一个参考去这个时候在一千万: http://goroutines.com/10m

这似乎是基于 Java 和1200万个连接: https://mrotaru.wordpress.com/2013/06/20/12-million-concurrent-connections-with-migratorydata-websocket-server/

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

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

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

对于 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个套接字