0

我有一个应用程序服务器。在较高级别上,此应用程序服务器具有用户。用户是一个或多个组的一部分,服务器使所有用户都知道他们的组和他们组中的其他用户的状态。主要有以下三个功能:

  • 更新和广播与用户及其群组相关的元数据;例如,用户登录,服务器会更新该用户的状态并将其广播给该用户组中的所有在线用户。
  • 充当两个或多个用户之间的代理;客户端利用点对点传输,但在两个用户无法直接相互连接的情况下,服务器将充当他们之间的代理。
  • 为离线用户存储数据;如果客户端需要向不在线的用户发送一些数据,服务器会将该数据存储一段时间,然后在用户下次上线时发送。

我正在尝试修改这个应用程序以允许它分布在多个服务器上,不一定都在同一个本地网络上。但是,我要求不能破坏与旧客户端的向后兼容性;本质上,分发需要对客户端透明。

我遇到的最大问题是处理连接到服务器 A的用户进行更新的情况,该更新需要广播给服务器 B上的用户。

通过扩展,更大的问题是当服务器 A上的用户需要服务器充当他们和服务器 B上的用户之间的代理时。

我最初的想法是尝试为每个用户分配一个首选服务器,使用一些算法来考虑他们需要与哪些用户进行通信。这可以减少可能需要与其他服务器上的用户通信的用户数量。

但是,这只会最大限度地减少不同服务器上的用户需要通信的频率。我仍然有实现不同服务器上用户之间通信的问题。

我能想到的唯一解决方案是让服务器相互连接,当他们需要处理连接到不同服务器的用户时。

例如,如果我连接到服务器 A并且我需要一个代理与另一个连接到服务器 B的用户,我会要求服务器 A与该用户建立代理连接。服务器 A会看到另一个用户已连接到服务器 B,因此它将与服务器 B 建立“中继”连接。此连接只会将我的请求转发到服务器 B并将响应转发给我。

这样做的问题是它会增加带宽使用,这已经非常高了。不幸的是,我没有看到任何其他解决方案。

是否有任何众所周知或更好的解决方案来解决这个问题?分布式系统要求不同服务器上的用户之间进行通信似乎并不常见。

4

1 回答 1

1

我不知道您在修改现有服务器方面有多大的灵活性。我很久以前这样做的方法是让所有服务器保持 TCP 连接彼此开放。我使用了一个 UDP 广播,它告诉其他服务器彼此有关,并允许它们连接到新服务器并删除停止发送广播的服务器。

然后每次用户连接到服务器时,服务器都会向它连接的所有服务器单播一条 TCP 消息,并且所有服务器都会保留用户列表以及他们所在的服务器。

然后,正如您所建议的,如果您从一个用户收到消息到另一台服务器上的另一位用户,则必须将其中继到另一台服务器。服务器确实需要在同一个 LAN 上才能正常工作。

您可以在线程中运行服务器到服务器的通信,并实际模拟用户在同一台​​服务器上。

但是,维护用户列表和发送消息很容易出现竞争条件(例如,当您将消息从一台服务器中继到另一台服务器时用户掉线等)。

维护服务器代码是一场噩梦,这确实不是实现可扩展服务器的最有效方式。但是,如果您必须使用遗留服务器代码库,那么您真的没有太多选择。

如果您可以考虑使用支持远程进程和节点的语言,例如 Erlang。

另一种方法可能是使用消息队列系统,如 RabbitMQ 或 ActiveMQ,并让服务器通过它相互通信。这些系统被设计为可扩展的,并且通常使用发布/订阅机制。

于 2011-04-12T09:17:41.313 回答