# Center 节点说明 ## 节点定位 - 提供跨游戏服的中心数据与控制平面 - 统一账号绑定(UID ↔ 第三方平台 OpenID)、开发者账号注册与认证 - 聚合并缓存玩家“最后登录记录”,兼顾 Redis 热数据与 MongoDB 持久化 - 运维控制接口:存活探测、优雅关停、DB 队列监控 ## 启动流程 - 入口:[center.go](./center.go) - 基于 Cherry 框架配置并启动节点,注册组件与 Actor: - 组件:GOPS、配置加载(SDK/RateLimiter/Lua)、Redis 客户端(GUID/Center)、数据库组件 - Actor:Player、Ops、Dev - 关键步骤顺序:ConfigureNode → Register(组件) → AddActors → Startup ## 主要 Actor 与远程接口 - Ops 运维 - 文件:[actor.go](./ops/actor.go) - 接口:Ping(健康探测)、Shutdown(优雅关停)、DbReport(DB 队列状态) - Dev 开发者账号 - 文件:[actor.go](./dev/actor.go) - 接口:Register(注册开发者账号)、Auth(账号认证) - Player 玩家服务 - 文件:[actor.go](./player/actor.go)、[actor_uid.go](./player/actor_uid.go) - 设计:父 Actor 按 workerSize 分片,将消息转发到子 ActorUID - 接口:BindUID(UID 绑定第三方平台)、UpdateLastPlayer(更新最后登录记录) ## 数据模型与持久化 - 数据库组件 - 文件:[db.go](./internal/db/db.go) - 表:DevAccountTable、UserBindTable、LastPlayerTable - 写入:统一通过 DBQueue 异步入队(save2Queue),提升写入峰值承载与可靠性 - 脚本:版本迁移脚本 [ver_00001.go](./internal/db/ver_00001.go) - 玩家最后登录记录 - 结构定义:[last_player.go](./internal/db/data/last_player.go)、[last_player_table.go](./internal/db/last_player_table.go) - 写入策略:ActorUID 接口更新 Redis 列表并裁剪至上限,同时入队持久化到 MongoDB - 账号绑定 - 逻辑入口:[user_bind_table.go](./internal/db/user_bind_table.go) - 通过 UID、SDKID、PID、OpenID 进行关联,记录绑定时间 - 开发者账号 - 逻辑入口:[dev_account_table.go](./internal/db/dev_account_table.go) - 支持注册与认证,账号 ID 由 GUID 生成 ## 缓存与预加载 - 开发者账号缓存 - 文件:[cache.go](./internal/db/cache.go) - 实现:goburrow/cache,按访问后过期(48h),减少数据库查询压力 - 预加载 - 文件与方法:preloadDevAccount(见 [dev_account_table.go](./internal/db/dev_account_table.go)) - 启动时分页拉取历史数据入缓存,降低首请求延迟 ## 运维与监控 - Ping:检查 Center 节点存活与响应 - Shutdown:协调应用优雅关闭 - DbReport:查询数据库队列堆积与处理状态,辅助容量评估与告警 - 入口参考:[ops/actor.go](./ops/actor.go) ## 目录结构概览 - dev:开发者账号相关 Actor 与逻辑 - internal/db:数据库组件、表定义、数据结构、缓存与迁移脚本 - ops:运维 Actor 与远程接口 - player:玩家 Actor 分片与 UID 接口、最后登录数据更新 ## 设计目标 - 高可用:通过分片 Actor 与异步队列提升吞吐与隔离故障 - 一致性:Redis 作为热数据缓存,DBQueue 保障最终一致性 - 易扩展:Actor 体系可按业务维度扩展,DB 脚本支持增量迁移 - 可观测:内置运维接口与队列报告,便于监控与告警集成 ## 远程接口列表 - Ops - CenterOps_Ping → 返回 pb.Bool,健康探测([ops/actor.go](./ops/actor.go)) - CenterOps_Shutdown → 返回 code,优雅关停([ops/actor.go](./ops/actor.go)) - CenterOps_DbReport → 返回 pb.DBQueueReportList,DB 队列状态([ops/actor.go](./ops/actor.go)) - Dev - Dev_Register(pb.DevRegister) → 返回 code,注册开发者账号([dev/actor.go](./dev/actor.go)) - Dev_Auth(pb.DevRegister) → 返回 pb.I64(accountID), code,账号认证([dev/actor.go](./dev/actor.go)) - Player - Player_BindUID(pb.User) → 无返回(异步入队持久化)([player/actor_uid.go](./player/actor_uid.go)) - Player_UpdateLastPlayer(pb.UpdateLastPlayer) → 无返回(更新 Redis 并入队 DB)([player/actor_uid.go](./player/actor_uid.go)) ## 典型调用流程 - 开发者账号注册与认证 - 客户端 → 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) - AccountName、Password、Ip - Player_BindUID(pb.User) - Uid、SdkID、PID、OpenID - 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 配置预加载入口,确保启动即热数据可用。