【问题标题】:Scaling WebSockets on Google Compute Engine在 Google Compute Engine 上扩展 WebSocket
【发布时间】:2013-08-26 19:59:38
【问题描述】:
我想将聊天系统作为我在 App Engine 上开发的游戏的一部分。为了实现这一点,我想使用 WebSockets,并让客户端通过集线器相互连接,在本例中是 GCE 的实例。假设这个游戏需要在 GCE 上扩展到多个实例,这将如何工作?如果我有一个客户端 1,并且负载均衡器将客户端 1 的请求定向到实例 A,另一个客户端 (2) 进来并被定向到实例 B,但是这些客户端想要互相聊天,他们每个人都会连接到不同的集线器,并且将无法相互连接。这将如何设置以适应规模?我是否会使用队列来实现它,每个实例都在该队列上进行侦听,如果是,我将如何做到这一点?
【问题讨论】:
标签:
google-app-engine
websocket
google-compute-engine
【解决方案1】:
Google Play Game Services 提供您想要的功能,但与 Android 和 ios 客户端相关。因此,此选项可能与您的游戏技术设计不兼容。
总的来说,您的推理是正确的。来自想要相互交谈的客户端的消息大部分时间会到达不同的服务器实例。您要做的是让实例处理用户之间的通信。 Pub/sub (publish-subscribe pattern) 在这种情况下是非常合适的模式。大致:
- 只要有消息指向客户端 X,就会在通道 X 上发布消息,
- 每当客户端 X 创建会话时,处理它的实例都会订阅通道 X。
对于初学者,您可以使用许多现有解决方案中的一种。使用redis 很容易设置它。如果您需要更底层和更灵活的东西,请查看zeromq。
您可以期望任一解决方案的单个实例能够处理数千个 QPS。
很遗憾,我没有任何扩展这两种解决方案的经验,因此无法就它们的可扩展性限制向您提供任何实用建议。
PS。您可能还想探索其他主题,例如:消息持久性和故障恢复我根本没有在这里讨论。
【解决方案2】:
我还没有尝试实现它,但我可能很快就会实现,我认为自己处理它应该相当简单。
您有:带有客户端列表的服务器 1,您有带有另一个客户端列表的服务器 2,
因此,如果客户端想要将数据发送到可能在服务器 2 上的另一个客户端,您必须:
- 查找接收方是否在当前服务器上 - 如果是,您只需发送它(标准)
- 否则,您将相同的数据发送到您拥有的所有其他服务器,因此他们会检查特定客户端(或多个客户端)的列表并将数据发送给他们。