服务器引擎是什么意思?
可以简单理解为一组方法集合。服务是分布式游戏服务端中的最小实体,一个服务提供了一组确定的、可供调用的方法。skynet中,一个skynet_context唯一对应一个服务,而一个skynet节点对应一组服务;传统MMO中,一个进程对应一组服务,但是很难在其中找到“一个”服务的划分界限。
服务的概念就是为了提出一种与物理容器无关的抽象。服务可以以某个进程为容器,也可以以某个线程为容器。可以像skynet一样以一个luaState为容器,也可以像Erlang游戏服务端那样以一个actor为容器。而一个容器也可以提供多种服务。
服务中的数据定位
游戏世界的状态可以简单分为两个部分,一部分是需要存档的,比如玩家数据;一部分是不需要存档的,比如场景状态。
对于访问较频繁的部分,比如场景状态,会维护成纯内存数据;对于访问较不频繁的部分,比如玩家存档,就可以考虑维护在第三方。这个第三方,就是数据服务。
数据服务与之前所提到的场景服务、IM服务等都属于应用层的概念。数据服务通常也会依赖于一种基础设施抽象,那就是缓存。
我们可以将服务状态存放在外部设施中,比如数据服务。
无状态服务
将状态存放在外部设施的服务就是无状态服务。而与之对应的,场景服务这种状态需要在进程内维护的就是有状态服务。无状态游戏客户端意味着网络通信的成本跟内存数据访问的成本一样低——这当然是不可能实现的。游戏中可以拆分为无状态服务的业务需求其实有很多,基本上所有服务间交互需求都可以实现为无状态服务。比如切场景服务,因为切场景的请求是有限的,对时延的要求也不会特别高,同理的还有分配房间服务;或者是面向客户端的IM服务、拍卖行服务等等。
游戏服务端中的Message Queue
面对这种需求,我们需要一种消息队列中间件。
生产者消费者一直都是一种比较经典的解耦模型,而消息队列就是基于这种模型构建的。每个skynet节点本质上就是一个高度精简的消息队列,为寄宿的每个服务维护一个私有队列,对全局队列中的消息dispatch,驱动寄宿服务。