套接字连接可以多路复用吗?

Posted

技术标签:

【中文标题】套接字连接可以多路复用吗?【英文标题】:Can socket connections be multiplexed? 【发布时间】:2010-10-14 12:24:55 【问题描述】:

是否可以多路复用 sa ocket 连接?

我需要建立到 yahoo messenger 的多个连接,并且我正在寻找一种方法来有效地做到这一点,而不必为每个客户端连接打开一个套接字。

到目前为止,我必须为每个客户端使用一个套接字,但这并不能很好地扩展到超过 50,000 个连接。

哦,我的解决方案是针对电信公司的,所以我至少需要达到 250,000 到 500,000 个连接

我计划将多个 IP 地址绑定到单个 NIC,以克服每个 IP 地址的 65k 端口限制。

请我提供任何帮助,我能得到的见解。

**我在这个网站上的大多数其他问题都没有得到解答:) **

谢谢

【问题讨论】:

【参考方案1】:

这是一个关于在严重情况下扩展的有趣问题。

您实际上是在问,“我如何建立 N 个与 Internet 服务的连接,其中 N >= 250,000”。

有效且高效地做到这一点的唯一方法是集群。您不能在单个主机上执行此操作,因此您需要能够将您的客户端群分割和划分为多个不同的服务器,以便每个服务器只处理一个子集。

我们的想法是让单个服务器保持打开的连接尽可能少(均匀地分散连接),同时保持足够的连接以通过将服务器间通信保持在最低水平来使您托管的任何服务都可行。这意味着任何两个相关的连接(例如两个经常互相交谈的帐户)都必须位于同一主机上。

您将需要能够处理此问题的服务器和网络基础设施。您将需要一个 IP 地址子网,每台服务器都必须与 Internet 进行无状态通信(即,您的路由器不会进行任何 NAT 以便不必跟踪 250,000 多个连接)。

您必须与 AOL 交谈。如果不考虑切断您的连接,AOL 将无法处理这种级别的连接。这种规模的任何服务都必须与 AOL 协商,以便您和他们都能够处理连接。

您应该研究一些 i/o 多路复用技术。想到了 Kqueue 和 epoll。

为了编写这个大规模并发和电信级的解决方案,我建议研究 erlang。 Erlang 是为诸如此类的情况而设计的(多服务器、大规模多客户端、大规模多线程电信级软件)。它目前用于运行爱立信电话交换机。

【讨论】:

嗨 Jerub,我有一个简单的负载平衡算法,用于将来自前端服务器(托管数据库和 SMPP 内容)的传入负载分配到后端 IM-Gateway 盒。因此,我能够非常快速地有效地进行分区和横向扩展。我的主要问题是充分利用单个节点。 我不同意你的第二个说法。 IM 提供商(AOL、YAHOO)最终控制“帐户之间的聊天”,我的解决方案只是为用户提供访问其 IM 帐户的代理。我不允许帐户之间的通信只是因为它们都通过我的服务器进行代理。 Jerub,您能否详细说明关于网络基础设施的第三个建议,我在网络方面没有丰富的经验。谢谢 我不同意你对第 4 项的看法。Meebo 以非常大的规模成功地做到了这一点。而我的音量只是 IM 提供商处理的一个 dorp。我所有的用户都有合法的 IM 帐户,我只是方便的代理。如果他们都单独登录,则 IM 提供者无论如何都会有相同的负载。 Kqueue 和 epoll。我会查找的。但是,现在我正在远离 .net3.5 xxxxAsync。我正在尝试 Net.Sockets.Socket.Select()。它为我提供了非阻塞读取,并且非常快速和简单 - 无需处理混乱的 socketAsyncArgs。完成测试后我会发布一些结果。【参考方案2】:

虽然您可以在套接字上侦听多个传入的连接请求,但在建立连接时,它会将服务器上的唯一端口连接到客户端上的唯一端口。为了多路复用连接,您需要控制管道的两端并拥有一个协议,该协议允许您将上下文从一个虚拟连接切换到另一个虚拟连接,或者使用不关心客户端身份的无状态协议。在前一种情况下,您需要在应用程序层中实现它,以便您可以重用现有连接。在后一种情况下,您可以通过使用跟踪哪个服务器响应到哪个客户端的代理来获得。由于您要连接到 Yahoo Messenger,因此我认为您无法执行此操作,因为它需要经过身份验证的连接,并且假定每个连接对应一个用户。

