Apollo 技术文档Apollo 技术文档
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
  • MMORPG 架构 QA

Q108: 从 0 到 1 搭建一个 MMO 服务器,你的思路是什么?

问题分析

本题考察系统设计能力:

  • 需求分析
  • 架构设计
  • 技术选型
  • 实施路线

一、需求分析

1.1 核心需求

┌─────────────────────────────────────────────────────────────┐
│                    MMO 服务器需求                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  功能需求:                                                   │
│  ├── 玩家注册/登录                                           │
│  ├── 角色创建/管理                                           │
│  ├── 3D 场景移动                                             │
│  ├── 聊天系统                                                │
│  ├── 战斗系统                                                │
│  ├── 背包/物品                                               │
│  ├── 任务系统                                                │
│  └── 公会系统                                                │
│                                                             │
│  非功能需求:                                                 │
│  ├── 承载: 5000+ CCU                                        │
│  ├── 延迟: < 100ms (同区)                                   │
│  ├── 可用性: 99.9%                                          │
│  ├── 扩展性: 支持动态扩容                                     │
│  └── 安全性: 防外挂、防刷                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

二、技术选型

2.1 技术栈

层级技术选择理由
网络层TCP/KCP可靠传输
协议层Protobuf高效序列化
通信模型Actor分布式友好
脚本语言Python快速开发
数据库MySQL + Redis持久化 + 缓存
消息队列自建游戏专用

2.2 架构决策

# 技术选型分析

class ArchitectureDecision:
    """架构决策"""

    @staticmethod
    def choose_communication_model():
        """选择通信模型"""
        return {
            'model': 'Actor',
            'reasons': [
                '避免锁竞争',
                '天然分布式',
                '消息隔离',
                '易于扩展'
            ],
            'alternatives': {
                '线程模型': '锁竞争复杂',
                '协程模型': '阻塞风险',
                '进程模型': '通信成本高'
            }
        }

    @staticmethod
    def choose_serialization():
        """选择序列化方案"""
        return {
            'primary': 'Protobuf',
            'reasons': [
                '性能优异',
                '跨语言',
                '字段兼容',
                '体积小'
            ],
            'comparison': {
                'Protobuf': {'speed': 9, 'size': 8, 'readability': 5},
                'JSON': {'speed': 5, 'size': 4, 'readability': 10},
                'MsgPack': {'speed': 8, 'size': 9, 'readability': 4},
                'FlatBuffers': {'speed': 10, 'size': 9, 'readability': 3}
            }
        }

三、架构设计

3.1 系统架构

3.2 组件职责

# 组件定义

class ComponentArchitecture:
    """组件架构"""

    components = {
        'LoginApp': {
            '职责': ['玩家登录验证', '令牌发放', '负载均衡'],
            '技术': 'Python/Tornado',
            '端口': 8000,
            '实例数': 2
        },
        'Gateway': {
            '职责': ['连接管理', '消息转发', '流量控制'],
            '技术': 'C++/Epoll',
            '端口': 9000,
            '实例数': 4
        },
        'BaseApp': {
            '职责': ['玩家数据管理', '背包/任务', '跨服功能'],
            '技术': 'Python/Actor',
            '端口': 10000,
            '实例数': 4
        },
        'CellApp': {
            '职责': ['场景逻辑', '战斗系统', 'AOI 广播'],
            '技术': 'Python/Actor',
            '端口': 11000,
            '实例数': 8
        },
        'DBMgr': {
            '职责': ['数据库操作', '数据缓存', '异步保存'],
            '技术': 'Python/MySQL',
            '端口': 12000,
            '实例数': 1
        }
    }

四、实施路线

4.1 分阶段计划

4.2 详细计划

第一阶段:基础设施 (4 周)
├── Week 1-2: 网络框架
│   ├── TCP/KCP 通信
│   ├── Protobuf 协议
│   ├── 消息分发
│   └── 心跳机制
├── Week 3: Actor 模型
│   ├── 消息队列
│   ├── Actor 调度
│   ├── 邮箱机制
│   └── 远程调用
└── Week 4: 基础组件
    ├── 定时器
    ├── 日志系统
    ├── 配置管理
    └── 监控接口

第二阶段:核心功能 (6 周)
├── Week 5-6: 登录系统
│   ├── 账号验证
│   ├── 令牌机制
│   ├── 网关接入
│   └── 负载均衡
├── Week 7-8: 角色系统
│   ├── 角色创建
│   ├── 属性系统
│   ├── 数据持久化
│   └── 缓存管理
└── Week 9-10: 场景系统
    ├── 空间管理
    ├── 位置同步
    ├── AOI 实现
    └── 场景切换

第三阶段:游戏功能 (8 周)
├── Week 11-13: 战斗系统
│   ├── 技能系统
│   ├── 伤害计算
│   ├── 状态效果
│   └── AI 行为
├── Week 14-15: 物品系统
│   ├── 背包管理
│   ├── 物品使用
│   ├── 交易系统
│   └── 拍卖行
└── Week 16-18: 社交系统
    ├── 好友系统
    ├── 聊天系统
    ├── 公会系统
    └── 组队系统

