我有一个基于微服务架构的多人游戏,我试图弄清楚如何水平扩展。它目前在Docker Swarm中进行了编排,但我正在考虑迁移到Kubernetes。
以下是有关游戏的详细信息:
目前,我有一个容器负责所有表。当玩家加入桌子时,他坐下来并建立一个Websocket连接,该连接被路由到该特定容器。所有桌子上的所有玩家都连接到同一容器。游戏逻辑和游戏事件可以轻松推送给所有客户端。
目前就是这样。 位于同一张桌子上的所有客户端都具有到同一容器的连接,因此轻松地来回推送动态游戏数据。
Client 1+
| Container A +Client 3
| +---------------+ |
+---> |---------------| <----+
|| Table 1 || |Client 4
Client 2+----> |---------------| <----+
|---------------|
|| Table 2 ||
|---------------|
|---------------|
|| Table 3 ||
+---------------+
| . |
| . |
| . |
+---------------+
但是,当您尝试通过仅增加容器数量来扩展规模时,您会遇到以下问题:坐在同一张桌子上的客户端已连接到不同的容器。这意味着必须在位于这些容器之间的数据库中更新每个游戏动作和所有共享的动态游戏数据。但是,这变得越来越难以编写和维护:
Container 1 Container 2
Client 1+ +-------------+ +-------------+ +Client 3
+----> |-------------| |-------------| <------+
|| Table 1 || || Table 1 ||
+----> |-------------| |-------------| <------+Client 4
Cleint 2+ |-------------| |-------------|
|| Table 2 || || Table 2 ||
+-------------+ +-------------+
| | | |
| | | |
| | | |
+----+--------+ +-----------+-+
| |
| |
| |
| +------------------------+ |
+> | Redis DB | <+
+------------------------+
与其以这种方式设计组件,不如以某种方式将必须坐在同一张桌子上的客户端路由到同一容器将更加简单。这是为了避免将每个播放器操作和每个公共表更新写入数据库。看起来像这样:
Game Service
+-----------------+
Client 1+ | | + Client 3
| | Container 1 | |
+------> +-----------+ <-------+
| |-----------| |
Client 2 +-----> || Table 1 || <-------+ Client 4
| |-----------| |
| |-----------| |
| || Table 2 || |
| |-----------| |
| +-----------+ |
| |
| Container 2 |
| +-----------+ |
| |-----------| |
| || Table 3 || |
| |-----------| |
| |-----------| |
| || Table 4 || |
| |-----------| |
| +-----------+ |
| |
+-----------------+
具有上述架构将大大降低应用程序的复杂性。问题是必须识别来自不同客户端的连接并将其路由到正确的容器。我还没有找到一种方法。是否可以使用什么工具路由到服务中的特定容器?
在我的方案中使用什么正确的方法? 另外,如果手动将请求路由到目标容器不是可行的选择,那么构造此服务的正确方法是什么?
答案 0 :(得分:1)
这可以通过Istio等第三方库的帮助来实现。
https://istio.io/docs/tasks/traffic-management/request-routing/
您将必须根据您的配置定义VirtualServices。对于您的游戏服务,您应该使用StatefulSet,这样您就可以确定将流量引至哪个服务。