如何保留100万个同步TCP连接?

时间:2010-05-14 02:06:31

标签: tcp

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

服务器和客户端之间的数据流量很少,因此可以忽略带宽问题。

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

有人知道如何做到这一点,以及需要什么硬件/软件(以最低成本)?

6 个答案:

答案 0 :(得分:20)

您正在考虑使用哪种操作系统?

如果使用Windows操作系统并使用Vista之后的某些内容,则单个计算机上的数千个连接不会出现问题。我使用低规格的Windows Server 2003计算机运行测试(此处:http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html),并轻松实现了超过70,000个活动TCP连接。影响连接数量的一些资源限制在Vista上已大大提升(参见此处:http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html),因此您可以通过一小组计算机实现目标。我不知道在那些路由连接之前你需要什么。

Windows提供了一个称为I / O完成端口的工具(请参阅:http://msdn.microsoft.com/en-us/magazine/cc302334.aspx),它允许您使用极少数线程为数千个并发连接提供服务(我昨天运行了测试,其中5000个连接使链接饱和到服务器有2个线程来处理I / O ...)。因此,基本架构具有很高的可扩展性。

如果你想运行一些测试,那么我的博客上有一些免费提供的工具,允许你使用成千上万的连接(1)和(2)来捣乱一个简单的echo服务器。一些免费代码,您可以使用它们来帮助您入门(3

根据您的意见,问题的第二部分更棘手。如果客户端的IP地址不断变化,并且您和他们之间没有任何东西可以提供NAT来为您提供一致的IP地址,那么毫无疑问,他们的连接将被终止并需要重新建立。如果客户端在IP地址发生变化时检测到此连接断开,那么他们可以重新连接到服务器,如果他们不能,那么我会建议客户端需要经常轮询服务器,以便他们可以检测到连接丢失和重新连接。服务器无法在此处执行任何操作,因为它无法预测新的IP地址,并且在尝试发送数据时会发现旧连接已失败。

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

答案 1 :(得分:11)

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

答案 2 :(得分:4)

我遇到了APE Project 一会儿回来。这似乎是梦想成真。它们可以在单个节点上支持多达10万个并发客户端。将它们分布在10或20个节点上,您可以服务数百万。适用于RESTful应用程序。可能希望更深入地了解任何共享命名空间。一个缺点是这是一个独立的服务器,如对Web服务器的补充。该服务器当然是开源的,因此任何成本都与硬件/ ISP相关。

答案 3 :(得分:1)

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

TCP是唯一的选择,它也会给你带来麻烦。大多数路由器将在几分钟后忘记路由和/或断开连接,因此您的客户端/服务器代码将不得不经常发送“保持活动”。

我建议设置一个“嗅探器”,以了解电话公司如何与智能手机保持联系以实现“推送”技术。复制他们正在做的事情,因为那些东西有效

答案 4 :(得分:0)

正如格雷格所说,你所描述的问题是C10K(或者更确切地说是“C1M”) 我最近在linux上创建了一个简单的TCP echo服务器,通过使用epoll队列,可以很好地扩展会话数(仅测试高达200.000)。在BSD上,你有类似的叫做kqueue的东西。 如果您愿意,可以查看code。希望这有帮助,祝你好运!

答案 5 :(得分:-4)

编辑:如下面的评论中所述,我原来断言根据端口数量存在64K限制是不正确的,但 的数量限制为32K套接字句柄,所以我建议的设计是有效的。

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

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

使用这种方法,您唯一的限制是您可以多快地处理和响应UDP消息。有数百万个客户端,即使是稀疏的流量也可能会给你带来大量的峰值,如果你没有足够快地读取数据包,你的输入队列就会填满,你就会开始丢弃数据包。 Greg指出的C10K页面将为您提供策略。