Center 节点说明
节点定位
- 提供跨游戏服的中心数据与控制平面
- 统一账号绑定(UID ↔ 第三方平台 OpenID)、开发者账号注册与认证
- 聚合并缓存玩家“最后登录记录”,兼顾 Redis 热数据与 MongoDB 持久化
- 运维控制接口:存活探测、优雅关停、DB 队列监控
启动流程
- 入口:center.go
- 基于 Cherry 框架配置并启动节点,注册组件与 Actor:
- 组件:GOPS、配置加载(SDK/RateLimiter/Lua)、Redis 客户端(GUID/Center)、数据库组件
- Actor:Player、Ops、Dev
- 关键步骤顺序:ConfigureNode → Register(组件) → AddActors → Startup
主要 Actor 与远程接口
- Ops 运维
- 文件:actor.go
- 接口:Ping(健康探测)、Shutdown(优雅关停)、DbReport(DB 队列状态)
- Dev 开发者账号
- 文件:actor.go
- 接口:Register(注册开发者账号)、Auth(账号认证)
- Player 玩家服务
- 文件:actor.go、actor_uid.go
- 设计:父 Actor 按 workerSize 分片,将消息转发到子 ActorUID
- 接口:BindUID(UID 绑定第三方平台)、UpdateLastPlayer(更新最后登录记录)
数据模型与持久化
- 数据库组件
- 文件:db.go
- 表:DevAccountTable、UserBindTable、LastPlayerTable
- 写入:统一通过 DBQueue 异步入队(save2Queue),提升写入峰值承载与可靠性
- 脚本:版本迁移脚本 ver_00001.go
- 玩家最后登录记录
- 账号绑定
- 开发者账号
缓存与预加载
- 开发者账号缓存
- 文件:cache.go
- 实现:goburrow/cache,按访问后过期(48h),减少数据库查询压力
- 预加载
运维与监控
- Ping:检查 Center 节点存活与响应
- Shutdown:协调应用优雅关闭
- DbReport:查询数据库队列堆积与处理状态,辅助容量评估与告警
- 入口参考:ops/actor.go
目录结构概览
- dev:开发者账号相关 Actor 与逻辑
- internal/db:数据库组件、表定义、数据结构、缓存与迁移脚本
- ops:运维 Actor 与远程接口
- player:玩家 Actor 分片与 UID 接口、最后登录数据更新
设计目标
- 高可用:通过分片 Actor 与异步队列提升吞吐与隔离故障
- 一致性:Redis 作为热数据缓存,DBQueue 保障最终一致性
- 易扩展:Actor 体系可按业务维度扩展,DB 脚本支持增量迁移
- 可观测:内置运维接口与队列报告,便于监控与告警集成
远程接口列表
- Ops
- Dev
- Dev_Register(pb.DevRegister) → 返回 code,注册开发者账号(dev/actor.go)
- Dev_Auth(pb.DevRegister) → 返回 pb.I64(accountID), code,账号认证(dev/actor.go)
- Player
典型调用流程
- 开发者账号注册与认证
- 客户端 → Dev_Register(accountName, password) → 返回 OK/错误码
- 客户端 → Dev_Auth(accountName, password) → 返回 accountID(pb.I64)
- 玩家 UID 绑定
- 游戏服 → Player_BindUID(pb.User: Uid, SdkID, PID, OpenID)
- Center 入队 UserBindTable → DBQueue 异步写入 MongoDB
- 最后登录记录更新
- 游戏服 → Player_UpdateLastPlayer(pb.UpdateLastPlayer)
- Center 从 Redis 读取列表 → 覆盖/裁剪至上限 → 回写 Redis
- 同步构造 LastPlayerTable → 入队 DBQueue → MongoDB 持久化
代码逻辑详解
- 入口初始化(center.go)
- ConfigureNode 以 Cluster 模式启动,注册 GOPS、配置加载(SDK/RateLimiter/Lua)、Redis(GUID/Center)、数据库组件。
- 数据库组件 NewCenter:注册 DevAccountTable、UserBindTable、LastPlayerTable;加载迁移脚本 ver_00001;设置预加载函数 preloadDevAccount。
- AddActors:注册 Player、Ops、Dev 三类 Actor 并启动。
- Dev 开发者账号(dev/actor.go)
- Register:校验用户名与密码长度与空白,检查唯一性,生成 GUID 作为 AccountID;写入缓存并入队持久化。
- Auth:优先从缓存命中,否则查库;返回 pb.I64(accountID) 与统一错误码。
- Player 玩家服务
- 父 Actor(player/actor.go):按 workerSize 创建子 ActorUID;OnRemoteReceived 按消息的 ChildID 计算 hash,将请求转发到对应子 Actor。
- 子 ActorUID(player/actor_uid.go):
- BindUID:构造 UserBindTable,入队到 DBQueue 异步落库。
- UpdateLastPlayer:从 Redis 取登录列表 → 更新玩家字段(ID/Name/Icon/Level/Power/UpTime)→ 按常量上限 constant.Player_LastMax 裁剪 → HSetJSON 回写;同时构造 LastPlayerTable 入队持久化。
- Ops 运维(ops/actor.go)
- Ping:返回 pb.Bool(true)。
- Shutdown:调用 App.Shutdown 优雅关闭。
- DbReport:返回 DBQueue 的队列状态报告。
消息路由与分片
- 父 Actor 根据消息 TargetPath 的 ChildID 取整并模 workerSize,选择子 ActorUID 处理,提升并发与隔离。
- workerSize 默认由 runtime.NumGoroutine()*2 计算,可按负载调整。
数据流与一致性
- 写入路径:业务请求 → 构造表对象 → save2Queue 入队 → DBQueue 后台消费写入 MongoDB。
- 缓存策略:开发者账号使用 goburrow/cache(访问后过期 48h),启动时 preloadDevAccount 批量预热,降低首请求延迟。
- 最终一致性:Redis 维护热数据(最后登录列表),DBQueue 保证异步持久化;出现短时不一致以队列为准。
- Redis 键构造:Center.BuildLastLoginKey(PID),使用 HSetJSON(OpenID → 登录列表) 存储。
错误码与返回约定
- 统一错误码来源 internal/code,典型值:OK、AccountInputParamsError、AccountNameLenError、AccountPasswordLenShort、AccountNameIsExist、AccountSDKAuthFail。
- 成功返回:
- Ping:pb.Bool(true)
- Auth:pb.I64(accountID)
- 其他更新类接口:无显式返回(依赖队列与日志观测)
接口字段参考
- Dev_Register/Dev_Auth(pb.DevRegister)
- Player_BindUID(pb.User)
- Player_UpdateLastPlayer(pb.UpdateLastPlayer)
- UID、PID、OpenID、GameNodeID、PlayerID、Icon、PlayerName、PlayerLevel、Power、UpTime
扩展指引
- 新增 Actor
- 创建包与 Actor 类型,实现 AliasID 与 OnInit,使用 p.Remote().Register 注册远程接口;在 center.go 的 AddActors 中加入。
- 新增数据库表
- 定义表结构(bson 标签)、实现 TableName/PrimaryValue/Save(或 Save2Queue);在 internal/db/db.go 的 AddTable 注册;必要时添加迁移脚本(实现 Version/Execute),在 AddScript 注册。
- 新增缓存或预加载
- 在 cache.go 定义缓存策略;通过 SetOnLoadFunc 配置预加载入口,确保启动即热数据可用。