Skip to main content

集群使用示例

tip

本篇文档不是必读内容,建议在时间充裕时阅读。

建议在游戏上线一段时间后来看,因为大部分游戏达不到需要集群的量。 同时,群集只是一种部署方式,后续将项目改成集群时,是不会对现有的代码(逻辑服)造成任何影响的。

所以,建议在游戏上线后且达到一定量时,再来了解集群相关内容也不迟。

介绍

i

从架构简图中可以看到,游戏网关是支持集群部署的,集群基于 Gossip 数据传播协议来完成。 在 ioGame 中实现集群是简单的、灵活的,且不会对现有的代码造成任何影响。


Gossip

Gossip 可以很方便地实现弹性集群,允许节点随时上下线,提供快捷的失败检测和动态负载均衡等。 此外,Gossip 协议最大的好处是,即使集群节点的数量增加,每个节点的负载也不会增加很多,几乎是恒定的。

集群没有中心节点,各个节点的地位完全相同,它们通过一种叫做 Gossip 的协议维护集群的状态。 通过 Gossip,每个节点都能知道集群中包含哪些节点,以及这些节点的状态。 这使得集群中的任何一个节点都可以完成任意 action 的路由,任意一个节点不可用都不会造成灾难性的后果。

Example Source Code

see https://github.com/iohao/ioGameExamples

path : SimpleExample/example/example-cluster-run-one

下面,我们将介绍单进程启动集群和多进程启动集群。

单进程启动集群

在 DemoClusterApplication 中,我们在一个进程中启动了对外服、游戏网关(3个集群节点)、游戏逻辑服。 NettyClusterSimpleHelper 是一个快速体验集群工具类,正式环境推荐一台机器部署一个游戏网关。

public class DemoClusterApplication {
public static void main(String[] args) {
var demoLogicServer = new DemoClusterLogicServer();
NettyClusterSimpleHelper.run(ExternalGlobalConfig.externalPort, List.of(demoLogicServer));
}
}

启动后的控制台信息

这里给出部分日志,可以看到,我们的游戏网关集群数量是 3,端口分别是 10200、10201、10202。

40:41.384  INFO xxx.java:184 : broker(游戏网关): [10200] --  集群数量[3] - 详细:[BrokerClusterMessage(brokerMessageList=[BrokerMessage(id=8da077f3-aa29-4315-86ea-a07eaa14d5ad, address=192.168.1.91:10201), BrokerMessage(id=ab0868f9-b79c-48a2-87a7-dec9ac417502, address=192.168.1.91:10200), BrokerMessage(id=ce231c96-fcc1-4a4f-be6f-7951591e4c2f, address=192.168.1.91:10202)])]
40:41.384 INFO xxx.java:184 : broker(游戏网关): [10202] -- 集群数量[3] - 详细:[BrokerClusterMessage(brokerMessageList=[BrokerMessage(id=8da077f3-aa29-4315-86ea-a07eaa14d5ad, address=192.168.1.91:10201), BrokerMessage(id=ab0868f9-b79c-48a2-87a7-dec9ac417502, address=192.168.1.91:10200), BrokerMessage(id=ce231c96-fcc1-4a4f-be6f-7951591e4c2f, address=192.168.1.91:10202)])]
40:41.384 INFO xxx.java:184 : broker(游戏网关): [10201] -- 集群数量[3] - 详细:[BrokerClusterMessage(brokerMessageList=[BrokerMessage(id=8da077f3-aa29-4315-86ea-a07eaa14d5ad, address=192.168.1.91:10201), BrokerMessage(id=ab0868f9-b79c-48a2-87a7-dec9ac417502, address=192.168.1.91:10200), BrokerMessage(id=ce231c96-fcc1-4a4f-be6f-7951591e4c2f, address=192.168.1.91:10202)])]

模拟客户端的请求

启动 DemoClusterClient 后,客户端的控制台信息

AcceptMessage ExternalMessage ==========
ExternalMessage(cmdCode=1, protocolSwitch=0, cmdMerge=65536, responseStatus=0, validMsg=null, dataContent=[10, 17, -27, -95, -108, -27, -89, -122, 44, 32, 73, 39, 109, 32, 104, 101, 114, 101, 32])

helloMessage ==========
HelloMessage(name=Michael Jackson, I'm cluster here )

多进程启动集群

多进程方式的具体代码就不贴在这里了,为了不与上同义反复,只贴出相关的类名,每个类都可以单独的启动。

path : example/example-cluster-run-one/src/test

  • DemoClusterGate10200 Broker1
  • DemoClusterGate10201 Broker2
  • DemoClusterGate10202 Broker3
  • DemoClusterLogic 游戏逻辑服
  • DemoClusterExternalTest 游戏对外服
  • DemoClusterWebsocketClient 模拟游戏客户端

简单、便捷、灵活

逻辑服不需要配置连接到集群端口,只需要配置连接到游戏网关的端口就可以了。 看了一些其他开源项目的集群方案,基本都是需要在客户端配置至少两个种子节点, 这样会增加一些使用难度,就是与集群相关的各种配置。

为了让大家在集群上使用简单,也可以理解为 ioGame 有意的为开发者屏蔽这一块相关的,即使屏蔽了也能享受集群。 屏蔽后就意味着开发者不需要关心集群,只需按常规的开发。

因为集群是无中心节点的,当逻辑服连接上任意一个游戏网关时,其他游戏网关能感知到,并与该逻辑服建立连接。 有多少个游戏网关节点,逻辑服就会与这些节点建立或减少连接。

从这里可以看出,ioGame 的架构是非常灵活的。 如果游戏网关是集群启动的,我们的架构就是集群的,反之亦然。 这个过程中,我们的逻辑服不需要改动任何代码。

生产环境的建议

在生产上建议一台物理机配置一个 Broker(游戏网关),一个 Broker 就是一个节点。 比如配置三台机器,那么可以使用同样的端口,假设三台机器的 ip 分别是

  • 192.168.1.10:30056
  • 192.168.1.11:30056
  • 192.168.1.12:30056