我有一个基于微服务架构的多人游戏,我试图弄清楚如何水平扩展。它目前在Docker Swarm中进行了编排,但我正在考虑迁移到Kubernetes。

以下是有关游戏的详细信息:

  • 这是带有纸牌的桌面游戏
  • 多个玩家坐在同一张桌子上,彼此玩耍

  • 现在开始工作,我有一个负责所有表的容器。当玩家加入桌子时,他坐下并建立一个Websocket连接,该连接被路由到该特定容器。所有桌子上的所有玩家都连接到同一容器。游戏逻辑和游戏事件可以轻松推送给所有客户端。

    目前就是这样。 位于同一表上的所有客户端都具有到同一容器的连接,因此可以轻松地来回推送动态游戏数据。
    Client 1+
            |         Container A         +Client 3
            |      +---------------+      |
            +--->  |---------------| <----+
                   ||   Table 1   ||      |Client 4
    Client 2+----> |---------------| <----+
                   |---------------|
                   ||   Table 2   ||
                   |---------------|
                   |---------------|
                   ||   Table 3   ||
                   +---------------+
                   |      .        |
                   |      .        |
                   |      .        |
                   +---------------+
    

    但是,当您尝试通过仅增加容器数量来扩展规模时,您会遇到以下问题:坐在同一张桌子上的客户端将连接到不同的容器。这意味着必须在位于这些容器之间的数据库中更新每个游戏 Action 和所有共享的动态游戏数据。但是,这变得越来越难以编写和维护:
                       Container 1             Container 2
      Client 1+      +-------------+         +-------------+        +Client 3
              +----> |-------------|         |-------------| <------+
                     ||  Table 1  ||         ||  Table 1  ||
              +----> |-------------|         |-------------| <------+Client 4
      Cleint 2+      |-------------|         |-------------|
                     ||  Table 2  ||         ||  Table 2  ||
                     +-------------+         +-------------+
                     |             |         |             |
                     |             |         |             |
                     |             |         |             |
                     +----+--------+         +-----------+-+
                          |                              |
                          |                              |
                          |                              |
                          |  +------------------------+  |
                          +> |       Redis DB         | <+
                             +------------------------+
    

    与其设计这样的组件,不如以某种方式将必须坐在同一张桌子上的客户端路由到同一容器要简单得多。这是为了避免将每个播放器操作和每个公共(public)表更新写入数据库。它看起来像这样:
                     Game Service
                  +-----------------+
    Client 1+     |                 |      + Client 3
            |     |   Container 1   |      |
            +------> +-----------+ <-------+
                  |  |-----------|  |
    Client 2 +-----> || Table 1 || <-------+ Client 4
                  |  |-----------|  |
                  |  |-----------|  |
                  |  || Table 2 ||  |
                  |  |-----------|  |
                  |  +-----------+  |
                  |                 |
                  |   Container 2   |
                  |  +-----------+  |
                  |  |-----------|  |
                  |  || Table 3 ||  |
                  |  |-----------|  |
                  |  |-----------|  |
                  |  || Table 4 ||  |
                  |  |-----------|  |
                  |  +-----------+  |
                  |                 |
                  +-----------------+
    

    具有上述架构将大大降低应用程序的复杂性。问题是必须标识来自不同客户端的连接,并将其路由到正确的容器。我还没有找到一种方法。是否可以使用什么工具路由到服务中的特定容器?

    在我的方案中使用什么正确的方法?
    另外,如果手动将请求路由到目标容器不是可行的选择,那么构造此服务的正确方法是什么?

    最佳答案

    这可以通过Istio等第三方库的帮助来实现。

    https://istio.io/docs/tasks/traffic-management/request-routing/

    您将必须根据您的配置定义VirtualServices。对于您的游戏服务,您应该使用StatefulSet,这样您就可以确定将流量路由至哪个服务。

    关于docker - 如何路由到服务中的特定容器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53683081/

    10-12 14:23
    查看更多