第四阶段:优化测试 (5 周)
├── Week 19-20: 性能优化
│   ├── 内存优化
│   ├── 网络优化
│   ├── 数据库优化
│   └── 并发优化
└── Week 21-23: 测试发布
    ├── 单元测试
    ├── 集成测试
    ├── 压力测试
    └── 试运行

五、关键设计

5.1 消息协议

// 消息协议定义

// 基础消息
message BaseMessage {
    uint32 msg_id = 1;        // 消息 ID
    uint64 sequence = 2;      // 序列号
    uint64 timestamp = 3;     // 时间戳
    bytes body = 4;           // 消息体
}

// 登录请求
message LoginRequest {
    string account = 1;
    string password = 2;
    string client_version = 3;
}

// 登录响应
message LoginResponse {
    int32 code = 1;
    string message = 2;
    string token = 3;
    repeated string servers = 4;  // 可选服务器
}

// 位置同步
message PositionUpdate {
    uint64 entity_id = 1;
    float x = 2;
    float y = 3;
    float z = 4;
    float yaw = 5;
    uint32 timestamp = 6;
}

5.2 数据模型

# 数据模型设计

class PlayerSchema:
    """玩家数据模式"""

    # 数据库表结构
    TABLE_SQL = """
    CREATE TABLE players (
        id BIGINT PRIMARY KEY AUTO_INCREMENT,
        account_id BIGINT NOT NULL,
        name VARCHAR(32) NOT NULL UNIQUE,
        level INT DEFAULT 1,
        exp BIGINT DEFAULT 0,
        gold BIGINT DEFAULT 0,

        -- 位置
        space_id INT,
        position_x FLOAT,
        position_y FLOAT,
        position_z FLOAT,

        -- 时间戳
        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        last_login_at TIMESTAMP,

        -- 索引
        INDEX idx_account (account_id),
        INDEX idx_level (level),
        INDEX idx_space (space_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    """

    # Redis 缓存结构
    CACHE_KEY = "player:{player_id}"
    CACHE_FIELDS = [
        'id', 'account_id', 'name', 'level', 'exp', 'gold',
        'space_id', 'position_x', 'position_y', 'position_z'
    ]


class ItemSchema:
    """物品数据模式"""

    TABLE_SQL = """
    CREATE TABLE player_items (
        id BIGINT PRIMARY KEY AUTO_INCREMENT,
        player_id BIGINT NOT NULL,
        item_id INT NOT NULL,
        count INT DEFAULT 1,
        quality INT DEFAULT 1,

        -- 装备属性
        enchant_level INT DEFAULT 0,
        extra_data JSON,

        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
        updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

        INDEX idx_player (player_id),
        INDEX idx_item (item_id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    """

六、核心代码框架

6.1 Actor 实现

# Actor 框架

import queue
import threading

class Actor:
    """Actor 基类"""

    def __init__(self, actor_id):
        self.actor_id = actor_id
        self.mailbox = queue.Queue()
        self.running = False
        self.thread = None

    def start(self):
        """启动 Actor"""
        self.running = True
        self.thread = threading.Thread(target=self._loop, daemon=True)
        self.thread.start()

    def stop(self):
        """停止 Actor"""
        self.running = False
        if self.thread:
            self.thread.join()

    def _loop(self):
        """消息循环"""
        while self.running:
            try:
                message = self.mailbox.get(timeout=0.1)
                self.handle_message(message)
            except queue.Empty:
                continue
            except Exception as e:
                ERROR_MSG(f"Actor {self.actor_id} error: {e}")

    def send(self, message):
        """发送消息"""
        self.mailbox.put(message)

    def handle_message(self, message):
        """处理消息 (子类实现)"""
        raise NotImplementedError

    def ask(self, message, timeout=5):
        """请求-响应模式"""
        response_queue = queue.Queue()

        # 添加回调地址
        message.reply_to = response_queue

        self.send(message)

        try:
            return response_queue.get(timeout=timeout)
        except queue.Empty:
            raise TimeoutError("Actor response timeout")


# 远程 Actor
class RemoteActor:
    """远程 Actor 代理"""

    def __init__(self, actor_id, address, port):
        self.actor_id = actor_id
        self.address = address
        self.port = port
        self.transport = None

    def send(self, message):
        """发送远程消息"""
        # 通过网络发送
        self.transport.send(self.actor_id, message)

    def ask(self, message, timeout=5):
        """远程请求"""
        # 实现请求-响应
        pass

七、总结

从 0 到 1 核心要点

MMO 服务器搭建 = 需求分析 + 架构设计 + 分阶段实施
- 需求优先,避免过度设计
- 技术选型考虑团队和场景
- Actor 模型简化并发
- 分阶段迭代验证
- 性能和安全是持续工作

参考资料

  • MMO Server Architecture
  • Game Server Patterns
在 GitHub 上编辑此页
最后更新: 3/20/26, 6:06 AM
贡献者: cuihairu