0

我有一个应用程序服务器。在高层次上,这个应用程序服务器有用户。用户是一个或多个组的一部分,服务器可让所有用户了解他们的组和其他用户的状态。有三大功能:分配应用程序服务器

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

我试图修改此应用程序以允许它分布在多个服务器上,不一定都在同一个本地网络上。但是,我有一个要求,即不能破坏与旧客户的向后兼容性;本质上,分销对客户来说应该是透明的。

我有正在处理连接到服务器A一个用户的情况下使得需要被广播到服务器B一个用户的更新的最大问题。

推而广之,一个更大的问题是,当上服务器A用户需要服务器充当和服务器B用户他们之间的代理。

我最初的想法是尝试为每个用户分配一个首选的服务器,使用某种算法将需要与之通信的用户考虑在内。这可以减少可能需要与其他服务器上的用户通信的用户数量。

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

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

例如,如果我连接到服务器A,我需要连接到服务器B另一个用户的代理,我会问服务器A的代理连接到该用户。 服务器A将看到另一个用户连接到服务器B,因此它将与服务器B进行“中继”连接。此连接只会将我的请求转发给服务器B以及对我的回复。

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

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

+0

写入的服务器是什么O/S和语言? – 2011-04-12 09:02:15

+0

Windows和C++ – 2011-04-12 09:04:05

+0

这是一个非常复杂的话题。上次我在C++同步服务器上写这样的东西真的很难,并且受到非常讨厌的竞争条件的影响。我最近在Erlang写了一些非常相似的东西,它相对容易。 – 2011-04-12 09:07:53

回答

1

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

然后,每次用户连接到服务器时,服务器将TCP消息单播到所连接的所有服务器,并且所有服务器都保存用户列表和他们所在的服务器。

然后,如果您建议如果您从另一个服务器上的某个用户向另一个用户发送消息,则必须将该消息转发给其他服务器。服务器真的需要在同一个LAN上才能正常工作。

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

但是,维护用户列表和发送消息很容易出现竞争状况(例如,当用户将消息从一台服务器转发到另一台服务器时,用户就会退出)。

维护服务器代码是一场噩梦,这实际上并不是实现可伸缩服务器的最有效方式。但是,如果您必须使用旧版服务器代码库,那么您实际上没有太多选项。

如果您可以使用支持远程进程和Erlang等节点的语言进行研究。

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

+0

感谢您的建议。我没有提及服务器不在同一个局域网中,目前最大的瓶颈之一就是带宽。不,服务器有150,000多行C++,所以变化应该保持在最低限度。 – 2011-04-12 09:30:10

+0

如果我再次提起这个问题(我和你有类似的情况,追溯分布式独立服务器),我一定会查看消息队列路由(RabbitMQ)。通过这种方式,所有服务器都需要连接到消息队列并监视某些通道。然后他们使用消息队列回复。这对您的带宽问题没有帮助。但它会使消息传递更容易。 – 2011-04-12 18:05:54

+0

几年后,我重新编写了一个兼容的Erlang分布式服务器,原始服务器花费的时间只有一小部分时间,并且更简单,更简单。该代码也是代码行数的十分之一。我的竞赛条件少得多,而且发行版建在......只是说:) – 2011-04-12 18:11:42

相关问题