【讨论】:

嗨,谢谢,我明白了。但我仍然坚持寻找一种可扩展的方式来完成这项工作。我想知道 meebo 的人是如何做到这一点的 :)【参考方案3】:

如果另一端支持这样的操作,您只能在一个套接字上多路复用多个连接。 换句话说,它是一个函数协议 - 套接字对它没有任何原生支持。

我怀疑 yahoo messenger 协议是否支持它。

另一种方法(单个 NIC 上的多个 IP)是设计自己的多路复用协议,并拥有从多路复用协议转换为雅虎协议的卫星服务器。

【讨论】:

嗨,Douglas,我不明白你的建议。我的目标是将我可以在单个服务器节点上处理的可能的客户端数量增加到最大,这样当我向外扩展时,我知道每个盒子已经达到了客户端的全部容量。卫星服务器如何通过 NIC 上的多个 IP 提供帮助?【参考方案4】:

我将介绍另一种您可以考虑的方法(取决于您的绝望程度)。

请注意,操作系统 TCP/IP 实现必须是通用的,但您只对非常具体的用例感兴趣。因此,在您的应用程序代码中实现 TCP/IP 的精简版本(它只处理您的用例,但做得很好)可能是有意义的。

例如,如果您使用的是 Linux,您可以将几个 IP 地址路由到一个 tun 接口,并让您的应用程序处理该 tun 接口的 IP 数据包。这样您就可以在您的应用程序中完全实现 TCP/IP(针对您的用例进行了优化),并避免任何操作系统对打开连接数的限制。

当然,自己做 TCP/IP 需要做很多工作,但这真的取决于你有多绝望——即你能负担得起多少硬件来解决这个问题。

【讨论】:

cmeerw,谢谢我考虑过使用 raw 选项,但要理解 YMSG 协议是在 TCP 之上实现的,所以我真的会按照你的建议做一个过度杀戮。我所做的是构建了一个非常轻量级的解析器,可以在 bytes[] 和 YPacket 结构之间进行转换。 但它仍然不能解决我的扩展问题,以满足该解决方案将处理的预期客户端连接数。 再次提醒,我的解决方案必须与 yahoo 和其他 IM 服务器通信,这些服务器都是基于 TCP 的,并且他们自己的 IM 客户端都使用标准的 tcp Scockets。 我能希望的最好的结果是创建一个超瘦客户端(我现在正在这样做),我可以在代码中运行多个实例而不会占用我所有的服务器资源,或者实例化多达可能在单个服务器节点上,然后最终不得不投入更多的硬件来解决问题。 可销售性问题不仅仅是获得足够的端口,我相信我可以使用多个 IP 地址和多个 NIC 来解决这个问题(在一定程度上......而且内存消耗......即使客户端是空闲,我无法断开它们以节省资源,因为重新连接太昂贵了。【参考方案5】:

500,000 个任意 yahoo messenger 连接 - 您的电信公司是否代表 Yahoo 执行此操作?似乎多年来已经存在的任何解决方案都应该在摩尔定律的帮助下具有可扩展性 - 据我所知,所有 IM 客户端在很长一段时间内都非常有效,并且没有迫切的需求增长我能想到。

为什么用硬件加传统解决方案来解决这个问题不是一个合理的问题?

【讨论】:

感谢您的回复。我正在为手机上没有数据/互联网访问权限的电信公司移动用户(我居住的第三世界的许多农村地区)建立一个雅虎 IM 代理。遗憾的是,摩尔定律并没有扩展一切……他们没有取消 TCP 中单个 IP 的 64k 端口限制:)

以上是关于套接字连接可以多路复用吗?的主要内容,如果未能解决你的问题,请参考以下文章

TCP的多路复用和分解

非阻塞套接字与IO多路复用

多路复用之selectepollpoll

非阻塞套接字与IO多路复用

IO多路复用

Linux select多路复用介绍(转)