跳到主要内容

moon介绍

moon 是一个轻量级在线游戏服务器框架,基于 Actor 模型构建,秉承 "Keep it simple, stupid" 设计原则。通过精简的核心代码实现了 Actor 调度系统和 Lua API 封装。

后续文章中用服务(Lua Service)来代表Actor

核心特性

框架优势

  • 核心代码精简,易于学习和掌握
  • 全平台支持(Windows、Linux、MacOS)
  • 完整的网络协议支持体系
    • TCP
    • UDP/KCP
    • WebSocket
    • HTTP
      • 基于 Lua 协程实现的全套异步功能:
      • 协程 Socket
      • 定时器系统
      • 服务间通信
        • 进程内通信
        • 集群间通信
      • 异步数据库驱动
        • Redis
        • MySQL
        • PostgreSQL
        • MongoDB
      • 性能优化组件
        • 高性能 JSON 处理
        • Protocol Buffers 支持
        • 文件系统操作
        • RecastNavigation 寻路
        • ZSet 排行榜

架构设计

系统架构图

moon设计时希望能充分利用多核的优势,采用了单进程多线程模式。为了简化设计,使用Asio库作为网络和线程通信的基础组件,Asio是一个成熟的跨平台异步IO库,使我们不必关心平台相关的细节,把复杂度限制在可控的范围内。moon采用了One Thread One IoContext的线程调度模型,Lua服务作为Actor的载体,每个线程可以有一个或者多个Lua Service,这样的好处是可以实现独占线程服务和共享线程服务:

  • 独占线程服务 可以表示运行期常驻的服务,如网关,DB Proxy等,这种服务很容易成为整个系统的的热点,希望它们能独占线程,提高响应能力,避免受到其它服务调度的影响

  • 共享线程服务 可以表示运行期间动态创建和销毁的服务,如一个玩家,一个组队副本场景等,这种服务功能上通常彼此之间是独立的,天然可拆分,可以多线程负载提高处理能力

moon提供的核心功能就是创建服务,并为它提供一个进程内不重复的ID, 服务间可以互相发送消息, 每个服务可以注册消息回调,来接收发送给它的消息, 每个服务都是被消息驱动的, 定时器也是一种消息。对于单个游戏服,推荐把业务逻辑尽量集中在同一个(节点)进程中, 按需求拆分不同的服务,这些服务协同工作构成单个游戏服务器节点进程,多个节点进程组成游戏服务器集群。服务间通信不必时刻关心对方是否还活着,通讯数据能否正确到达等问题。进程内的所有服务是同生共死的,对于游戏业务某个环节出了错都可能都是致命的,没必要把问题隐藏起来, 系统处于不完整状态可能会造成更大的损害。框架采用Lua编写逻辑代码C++编写少量核心库的开发方式,Lua作为脚本语言弥补了C++开发效率低,对于健壮性,采用Lua沙盒基本上能隔绝逻辑层的bug。

LuaAPI的封装参考了skynet, 所以和skynet有许多相似的地方, moonskynet最大区别是的调度方式,skynet使用了调度队列和服务消息队列实现了近似均衡的调度,同一个服务可能会切换不同的线程间调度(One queue, many processors)。

One queue, many processors

moon 每个线程都拥有自己的消息队列(Many processors, each with their own run queue),服务是固定在某个线程中的,这样就可以独占或共享线程,独占线程的服务可以有更高的响应能力,并且不受其他服务的影响。对于游戏业务,一般会出现难以拆分的热点服务, 如大地图战斗场景,这种服务的处理能力往往就是游戏服务器的上限,独占线程能最大程度发挥这种服务的性能。而服务切换不同线程调度,往往会降低响应能力,影响处理性能。

Many processors, each with their own run queue

核心概念

游戏服务器面临的主要问题包括进程间通信和逻辑模块之间的通信。在进程层面,需要处理与客户端、服务器集群、数据库和平台之间的远程过程调用。在逻辑层面,需要划分模块并确保它们之间的通信便利且高效,以利用多核CPU。moon通过抽象出三大基础设施来处理这些问题:

  1. 节点(Node)

    • 表示独立 Moon 进程
    • 通过 cluster.send/call 实现进程间服务通信
  2. 服务(Service)

    • Actor 的载体
    • 通过 moon.send/call 实现进程内服务间通信
  3. 模块(Module)

    • 服务内逻辑单元
    • 通常对应单个 Lua 文件

这三大设施也是灵活搭建不同类型游戏的基础。示例DEMO可以作为参考,你也可以基于它实现适合自己游戏类型的服务器。