可能的套接字连接数有多少?

89

有人知道现代标准Linux服务器上可以建立多少个TCP套接字连接吗?

(通常每个连接上的流量较少,但所有连接都必须始终保持开启状态。)


1
对于Windows,参见此问题[Windows并发TCP/IP连接的最大数量是多少?][1] [1]:https://dev59.com/7kbRa4cB1Zd3GeqPxiRO - lsalamon
8个回答

92

我在一台Linux桌面电脑上(16G内存,I7 2600 CPU)使用C语言编写的单线程HTTP服务器并使用epoll,实现了1600k并发空闲socket连接和同时达到57k req/s的性能。源代码可以在github上找到,这里有一篇博客。

编辑:

我使用JAVA/Clojure,在同一台计算机上实现了600k并发HTTP连接(客户端和服务器),详细信息请参见文章,HN讨论:http://news.ycombinator.com/item?id=5127251

每个连接的成本(使用epoll):

  • 应用程序需要为每个连接提供一些RAM
  • TCP缓冲区2 * 4k ~ 10k,或更多
  • 从epoll(7)中可以看出,epoll需要为文件描述符分配一些内存

在32位内核上,每个注册的文件描述符大约需要90个字节,在64位内核上则需要大约160个字节。


3
哈哈哈……1千万连接。这篇文章介绍了如何通过优化操作系统内核,实现同时处理10百万个并发连接的技术。 - Lothar
5
我的评论与Erlang没有任何关系,或者说与leef发布的关于在单个盒子上使用100万个套接字连接的评论完全不相关。因此,这个回答提到了160万的连接数量,所以leef的评论看起来有点愚蠢。虽然Erlang很棒,支持CouchDB,但我不认为你的评论在这里有任何相关性。 - wallacer

25

1
刚刚检查了我的Ubuntu(13.04)笔记本电脑...386491。我怀疑这不会是我遇到的第一个限制。 - Gerry
2
在我的Debian不稳定版(内核4.19.0-1-amd64)上:18446744073709551615。;) - Per Lundberg

10

在 /proc 文件系统中可以配置打开套接字的数量限制。

cat /proc/sys/fs/file-max

操作系统定义了整数限制,最大支持传入连接数量。

Linux本身支持数十亿个打开的套接字(sockets)。

要使用套接字,需要一个应用程序监听,例如Web服务器,并且每个套接字将使用一定数量的RAM。

RAM和CPU将引入实际限制。(现代2017年,考虑百万而不是十亿)

100万可行,但不容易。预计使用X GB RAM来管理100万个sockets。

传出TCP连接受端口号的限制,每个IP地址限制在约65000个。您可以拥有多个IP地址,但不是无限制的IP地址。 这是TCP而不是Linux的限制。


9

1万个?7万个?这就是全部吗 :)

如果你需要一个服务器,FreeBSD可能是你想要的选择。这里有一篇关于调整FreeBSD以处理10万个连接的小博客文章,它已经具备了一些有趣的功能,例如零拷贝套接字和kqueue作为完成端口机制。

Solaris在上个世纪就能处理10万个连接!他们说Linux会更好。

我遇到过的最好的描述是关于编写可扩展Web服务器的演示文稿/论文。他毫不畏惧地表达事实 :)

对于软件也是如此:应用层的白痴迫使操作系统层出现伟大的创新。因为Lotus Notes每个客户端保持一个TCP连接开启,IBM为Linux做出了“一个进程,100,000个打开的连接”情况下的主要优化。

O(1)调度程序最初是为了在某些无关紧要的Java基准测试中得分而创建的。底线是这种膨胀对我们所有人都有益。


3
因为测试已经通过,而且数量已经超过了客户的要求,所以我停在了70,000。随着非分页池限制计算方式的改变,我想在Windows Server 2008机器上建立10万个连接应该不会有问题。 - Len Holgate
你能分享一下你引用的演示文稿链接吗? - Brian Cline
1
@BrianCline 你可能不再需要这个了,但我也想要,并且我认为我找到了它:https://www.slideshare.net/Arbow/scalable-networking(第33张幻灯片) - Piyin

5
在Linux上,您应该考虑使用epoll进行异步I/O。同时,调整套接字缓冲区大小以避免每个连接浪费太多内核空间可能也很有价值。
我估计在一台合理的机器上,您应该能够达到10万个连接。

3

这取决于应用程序。如果每个客户端只有少数几个软件包,则Linux 的 100K 很容易处理。 我们团队的工程师多年前曾进行过一项测试,结果显示:在连接建立后,如果没有来自客户端的任何软件包,Linux epoll 可以在 CPU 使用率低于 50% 的情况下监视 400K 个 fd 以进行读取。


1

使用哪个操作系统?

对于Windows机器,如果您正在编写一个可扩展的服务器,并因此使用I/O完成端口和异步I/O,则主要限制是每个活动连接所使用的非分页池的数量。这直接转化为基于安装在计算机上的内存总量的限制(非分页池是一定的、固定大小的数量,基于安装的总内存)。

对于不太频繁访问的连接,您可以通过发布“零字节读取”来使它们更有效率,这不会使用非分页池,也不会影响锁定页面限制(另一个可能限制您打开大量套接字连接的资源)。

除此之外,您需要进行性能分析,但我已经成功地在一个配置适中的服务器(760MB内存)上获得了超过70,000个并发连接;请参见这里http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html以获取更多详细信息。

显而易见,如果你使用效率较低的架构,比如“每个连接一个线程”或者“选择”,那么你应该期望达到更少令人印象深刻的数字;但是,在我看来,没有理由为Windows Socket服务器选择这样的架构。

编辑:请参阅此处http://blogs.technet.com/markrussinovich/archive/2009/03/26/3211216.aspx。在Vista和Server 2008中,非分页池的数量计算方式已经改变,现在可用的资源更多了。


嗯,有趣。在W2K上具有128mb的非分页池和IOCP的情况下,我可以维持4,000个活动套接字(例如,同时流式传输)。当这些套接字处于空闲状态时,我可以维持大约16,000个套接字。我猜你的套接字是空闲的,或者这个零字节读取操作有所帮助。 - user82238
定义活动。您正在不同的机器上运行测试客户端?您正在使用某种形式的流量控制来管理发送的数据量?我的套接字正在回显消息,但没有使用零字节读取。它们没有全速运行并尽可能快地流式传输数据。 - Len Holgate
我以为在Windows上只能获得65k个连接 - 你必须编辑tcpnumconnections注册表设置。(而且在XP上,他们在tcpip.sys中进一步限制了它,在bittorrent网站上有很多关于这个问题的讨论) - gbjbaanb
2
你可能有些混淆了。tcpip.sys 中的限制是针对半开放连接的,它限制了您可以同时进行的并发连接数量。MaxUserPort 注册表项限制了客户端端口的数量,因此您可以设置的最大值将限制您可以建立的 OUTBOUND 连接数量。没有限制可用于 INBOUND 连接的数量。 - Len Holgate

-12

实际上,对于一个应用程序来说,在单台机器上打开超过4000-5000个套接字变得不切实际。仅仅检查所有套接字的活动并管理它们就开始成为性能问题 - 特别是在实时环境中。


4
这个陈述过于笼统。实际上,一切取决于您在应用层上所做的事情;在几乎所有情况下,这将成为您的性能瓶颈。 - DarkSquid
实际上,有很多正在运行的服务器远远超过这个并发连接数。 - user207421

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