# Profile 配置文件说明 本文档说明 `etc/profile/` 目录下各环境配置文件的组织方式、字段含义和修改原则。 ## 目录说明 ### 环境文件 当前仓库存在的顶层 profile 文件: | 文件 | 说明 | | --- | --- | | `local.json` | 本地 Docker 联调环境 | | `dev.json` | 开发环境 | | `test.json` | 测试环境 | | `su.json` | SU 环境 | | `su_dev.json` | SU 开发联调环境 | | `lgy.json` | LGY 环境 | | `lgy_dev.json` | LGY 开发联调环境 | | `dhc.json` | DHC 环境 | | `dhc_dev.json` | DHC 开发联调环境 | | `azw.json` | AZW 环境 | | `lcs.json` | 现有环境文件 | ### include 文件 `etc/profile/include/` 目录用于拆分公共片段,当前可见的公共配置包括: | 文件 | 用途 | | --- | --- | | `logger.json` | 日志模板 | | `dev_cluster.json` | 开发环境集群配置 | | `dev_data_config.json` | 开发环境数据配置 | | `dev_mongodb.json` | 开发环境 MongoDB 配置 | | `dev_redis.json` | 开发环境 Redis 配置 | | `dev_queue.json` | 数据库存盘队列配置 | | `dev_session.json` | 会话配置 | | `dev_genpool.json` | 全局 ID 池配置 | | `dev_game.json` | 开发环境节点配置 | | `dev_battle_record.json` | 战报配置 | ## 配置加载方式 节点启动入口在 `nodes/main.go`,执行流程是: 1. 读取命令行参数中的 `-path` 2. 读取命令行参数中的 `-node` 3. 调用 Cherry 的 `profile.Init(path, nodeID)` 4. 根据 `nodeID` 解析节点类型并启动对应节点 实际启动命令: ```bash run -path=./etc/profile/dev.json -node=1 ``` 因此 profile 的正确性,直接决定节点能否启动。 ## 整体结构 一个完整 profile 的典型结构如下: ```json { "@desc": "环境描述", "include": [], "env": "dev", "debug": true, "print_level": "debug", "cluster": {}, "data_config": {}, "node": {}, "db_queue": {}, "redis": [], "mongo": {}, "rate_limiter": [], "sessions": {}, "gen-pool": {}, "battle_record": {}, "logger": {} } ``` 并不是所有环境都必须把所有字段写满。 例如: - `su_dev.json` 主要通过 `include` 引入公共片段 - `local.json` 与 `dev.json` 则直接写了完整结构 ## 基础字段 | 字段 | 类型 | 说明 | | --- | --- | --- | | `@desc` | string | 环境描述 | | `include` | array | 需要合并的公共配置文件 | | `env` | string | 环境名 | | `debug` | bool | 是否开启调试模式 | | `print_level` | string | 全局日志级别 | ### include 用于配置复用。 示例: ```json { "include": [ "include/logger.json", "include/dev_mongodb.json", "include/dev_redis.json" ] } ``` 适用场景: - 同一套 Redis、Mongo、logger 被多个环境共用 - 平台环境只覆盖少量差异字段 ## cluster `cluster` 用于配置服务发现与节点通信。 ### 结构示例 ```json { "cluster": { "discovery": { "mode": "nats" }, "nats": { "master_node_id": "master-1", "prefix": "test", "address": "nats://nats:4222,nats://nats-1:4223,nats://nats-2:4224", "reconnect_delay": 1, "max_reconnects": 0, "request_timeout": 2, "user": "", "password": "", "pool_size": 16, "is_stats": false } } } ``` ### discovery | 字段 | 说明 | | --- | --- | | `mode` | 服务发现模式,当前项目实际主要使用 `nats` | 当前注释里还预留了: - `default` - `nats` - `etcd` 但仓库现有环境基本都是 `nats`。 ### nats | 字段 | 说明 | | --- | --- | | `master_node_id` | 主节点 ID,当前固定为 `master-1` | | `prefix` | 环境隔离前缀 | | `address` | NATS 地址列表,逗号分隔 | | `reconnect_delay` | 重连等待时间,单位秒 | | `max_reconnects` | 最大重连次数,`0` 表示不限 | | `request_timeout` | 请求超时,单位秒 | | `user` | 认证用户 | | `password` | 认证密码 | | `pool_size` | 连接池大小 | | `is_stats` | 是否开启统计 | ### 修改原则 - `prefix` 必须按环境唯一 - `master_node_id` 一般不要改 - `address` 必须与实际 NATS 集群对应 ## data_config 用于配置 Excel 导出的游戏数据加载方式。 ### 结构示例 ```json { "data_config": { "parser": "json", "data_source": "file", "file": { "file_path": "../data/", "ext_name": ".json", "reload_time": 3000 }, "redis": { "address": "redis:6379", "password": "xxx", "db": 0, "prefix_key": "data_config", "subscribe_key": "data_config_change" } } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `parser` | 解析器类型,当前使用 `json` | | `data_source` | 数据来源,支持 `file` 或 `redis` | #### `file` | 字段 | 说明 | | --- | --- | | `file_path` | 数据目录 | | `ext_name` | 文件扩展名 | | `reload_time` | 热更新检查间隔,毫秒 | #### `redis` | 字段 | 说明 | | --- | --- | | `address` | Redis 地址 | | `password` | Redis 密码 | | `db` | DB 编号 | | `prefix_key` | 数据前缀 | | `subscribe_key` | 配置变更订阅键 | ### 现状 当前环境主要还是 `file` 模式,目录通常是 `../data/`。 ## node `node` 是最关键的一段,决定当前 profile 支持哪些节点、每个节点如何匹配以及节点私有配置。 ### 结构示例 ```json { "node": { "gate": [ { "enable": true, "node_id": "gate-1", "address": ":30001", "__settings__": { "heartbeat": 120, "ref_logger": "debug_file_log", "redis_id_list": { "guid_redis_id": "redis-global", "center_redis_id": "redis-global" } } } ] } } ``` ### 通用字段 | 字段 | 说明 | | --- | --- | | `enable` | 是否启用该实例 | | `node_id` | 节点 ID,可写固定值,也可写正则 | | `address` | 对外监听地址,部分节点需要 | | `__settings__` | 节点私有设置 | ### `node_id` 规则 常见写法: | 写法 | 含义 | | --- | --- | | `gate-1` | 固定实例 | | `master-1` | 固定实例 | | `^\d+$` | 匹配任意数字 game 节点 | | `^map-\d+$` | 匹配多个 map 节点 | | `^chat-\d+$` | 匹配多个 chat 节点 | ### `__settings__` 常见字段 | 字段 | 说明 | | --- | --- | | `ref_logger` | 引用 `logger` 中的日志配置名 | | `redis_id_list` | 当前节点依赖的 Redis 配置映射 | | `mongo_id_list` | 当前节点依赖的 Mongo 配置映射 | | `heartbeat` | gate 心跳时间 | | `battle_validation` | game 是否开启战斗校验 | | `allow_register` | web 是否允许注册 | ### 节点类型 仓库当前支持的节点类型可从 `nodes/main.go` 看出: - `master` - `center` - `game` - `gate` - `web` - `ops` - `chat` - `map` - `record` ## db_queue `db_queue` 用于配置 MongoDB 批量落盘策略。 相关代码在 `internal/component/db/queue/table_queue_config.go`。 ### 结构示例 ```json { "db_queue": { "save_ticker": 3, "save_count": 1000, "stop_save_count": 10000, "print_save_log": false, "tables": [] } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `save_ticker` | 定时保存周期,秒 | | `save_count` | 每次批量保存条数 | | `stop_save_count` | 节点停止时一次处理条数 | | `print_save_log` | 是否打印保存日志 | | `tables` | 针对单表覆盖默认参数 | ### 单表覆盖 例如 `lgy.json` 与 `su.json` 中,会针对 `map_tile`、`map_res` 一类高频表做特殊配置。 示例: ```json { "tables": [ { "name": "map_tile", "save_ticker": 120, "save_count": 300 } ] } ``` ## redis `redis` 用于定义 Redis 实例列表,节点通过 `redis_id_list` 引用。 ### 结构示例 ```json { "redis": [ { "redis_id": "redis-global", "address": "redis:6379", "password": "xxx", "db": 0, "pool_size": 64, "desc": "全局" } ] } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `redis_id` | 逻辑 ID | | `address` | 地址 | | `password` | 密码 | | `db` | Redis DB | | `pool_size` | 连接池大小 | | `desc` | 描述 | ### 使用关系 - 先在 `redis` 中声明实例 - 再在 `node.*[].__settings__.redis_id_list` 中引用 - 运行时由 Redis 组件读取 `redis_id_list` ## mongo `mongo` 用于定义 MongoDB 分组配置,节点通过 `mongo_id_list` 引用。 ### 结构示例 ```json { "mongo": { "db_game_group": [ { "enable": true, "db_id": "mongo-f1-game", "db_name": "f1-game", "uri": "mongodb://user:pass@host:27017", "timeout": 3000 } ] } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `enable` | 是否启用 | | `db_id` | 逻辑 ID | | `db_name` | 数据库名 | | `uri` | Mongo 连接串 | | `timeout` | 超时,毫秒 | ### 分组说明 | 分组 | 用途 | | --- | --- | | `db_game_group` | game 数据 | | `db_center_group` | center 数据 | | `db_map_group` | map 数据 | ### 使用关系 - 先在 `mongo` 中定义 `db_id` - 再在节点 `mongo_id_list` 中引用 - 数据库组件根据 `mongo_id_list` 取对应实例 ## rate_limiter 用于限流配置。 ### 结构示例 ```json { "rate_limiter": [ { "enable": true, "rate_id": "ip_rate", "interval": 1, "capacity": 60, "quantum": 60, "clean_ticker_interval": 10, "clean_before_minute": 5, "error_code": 205 } ] } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `enable` | 是否启用 | | `rate_id` | 限流器 ID | | `interval` | 加令牌周期 | | `capacity` | 桶容量 | | `quantum` | 每次补充数量 | | `clean_ticker_interval` | 清理周期 | | `clean_before_minute` | 清理多久未使用的数据 | | `error_code` | 触发限流时返回码 | ## sessions 用于会话系统的 Redis 配置。 相关代码在 `internal/sessions/actor.go`。 ### 结构示例 ```json { "sessions": { "redis_id": "redis-global" } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `redis_id` | 会话系统使用的 Redis 实例 ID | ## gen-pool 用于全局 ID 生成池配置。 相关代码在 `internal/gen_pool/actor.go`。 ### 结构示例 ```json { "gen-pool": { "redis_id": "redis-global" } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `redis_id` | ID 池使用的 Redis 实例 ID | ## battle_record 用于战报记录存储配置。 相关代码: - `nodes/record/mode_file.go` - `nodes/record/mode_cloud.go` ### 结构示例 ```json { "battle_record": { "enable": true, "mode": "file", "file": { "suffixKey": ".bin", "succeedPathKey": "../battle_record/succeed", "failedPathKey": "../battle_record/failed" }, "cloud": { "url": "", "secretKey": "" } } } ``` ### 字段说明 | 字段 | 说明 | | --- | --- | | `enable` | 是否启用 | | `mode` | 存储方式,`file` 或 `cloud` | #### `file` | 字段 | 说明 | | --- | --- | | `suffixKey` | 后缀名 | | `succeedPathKey` | 成功目录 | | `failedPathKey` | 失败目录 | #### `cloud` | 字段 | 说明 | | --- | --- | | `url` | 上传地址 | | `secretKey` | 上传鉴权 | ## logger 用于定义日志模板,节点通过 `ref_logger` 引用。 ### 结构示例 ```json { "logger": { "debug_file_log": { "level": "debug", "stack_level": "error", "enable_write_file": true, "enable_console": false, "max_age": 7, "time_format": "15:04:05.000", "print_caller": true, "rotation_time": 86400, "file_link_path": "logs/%nodeid.log", "file_path_format": "logs/%nodeid_%Y%m%d%H%M.log" } } } ``` ### 当前常用日志模板 从 `include/logger.json` 看,常见模板有: - `debug_console_log` - `debug_file_log` - `debug_log` - `info_console_log` - `info_file_log` - `info_log` ### 字段说明 | 字段 | 说明 | | --- | --- | | `level` | 日志级别 | | `stack_level` | 触发堆栈打印的级别 | | `enable_write_file` | 是否写文件 | | `enable_console` | 是否输出控制台 | | `max_age` | 保留天数 | | `time_format` | 时间格式 | | `print_caller` | 是否打印调用位置 | | `rotation_time` | 滚动周期,秒 | | `file_link_path` | 当前日志软链路径 | | `file_path_format` | 日志文件命名格式 | ## 不同环境的典型差异 ### local.json - 本地 Docker 联调 - Redis 地址是 `redis:6379` - Mongo 库名是 `local-f1-*` - 日志默认写文件 ### dev.json - 开发环境 - Redis、Mongo、NATS 指向开发环境地址 - `game` 节点通常使用数字 ID ### `*_dev.json` - 通过 `include` 复用公共配置 - 一般只覆盖少量差异,如 `env`、`cluster.nats.pool_size` ### 平台环境文件 例如 `su.json`、`lgy.json`、`azw.json`: - 通过不同 `env` 区分平台 - 通过不同 `cluster.nats.prefix` 做集群隔离 - 通过不同 `db_name` 做数据库隔离 - `game` 节点编号可能固定,也可能允许多实例 ## 修改建议 ### 新增环境 建议流程: 1. 复制最接近的现有环境文件 2. 修改 `env` 3. 修改 `cluster.nats.prefix` 4. 修改 Redis 与 Mongo 地址、密码、库名 5. 修改节点 `node_id` 与端口 6. 启动单节点验证 ### 修改已有环境 优先检查四个高风险字段: 1. `cluster.nats.prefix` 2. `mongo.*.db_name` 3. `node.*[].node_id` 4. `node.*[].__settings__.redis_id_list` / `mongo_id_list` ### 不建议直接改的内容 - `master_node_id` - 节点类型名称 - 已上线环境的 `db_name` - 已上线环境的 `game` 节点 ID 规则 ## 启动示例 ```bash run -path=./etc/profile/local.json -node=gate-1 run -path=./etc/profile/dev.json -node=1 run -path=./etc/profile/su.json -node=master-1 run -path=./etc/profile/lgy.json -node=web-1 ``` ## 常见错误 ### 1. `-node` 与 `node_id` 不匹配 例如 profile 里写的是 `node_id: "web-1"`,启动却用了 `-node=web`。 ### 2. 只改了 `redis`,没改 `redis_id_list` 节点最终使用哪个 Redis,不是看你定义了多少个 `redis`,而是看节点 settings 引用了哪个 ID。 ### 3. `include` 引入了公共配置,但顶层又被错误覆盖 这种问题最容易出现在 `*_dev.json`。改动前先确认最终覆盖顺序。 ### 4. NATS prefix 与其他环境重复 节点会串环境,这是最危险的配置错误之一。