精华 [经典问题]请教集群,后端同一业务用多机负载的方式,同一Room的客户端要路由到同一Backend, topic应该怎么写?
发布于 1 年前 作者 liangdas 710 次浏览 来自 问答

E926E5809D0C57D67F2717F5A3A523C4.png 就像这图,192.168.1.101与192.168.1.102其实是同一程序相同的业务,用来负载载不同的Room

9 回复

如果一个模块分布有一个进程里面的话,目前mqant的topic可以有两种分发规则

  1. 默认的分发规则 moduleType/handler/msg_id 也就是 Chat/HD_login/1 这种模式下如果Chat模块存在多个,系统内部会用调用方的ServerId来取模选择 你也可以通过app.Route(“Chat”,ChatRoute)指定一个自定义函数来自定义选取规则
  2. 明确指明mouduleid ,即 moduleType@moduleID/handler/msg_id Chat@Module001/HD_login/1

其实在一个模块里面调用另外一个模块的时候也有这几种选择方式

例如: r, e := m.RpcInvoke(“Login”, “getRand”, []byte(“hello”),msg,10.01,1,true) 这样写就会通过app.Route() 选

r, e := m.RpcInvoke(“Login@Login001”, “getRand”, []byte(“hello”),msg,10.01,1,true) 这样写就唯一指定了

如果这两种方式还不满足可以直接 m.App.GetServersByType(“Login”) 获取这个模块的所有进程列表 然后按自己的方式去选择一个调用,或者都调用

gate里面也是基于这个来实现的,所有如果你想在gate里面实现基于userid的方式取模的话可以考虑去改gate的代码

一般棋牌游戏里面的room基本都是定好的,一台服务器就指定这些roomid

最后贴上mqant rpc路由规则的文档 mqant RPC路由规则

大体上明白了,像现在这种选择Room的情况,创建成功后要告诉客户端是在哪个ModuleID下,然后客户端发消息时toptic就前面带上刚才返回的ModuleID就可以路由到指定的服务器了。

选择room之后的处理,是开启一个协程单独为这个room中的游戏做处理么? 我一直以为这个框架是,把room中的处理做成一个module,选择进入room之后,运行这个module做相应处理。 现在看来,同一个module在一个进程只能有一个实例,那么对于进入room之后的操作相对于只是这个module提供的一部分功能了?

@hellolw 是的,一个module里面可以有多高room,module统一接收各个room的消息,然后发送到他们对于的队列里面去处理,这是我目前的做法

@hellolw 你想的这种应该跟erlang挺像的,虚拟机里面可以创建很多进程,关键是erlang的进程间通信太好用了,目前golang还没有这么好用的库,我也挺喜欢erlang的模式

@liangdas 可不可以考虑对每个room起一个goroutines单独处理,每个goroutines和module主线程之间通过chan通信? 新版本的hitball游戏已经实现了一个你提到的这种模式,module的主goroutines收到消息以后通过一个queue传递给room,room里面每帧会处理queue的请求,做出反馈

https://github.com/liangdas/mqantserver/tree/master/src/server/hitball

回到顶部