lotou是一个基于golang的支持分布式的轻量级游戏服务器框架,主要提供游戏服务器集群的消息转发代码仓库
lotou提供了三种不同的消息发送方式:
1.Send 用于普通的消息推送,不需要返回,发送之后就不再关注
2.Request 异步非阻塞请求响应模式,request接收一个回调函数和一个超时时间,当远程服务通过respond响应或者远程服务响应超时的时候,回调函数会被唤醒。
3.Call 同步阻塞请求响应模式,call阻塞当前goroutinue,知道请求超时或者远程服务响应才返回,返回值为远程服务响应函数的返回值和一个error。
Service
service指游戏中的一个服务或者是一个模块,lotou消息转发的基本单位为服务,所有消息都是在服务之间进行转发。
发送到服务的消息被push到service的msgChan里面,service在启动的时候开启一个goroutinue来分发msgChan接收到的消息,并根据需要启动一个timer来执行mainloop。
非特殊情况,不要在service的主goroutinue里面调用阻塞式的消息发送模式(Call),因为一旦主goroutinue被阻塞,service将无法继续分发接收到的msg。
Message
lotou中消息的载体最终是一个Message的结构体,Message包含如下几个成员
- Src message sender
- Dst message receiver
- Type message type (normal、request、respond、call、ret…)
- EncType 目前支持不编码和gob,其中gob是lotou中实现的一种编码方式,不是golang自带的gob package。
- Cmd 消息的名字或者是命令,lotou的用户可以通过registerHandlerFunc来注册cmd处理函数,当service接收到对应的消息的时候,会进行正确的消息分发
- Id 如果message是一个request、call或者是respond、ret的时候,该Id代表请求或者call的ID,或者是respond ret响应的是哪一个id的请求或者call。
- Data具体发送的数据,是一个interface{}的slice,对于gob编码方式,data的第一个元素就是编码之后的[]byte。
Node(节点)
lotou支持分布式编程,可以将service分布在多台电脑上得多个应用中,这里lotou每一个进程就是lotou中的一个节点。
在所有节点中,会有一个master节点和多个slave节点,所有的slave节点都会和master节点建立连接,并向master发起注册,master会为每一个slave节点分配一个nodeId。
当lotou处于多节点模式下的时候,message会根据Dst是本地节点还是远程节点,进行适当的消息转发。
Master
对于一个多节点lotou网络,只能存在一个唯一的master 节点,该节点负责为每一个slave节点分配一个唯一的nodeid,并且对不同的节点的消息进行转发
Slave
对于一个多节点lotou网络,有N个slave节点,slave节点启动的时候会先向master节点申请nodeid。
serviceId
lotou为系统中每一个service分配一个唯一的serviceid。为了保证serviceid的唯一性,serviceid由两部分组成:
nodeid << (64 - 16) | id
其中nodeid占16为,id占48位
nodeid是上面提到的由master分配的节点Id
id是每一个节点为service分配的id,其中节点中保证不同的service不会有相同的id
agent服务
lotou中将tcp服务器中的客户端连接称为agent,每一个tcp连接都对应一个agent,agent服务会把从tcp上接收到的数据发送给其绑定的hostService,同时hostService也可以通过agent向tcp客户端发送数据
client服务
lotou中将tcp客户端称为client,client把从tcp上收到的数据发送给其绑定的hostService,同时hostService通过client向tcp服务器发送数据
timer
lotou内部实现一个定时器调度逻辑,定时器只针对具有主循环的service,如果一个service没有主循环(即启动的时候没有设置loopDuration),则无法注册timer,timer的最小调度周期即为一个loopDuration,单位为毫秒。
如果loopDuration为100,timer的间隔为10,则每一次主循环将会调用timer的回调10次,不建议使用比loopDuration小的timer间隔,如果需要更精确的timer,请提高mainLoop的精度。
Module
Module是lotou中service对外的接口,用户通过实现一个Module的接口,然后通过func StartService(name string,m Module) ServiceID 可以启动一个service。
Skeleton
skeleton是lotou中对Module的一个默认实现,对lotou的功能进行了一定程度的封装。
总结
本章主要讲解了lotou中使用到的基本概念,下一章将会继续对lotou消息分发的讲解。