如何同时保留一百万个TCP连接?

如何同时保留一百万个TCP连接?,tcp,Tcp,我要设计一个服务器,它需要为数百万通过TCP与服务器同时连接的客户端提供服务 服务器和客户端之间的数据通信量将是稀疏的,因此可以忽略带宽问题 一个重要的要求是,每当服务器需要向任何客户端发送数据时,它都应该使用现有的TCP连接,而不是打开指向客户端的新连接(因为客户端可能位于防火墙后面) 有人知道怎么做吗?需要什么硬件/软件(至少成本最低)?这个问题与所谓的问题有关。C10K页面列出了大量很好的资源,用于解决您在尝试允许数千个客户端连接到同一服务器时遇到的问题。编辑:正如下面的评论中所指出的,我

我要设计一个服务器,它需要为数百万通过TCP与服务器同时连接的客户端提供服务

服务器和客户端之间的数据通信量将是稀疏的,因此可以忽略带宽问题

一个重要的要求是,每当服务器需要向任何客户端发送数据时,它都应该使用现有的TCP连接,而不是打开指向客户端的新连接(因为客户端可能位于防火墙后面)


有人知道怎么做吗?需要什么硬件/软件(至少成本最低)?

这个问题与所谓的问题有关。C10K页面列出了大量很好的资源,用于解决您在尝试允许数千个客户端连接到同一服务器时遇到的问题。

编辑:正如下面的评论中所指出的,我最初断言的基于端口数的64K限制是不正确的,但是,套接字句柄的数量有32K的限制,因此我建议的设计是有效的

对于典型的TCP/IP服务器设计,您可以同时打开的连接数量有限。服务器有一个侦听端口,当客户端连接到该端口时,服务器会发出一个接受调用,并在随机端口上为其余连接创建一个新套接字

要处理超过64K的同时连接,我认为您需要使用UDP。服务器只需要一个端口就可以侦听,并且需要在数据包中使用32位客户端ID来管理连接,而不是为每个客户端使用单独的端口。32位客户端ID可以是客户端的IP地址,客户端可以在已知的UDP端口上侦听从服务器返回的消息。该端口将是防火墙上唯一需要打开的端口

使用这种方法,您唯一的限制是处理和响应UDP消息的速度。对于数以百万计的客户机,即使是稀疏的流量也可能给您带来巨大的峰值,如果您读取数据包的速度不够快,您的输入队列将填满,您将开始丢弃数据包。Greg指向的C10K页面将为您提供这方面的策略。

我遇到了
不久前。好像梦想成真了。它们可以在单个节点上支持多达10万个并发客户端。将它们分布在10或20个节点上,您可以为数百万个节点提供服务。非常适合RESTful应用程序。可能需要更深入地查找任何共享命名空间。一个缺点是这是一个独立的服务器,作为web服务器的补充。这台服务器当然是开源的,所以任何费用都与硬件/ISP有关。

您考虑使用什么操作系统

如果使用Windows操作系统并使用比Vista更高版本的操作系统,那么在一台机器上进行数千次连接时就不会出现问题。我已经用一台低规格的WindowsServer2003机器运行了测试(这里:),很容易实现了70000多个活动TCP连接。在Vista上,影响可能连接数量的一些资源限制已被大大取消(请参见此处:),因此您可能可以通过一个小型计算机集群来实现您的目标。我不知道你需要在他们前面做什么来连接

Windows提供了一种称为I/O完成端口(请参阅:)的功能,它允许您使用很少的线程来服务数千个并发连接(我昨天运行了5000个连接的测试,其中一个连接到一个服务器的链接上有两个线程来处理I/O…)。因此,基本架构是非常可伸缩的

如果你想运行一些测试,那么我在我的博客上有一些免费的工具,可以让你使用数千个连接()和()和一些免费代码来启动一个简单的echo服务器()

从你的评论来看,你问题的第二部分比较棘手。如果客户端的IP地址不断变化,并且您和他们之间没有提供NAT来为您提供一致的IP地址,那么毫无疑问,他们的连接将被终止,需要重新建立。如果客户端在其IP地址更改时检测到此连接中断,则可以重新连接到服务器,如果无法,则我建议客户端需要每隔一段时间轮询服务器,以便检测到连接丢失并重新连接。服务器在这里无能为力,因为它无法预测新的IP地址,并且在尝试发送数据时会发现旧连接失败


记住,一旦你的系统达到这个水平,你的问题才刚刚开始

您不能使用UDP。如果客户端发送请求,而您没有立即回复,路由器将在30秒或更短的时间内忘记反向路由,因此您的服务器将永远无法回复客户端

TCP是唯一的选择,它也会让你头疼。大多数路由器会在几分钟后忘记路由和/或断开连接,因此您的客户机/服务器代码必须经常发送“保持有效”


我建议设置一个“嗅探器”,以了解电话公司如何通过他们的“推送”技术与您的智能手机保持联系。不管他们在做什么,都要模仿,因为那玩意儿很管用

正如Greg所提到的,您描述的问题是C10K(在您的案例中更确切地说是“C1M”) 我最近在linux上制作了一个简单的TCP echo服务器,通过使用队列,它可以很好地扩展会话数(不过测试的会话数最多为200.000)。在BSD上,您有类似的东西,称为kqueue。
如果你想的话,你可以去看看。希望这对你有帮助,祝你好运

到服务器的多个客户端连接不使用其他服务器端口。仍然会有技术上的限制,但不是端口的数量。使用唯一的4元组(server_ip,se)在服务器端识别连接