# Go 微服务游戏平台架构设计

## 1. 设计目标

本架构用于重建一套高并发、可扩展、可自建部署的游戏平台系统。目标不是照搬旧系统的 PHP + Go + SQL Server 混合架构，而是吸收旧系统中已经验证过的游戏采集数据、slots 数学配置、返奖逻辑、商户对接模式，再用现代 Go 微服务方式重新设计。

开发阶段必须同时遵守 [AI开发约束与架构定稿.md](./AI开发约束与架构定稿.md)。该文档用于约束 Codex、AI 编程助手和开发人员，禁止随意更换框架、合并服务、绕过账本、绕过事件流或破坏高并发主链路设计。

继续开发前还必须阅读 [旧项目与新架构目录对齐审计.md](./旧项目与新架构目录对齐审计.md)。该文档用于说明旧 PHP/Go/SQL Server/Redis/slots 配置如何映射到新 Go 微服务，以及为什么本项目不能照抄 CloudWeGo Hertz 官方框架源码仓库的根目录结构。

核心目标如下：

- 使用 Go 微服务作为后端主体。
- 第一阶段支持一台服务器部署，使用单节点 K3s/Kubernetes 管理多个服务镜像。
- 所有数据库、中间件、数仓、对象存储全部自建，不依赖云厂商托管服务。
- 商户 API、玩家游戏 API、总后台 API 分离。
- 商户余额查询、扣款、派奖、退款、注单查询、结果推送由独立高并发服务承载，支持扩展负载。
- 游戏服务按子游戏拆分，每个子游戏独立镜像、独立 Deployment，可单独扩容和灰度。
- slots 返奖继续复用采集数据，但改为配置中心 + 内存加载 + 版本化发布模式。
- 总后台统计走自建数仓，避免直接查询交易主库。
- 当前阶段支持排行榜、在线状态、实时推送；聊天室能力后置按需开发。
- 从第一阶段开始按未来多机、K8s、负载均衡、服务治理方向设计。

## 2. 总体架构

```mermaid
flowchart TD
    Merchant["商户系统"] --> MerchantGateway["merchant-gateway 商户网关"]
    Player["玩家客户端"] --> GameGateway["game-gateway 游戏网关"]
    Admin["总后台"] --> AdminGateway["admin-gateway 后台网关"]

    MerchantGateway --> Wallet["wallet-service 钱包服务"]
    MerchantGateway --> Order["bet-order-service 注单服务"]
    MerchantGateway --> Callback["callback-service 回调服务"]

    GameGateway --> Session["game-session-service 会话服务"]
    GameGateway --> Router["game-router 游戏路由"]

    Router --> GameA["game-pg-olympus 子游戏服务"]
    Router --> GameB["game-jili-superace 子游戏服务"]
    Router --> GameC["game-cp-luckytiger 子游戏服务"]

    GameA --> Engine["slots-runtime-sdk 返奖引擎"]
    GameB --> Engine
    GameC --> Engine

    Engine --> Config["game-config-service 配置服务"]
    Engine --> Risk["risk-rtp-service 风控/RTP服务"]
    Engine --> Redis["Redis Cluster"]

    Wallet --> Ledger["ledger-service 账本服务"]
    Order --> Ledger
    Ledger --> PG["PostgreSQL 交易数据库"]

    Order --> MQ["Redpanda/Kafka 事件总线"]
    Wallet --> MQ
    Callback --> MQ
    GameA --> MQ
    GameB --> MQ
    GameC --> MQ

    MQ --> WarehouseWriter["warehouse-writer 数仓写入"]
    WarehouseWriter --> CH["ClickHouse 数仓"]

    Config --> MinIO["MinIO 配置/采集文件存储"]
    Config --> PG

    AdminGateway --> PG
    AdminGateway --> CH
    AdminGateway --> Redis

    GameGateway --> Ranking["ranking-service 排行榜"]
    GameGateway -. 后置按需 .-> Chat["chat-service 聊天室"]
    GameGateway --> Presence["presence-service 在线状态"]
```

## 3. 第一阶段单机部署方案

第一阶段使用一台服务器部署整套系统。物理上是单机，逻辑上仍按微服务架构拆分。

推荐使用 K3s，而不是完整 kubeadm。K3s 更轻，适合单机验证和小规模生产过渡。

第一阶段建议采用“业务服务进 K3s，状态服务跑宿主机或 Docker Compose”的方式。

宿主机部署：

- PostgreSQL
- Redis
- Redpanda
- ClickHouse
- MinIO
- Prometheus
- Grafana
- Loki

K3s 部署：

- merchant-gateway
- game-gateway
- admin-gateway
- wallet-service
- ledger-service
- bet-order-service
- settlement-service
- callback-service
- reconciliation-service
- game-router
- game-session-service
- game-config-service
- risk-rtp-service
- ranking-service
- chat-service（后置按需开发，不作为当前阶段已实现服务）
- presence-service
- notification-service
- warehouse-writer
- report-service
- 各个 game-* 子游戏服务

这样做的好处是：

- 业务服务从第一天就是容器化、可独立部署。
- 数据库和中间件第一阶段更容易排障和备份。
- 后续扩容到多台服务器时，业务服务基本不需要重构。
- 未来可以逐步把 PostgreSQL、Redis、Redpanda、ClickHouse、MinIO 迁移为集群。

## 4. 服务拆分

### 4.1 入口层服务

#### merchant-gateway

商户统一接入网关，负责所有对外商户 API。

职责：

- 商户签名校验。
- API Key / Secret 管理。
- 商户 IP 白名单。
- 请求限流。
- 幂等校验。
- 请求参数标准化。
- 余额查询入口。
- 扣款入口。
- 派奖入口。
- 退款入口。
- 注单查询入口。
- 商户回调补偿入口。

merchant-gateway 不直接处理复杂业务，只负责鉴权、限流、幂等、路由和协议适配。

#### game-gateway

玩家游戏入口网关。

职责：

- 玩家 token 校验。
- 游戏入口鉴权。
- 维护玩家与游戏服务的连接入口。
- HTTP/WebSocket 协议接入。
- 将请求转发给 game-router 或具体游戏服务。
- 对外隐藏内部服务拓扑。

#### admin-gateway

总后台入口。

职责：

- 管理员登录。
- RBAC 权限。
- 菜单权限。
- 操作审计。
- 管理接口聚合。
- 调用报表、风控、配置、商户、玩家、注单等内部服务。

## 5. 核心交易服务

### 5.1 wallet-service

钱包服务负责余额视图和资金操作入口。

职责：

- 查询余额。
- 冻结金额。
- 解冻金额。
- 扣款。
- 派奖。
- 退款。
- 冲正。
- 余额快照维护。

wallet-service 不应只做简单余额加减。所有资金变更必须通过 ledger-service 写入不可变账本。

### 5.2 ledger-service

账本服务是资金系统的核心。

设计原则：

- 账本只追加，不覆盖。
- 每一笔扣款、派奖、退款、冲正、人工调整都必须有 ledger entry。
- 当前余额可以放在余额快照表，但最终以账本流水为准。
- 每笔账变必须关联 merchant_id、player_id、round_id、order_id、transaction_id。

账本事件类型：

- BET_DEBIT：下注扣款。
- BET_DEBIT_REVERSE：下注扣款冲正。
- PAYOUT_CREDIT：派奖加款。
- PAYOUT_REVERSE：派奖冲正。
- REFUND：退款。
- MANUAL_ADJUST：人工调整。

### 5.3 bet-order-service

注单服务负责下注订单生命周期。

注单状态机：

```text
CREATED
DEBIT_PENDING
DEBIT_SUCCESS
RESULT_GENERATED
SETTLE_PENDING
SETTLED
CALLBACK_PENDING
CALLBACK_SUCCESS
FAILED
REVERSED
```

设计原则：

- 一个 round_id 只能对应一局游戏。
- 一个 client_request_id 只能产生一笔有效下注。
- 注单状态只能按状态机推进，不能随意跳转。
- 所有状态变化必须写事件。
- 注单最终状态必须可追溯。

### 5.4 settlement-service

结算服务负责根据游戏结果完成派奖。

职责：

- 接收游戏结果。
- 校验注单状态。
- 计算派奖金额。
- 调用 wallet-service 派奖。
- 更新注单状态。
- 产生结算事件。
- 对失败结算执行重试或进入人工处理。

### 5.5 idempotency-service

幂等服务用于防止重复扣款、重复派奖、重复创建注单。

幂等范围：

- 商户请求幂等。
- 玩家 spin 请求幂等。
- 钱包扣款幂等。
- 派奖幂等。
- 回调幂等。

幂等 key 示例：

```text
idempotency:{merchant_id}:{request_id}
idempotency:spin:{player_id}:{game_code}:{client_request_id}
idempotency:ledger:{transaction_id}
idempotency:callback:{callback_id}
```

短期幂等可存在 Redis，长期幂等必须落 PostgreSQL。

### 5.6 callback-service

商户回调服务负责异步推送结果。

职责：

- 注单结果推送。
- 派奖结果推送。
- 回调失败重试。
- 指数退避。
- 死信队列。
- 后台手动补推。
- 回调日志查询。

回调不应阻塞玩家主链路。玩家结算成功后，商户回调通过事件异步执行。

### 5.7 reconciliation-service

对账服务负责商户账变、平台账本、注单状态之间的核对。

职责：

- 商户日账单。
- 平台账单。
- 注单与账本一致性检查。
- 回调成功率检查。
- 异常订单扫描。
- 人工补偿入口。

## 6. 游戏运行服务

### 6.1 game-router

游戏路由服务根据 game_code 路由到具体子游戏服务。

职责：

- 维护 game_code 到服务地址的映射。
- 支持服务发现。
- 支持灰度发布。
- 支持按游戏、商户、地区做路由策略。

### 6.2 game-session-service

游戏会话服务负责玩家游戏会话。

职责：

- 进入游戏。
- 生成游戏 token。
- 维护在线状态。
- 记录当前游戏。
- 支持断线重连。
- 支持踢人。
- 支持玩家未展示结果恢复。

### 6.3 子游戏服务

每个子游戏独立服务、独立镜像、独立 Deployment。

示例：

```text
game-pg-olympus
game-pg-sweetbonanza
game-jili-superace
game-cp-luckytiger
```

每个子游戏服务职责：

- 接收 spin 请求。
- 校验 session。
- 调用注单服务创建 round。
- 调用钱包服务扣款。
- 使用本地内存中的游戏配置生成结果。
- 调用结算服务派奖。
- 返回开奖结果。
- 发布游戏事件。
- 维护当前玩家游戏状态。

热门游戏可以独立扩容，冷门游戏保持单副本。

### 6.4 slots-runtime-sdk

返奖引擎不建议做成每局远程调用的独立服务。高并发情况下，远程 RPC 会增加延迟和故障点。

推荐做法是提供 Go SDK/library，被每个子游戏服务内嵌使用。

slots-runtime-sdk 职责：

- 加载游戏数学配置。
- 解析 paytable。
- 解析 reel_set。
- 处理下注档位。
- 处理普通 spin。
- 处理 free spin。
- 处理 bonus。
- 处理 buy free。
- 计算 WinAmount。
- 计算 UpdateAmount。
- 生成可回放 result_json。
- 记录 config_version 和 result_hash。

### 6.5 game-config-service

配置服务负责管理采集来的 slots 数据和游戏数学配置。

职责：

- 上传采集文件。
- 原始文件保存到 MinIO。
- 解析配置。
- 生成标准化配置结构。
- 维护配置版本。
- 配置发布。
- 配置回滚。
- 通知游戏服务热更新。

采集数据不要再像旧系统那样手工复制到每个游戏目录，而应通过配置中心统一管理。

配置加载流程：

```text
采集文件上传
-> MinIO 保存原始文件
-> game-config-service 解析
-> PostgreSQL 保存配置元数据
-> 生成配置版本
-> 发布配置变更事件
-> 子游戏服务热加载到本地内存
```

每局 spin 时只读本地内存，不查数据库。

### 6.6 risk-rtp-service

风控和 RTP 服务负责控制策略。

职责：

- 商户 RTP 档位。
- 游戏 RTP 档位。
- 单玩家控制。
- 控赢配置。
- 控输配置。
- 池控。
- 最大赢限制。
- 异常下注风控。
- 高频请求风控。

控制配置可以存 PostgreSQL，热状态和实时命中状态放 Redis。

游戏服务在开奖前读取本地缓存或 Redis 热配置，不在每局请求中频繁查询数据库。

## 7. 排行榜、在线状态与后置聊天室

### 7.1 ranking-service

排行榜服务负责实时榜单和历史榜单。

设计：

- 实时榜单使用 Redis Sorted Set。
- 榜单变动通过事件进入 Redpanda。
- 历史榜单写入 ClickHouse。
- 定时快照可写 PostgreSQL 或 ClickHouse。

Redis key 示例：

```text
ranking:{merchant_id}:{game_code}:{date}
ranking:global:{game_code}:{date}
```

### 7.2 chat-service

聊天室服务后置按需开发，当前阶段只保留边界设计，不声明已经实现。

职责：

- WebSocket 长连接。
- 游戏房间频道。
- 商户频道。
- 世界频道。
- 敏感词过滤。
- 禁言。
- 黑名单。
- 消息限流。
- 聊天记录异步落库。

聊天消息热路径走 WebSocket + Redis PubSub 或 Redpanda，历史消息异步写入 ClickHouse 或 PostgreSQL。

### 7.3 presence-service

在线状态服务负责玩家在线、当前游戏、心跳。

职责：

- 玩家在线状态。
- 当前所在游戏。
- 当前房间。
- 心跳续约。
- 断线检测。
- 踢人。
- 重连恢复。

Redis key 示例：

```text
player:online:{player_id}
player:game:{player_id}
game:players:{game_code}
```

## 8. 数据库和中间件选型

### 8.1 PostgreSQL

用途：

- 商户。
- 玩家。
- 钱包。
- 账本。
- 注单主状态。
- 游戏配置元数据。
- 风控配置。
- 后台权限。

推荐分库：

```text
platform_db       平台、商户、管理员、权限
wallet_db         钱包、余额快照、账本
order_db          注单主表、结算状态
config_db         游戏配置元数据、RTP配置、版本
risk_db           风控策略、控奖配置
```

第一阶段可以跑单实例，但表结构和连接配置按未来分库设计。

### 8.2 Redis

用途：

- session。
- 短期幂等。
- 游戏临时状态。
- 玩家在线。
- 排行榜实时榜。
- RTP 热配置。
- 单控热配置。
- 限流。

Redis 不作为最终账本，只存可恢复状态。

### 8.3 Redpanda/Kafka

用途：

- 下注事件。
- 扣款事件。
- 派奖事件。
- 游戏结果事件。
- 回调事件。
- 排行榜事件。
- 聊天事件。
- 风控事件。
- 数仓写入事件。

推荐第一阶段使用 Redpanda，原因是自建更轻，不依赖 ZooKeeper，兼容 Kafka 协议。

### 8.4 ClickHouse

用途：

- 注单明细查询。
- 玩家输赢统计。
- 商户报表。
- 游戏日报。
- 玩家日报。
- RTP 分析。
- 回调成功率。
- 排行榜历史。
- 风控分析。

总后台统计必须查 ClickHouse，不直接扫 PostgreSQL 交易主库。

### 8.5 MinIO

用途：

- slots 采集文件。
- 游戏数学配置原始文件。
- 配置版本包。
- 回放文件。
- 大日志归档。
- 静态资源归档。

PostgreSQL 只存文件元数据、版本、hash、启用状态。

### 8.6 监控和日志

自建组件：

- Prometheus：指标采集。
- Grafana：监控面板。
- Loki：日志收集。
- Alertmanager：告警。
- Jaeger 或 Tempo：链路追踪。

所有 Go 服务必须输出：

- request_id
- trace_id
- merchant_id
- player_id
- round_id
- order_id
- service_name
- latency
- error_code

## 9. slots 返奖设计

旧系统中 slots 返奖依赖 betconfig、slotsdata、reel_set、paytable 等采集文件。当前阶段优先落地真实 `game-pg-mahjong`（PG Mahjong Ways）：结果池参考旧系统 `slotsdata`，旧 `dat` 文件通过导入工具转换为新格式。新系统继续复用这些采集数据，但不再手工复制目录。

新设计：

```text
采集数据
-> 上传到 game-config-service
-> 原始文件进 MinIO
-> 解析为标准配置
-> PostgreSQL 保存版本元数据
-> 发布配置版本
-> 子游戏服务热加载到本地内存
-> spin 时内存计算
-> 结果写事件和注单
```

返奖主路径不查数据库。

每局需要记录：

- round_id
- game_code
- player_id
- merchant_id
- bet_amount
- win_amount
- update_amount
- result_json
- config_version
- rng_seed_hash
- result_hash
- created_at

结果一旦生成，不允许修改。后续只能重试结算或冲正，不能重新开奖。

## 10. 下注主流程

```text
1. 玩家请求 spin。
2. game-gateway 校验 token。
3. game-router 路由到子游戏服务。
4. 子游戏服务生成 round_id。
5. bet-order-service 创建注单。
6. wallet-service 扣款或冻结。
7. 子游戏服务使用本地配置和风控状态生成结果。
8. settlement-service 派奖。
9. ledger-service 写账本。
10. bet-order-service 更新注单状态。
11. callback-service 异步通知商户。
12. 事件进入 Redpanda。
13. warehouse-writer 写 ClickHouse。
14. 后台从 ClickHouse 查询统计。
```

主链路只等待必要交易步骤。商户回调、统计、报表、排行榜历史全部异步化。

## 11. 玩家超时处理

玩家超时但 Go 服务下注成功时，必须以服务端状态为准。

原则：

- 客户端超时不代表下注失败。
- 只要服务端扣款成功，就必须生成唯一结果并落注单。
- 同一个 request_id 重试不能再次扣款。
- 玩家重连后必须返回同一局结果。
- 不能出现扣款成功但无结果。
- 不能出现结果成功但未结算且无人处理。

展示状态和业务状态分开。

业务状态：

```text
CREATED
DEBIT_PENDING
DEBIT_SUCCESS
RESULT_GENERATED
SETTLE_PENDING
SETTLED
FAILED
REVERSED
```

展示状态：

```text
NOT_DISPLAYED
DISPLAYED
```

如果玩家超时，但服务端已经完成结算：

```text
不退款
不重新开局
不重新扣款
不重新生成结果
重连或重试时返回同一局结果
```

需要提供接口：

```text
GET /game/round/latest-unconfirmed
POST /game/round/confirm-displayed
```

Redis 可以保存：

```text
pending_round:{player_id}:{game_code} = round_id
idempotency:spin:{player_id}:{game_code}:{client_request_id} = round_id
```

PostgreSQL 保存最终状态。Redis 丢失时，可从 PostgreSQL 恢复。

如果状态卡在 `DEBIT_SUCCESS`，补偿 worker 继续完成开奖或按规则冲正。

如果状态卡在 `RESULT_GENERATED`，补偿 worker 继续派奖，不能重新生成结果。

## 12. 补偿和容错

必须设计后台补偿任务。

补偿扫描状态：

- DEBIT_PENDING 超时。
- DEBIT_SUCCESS 超时。
- RESULT_GENERATED 超时。
- SETTLE_PENDING 超时。
- CALLBACK_PENDING 超时。

处理策略：

- 扣款未确认：查询钱包交易状态。
- 扣款成功但无结果：继续生成结果。
- 已生成结果但未派奖：继续派奖。
- 派奖成功但回调失败：继续回调。
- 超过安全窗口仍无法完成：进入人工处理。

所有补偿必须写审计日志。

## 13. 商户 API 设计范围

第一阶段商户 API 至少包括：

- 创建玩家或获取玩家。
- 查询余额。
- 玩家登录游戏。
- 下注扣款。
- 派奖。
- 退款。
- 注单查询。
- 账变查询。
- 游戏列表。
- 回调通知。
- 回调补推。

商户 API 必须支持：

- 签名。
- 时间戳。
- nonce。
- request_id。
- 幂等。
- IP 白名单。
- 限流。
- 错误码标准化。

## 14. K8s 部署设计

每个服务一个镜像。

镜像示例：

```text
registry/merchant-gateway:v1
registry/wallet-service:v1
registry/ledger-service:v1
registry/bet-order-service:v1
registry/game-config-service:v1
registry/risk-rtp-service:v1
registry/game-pg-olympus:v1
registry/game-jili-superace:v1
```

每个子游戏独立 Deployment。

扩容示例：

```text
game-pg-olympus replicas=8
game-jili-superace replicas=6
game-cp-luckytiger replicas=3
冷门游戏 replicas=1
```

未来多机时，只需要加入 K8s 节点，并调整副本、资源限制、HPA 策略。

## 15. 第一版最小闭环

第一版不要一次实现所有服务。先完成一条完整业务闭环。

最小闭环服务：

- merchant-gateway
- wallet-service
- ledger-service
- bet-order-service
- settlement-service
- callback-service
- game-gateway
- game-router
- game-config-service
- risk-rtp-service
- 一个示范 slots 子游戏服务
- event-writer
- admin-api
- report-service
- warehouse-writer

最小闭环流程：

```text
商户接入
-> 玩家进入游戏
-> spin
-> 扣款
-> 开奖
-> 派奖
-> 回调商户
-> 后台查注单
-> 后台查统计
```

这个闭环跑通后，再复制更多子游戏服务。

## 16. 必须从第一天具备的工程细节

每个请求和事件必须有：

- trace_id
- request_id
- merchant_id
- player_id
- game_code
- round_id
- bet_order_id
- ledger_transaction_id
- event_id
- config_version
- result_hash

每个服务必须具备：

- 健康检查。
- 优雅停机。
- 超时控制。
- 重试策略。
- 限流。
- 熔断。
- 结构化日志。
- Prometheus 指标。
- 链路追踪。

每个核心操作必须具备：

- 幂等。
- 状态机。
- 审计日志。
- 补偿机制。
- 错误码。

## 17. 服务级中文文档要求

本架构文档是总架构文档。后续进入开发阶段后，每一个微服务都必须单独编写一份中文服务文档，方便后端、前端、运维、测试、后续新同事快速理解。

服务文档必须使用中文表述，文件名也必须使用清晰的中文或“服务名 + 中文说明”的格式。

推荐目录结构：

```text
golang新架构/
├── 项目文档/
│   ├── 架构文档/
│   │   ├── Go微服务游戏平台架构设计.md
│   │   └── AI开发约束与架构定稿.md
│   ├── 实施计划/
│   │   └── 第一阶段实现计划.md
│   ├── 服务文档/
│   │   ├── merchant-gateway-商户网关服务.md
│   │   ├── wallet-service-钱包服务.md
│   │   ├── ledger-service-账本服务.md
│   │   ├── bet-order-service-注单服务.md
│   │   ├── settlement-service-结算服务.md
│   │   ├── callback-service-商户回调服务.md
│   │   ├── game-gateway-游戏网关服务.md
│   │   ├── game-router-游戏路由服务.md
│   │   ├── game-config-service-游戏配置服务.md
│   │   ├── risk-rtp-service-风控RTP服务.md
│   │   ├── ranking-service-排行榜服务.md
│   │   ├── 实时聊天能力说明（后置按需，当前阶段不创建 chat-service 文档）
│   │   └── game-pg-mahjong-子游戏服务.md
│   ├── 数据库文档/
│   │   ├── platform_db-平台库.md
│   │   ├── wallet_db-钱包账本库.md
│   │   ├── order_db-注单库.md
│   │   ├── config_db-配置库.md
│   │   ├── risk_db-风控库.md
│   │   └── clickhouse-数仓表说明.md
│   └── 运维文档/
│       ├── 单机K3s部署说明.md
│       ├── 服务发布与回滚说明.md
│       ├── 数据库备份恢复说明.md
│       └── 故障排查命令.md
```

每个服务文档必须包含以下内容：

```text
1. 服务名称
2. 服务职责
3. 不负责的边界
4. 上游调用方
5. 下游依赖服务
6. 依赖数据库
7. 依赖 Redis key
8. 依赖消息队列 topic
9. 对外 HTTP API
10. 内部 gRPC API
11. 请求参数
12. 响应参数
13. 错误码
14. 幂等规则
15. 状态机
16. 超时和重试策略
17. 补偿逻辑
18. 配置项
19. 启动命令
20. 本地调试命令
21. Docker 构建命令
22. K8s 部署命令
23. 日志查看命令
24. 健康检查命令
25. 常见故障排查
```

每个服务文档中的命令必须写成可复制执行的格式，例如：

```bash
# 本地启动
go run ./cmd/merchant-gateway

# 运行单元测试
go test ./...

# 构建镜像
docker build -t registry.local/merchant-gateway:v1 .

# 推送镜像
docker push registry.local/merchant-gateway:v1

# 部署到 K3s
kubectl apply -f deploy/k8s/merchant-gateway.yaml

# 查看 Pod
kubectl get pods -n game-platform -l app=merchant-gateway

# 查看日志
kubectl logs -n game-platform deploy/merchant-gateway --tail=200 -f

# 查看服务配置
kubectl describe deployment -n game-platform merchant-gateway

# 健康检查
curl -s http://merchant-gateway.game-platform.svc.cluster.local/health
```

服务文档必须明确写清楚“本服务不能做什么”。例如 wallet-service 不能直接生成游戏结果，game 服务不能直接改账本余额，admin-gateway 不能绕过业务服务直接修改核心交易表。

这样可以避免后续开发过程中服务边界变乱。

## 18. 数据库详细说明和架构图要求

### 18.1 数据库文档要求

所有数据库必须单独写中文数据库文档。每个库、每张表、每个关键字段都要详细说明。

数据库文档必须包含：

```text
1. 数据库名称
2. 数据库用途
3. 所属服务
4. 是否交易核心库
5. 是否允许后台直接写入
6. 表清单
7. 表用途
8. 字段说明
9. 主键
10. 唯一索引
11. 普通索引
12. 分区策略
13. 数据保留周期
14. 是否进入 ClickHouse
15. 是否需要备份
16. 备份频率
17. 恢复优先级
18. 示例 SQL
```

核心数据库必须至少包括：

```text
platform_db
- 商户表
- 商户密钥表
- 商户 IP 白名单表
- 管理员表
- 角色表
- 权限表
- 菜单表
- 操作审计表

wallet_db
- 玩家钱包表
- 余额快照表
- 不可变账本表
- 冻结资金表
- 账变事务表
- 人工调整表

order_db
- 注单主表
- 注单状态流转表
- 游戏 round 表
- 结算表
- 退款表
- 回调任务表
- 回调日志表

config_db
- 游戏基础信息表
- 游戏配置版本表
- slots 原始文件元数据表
- slots 解析配置表
- 游戏发布记录表
- 配置回滚记录表

risk_db
- RTP 档位表
- 商户 RTP 配置表
- 游戏 RTP 配置表
- 单玩家控制表
- 池控配置表
- 风控规则表
- 风控命中记录表

ClickHouse
- bet_events
- wallet_events
- game_round_events
- merchant_callback_events
- player_online_events
- ranking_events
- daily_merchant_report
- daily_game_report
- daily_player_report
```

核心交易表必须明确写清楚幂等字段和唯一约束。例如：

```text
注单表必须有：
- round_id 唯一
- merchant_id + merchant_order_no 唯一
- player_id + game_code + client_request_id 唯一

账本表必须有：
- ledger_transaction_id 唯一
- round_id
- bet_order_id
- entry_type
- amount
- balance_before
- balance_after
```

数据库文档中必须写示例 SQL，格式如下：

```sql
-- 查询某一局注单
SELECT *
FROM bet_orders
WHERE round_id = 'R202606060001';

-- 查询某个玩家账本
SELECT *
FROM ledger_entries
WHERE player_id = 10001
ORDER BY created_at DESC
LIMIT 100;
```

### 18.2 架构图要求

本项目必须维护一张总架构图，并在架构变更时同步更新。

总架构图要求：

- 使用 Mermaid 维护在 Markdown 中，方便版本管理。
- 后续可以导出 PNG 或 SVG 给产品、运维、开发查看。
- 图中必须包含入口层、交易层、游戏层、数据层、消息层、后台统计层。
- 图中必须标明 PostgreSQL、Redis、Redpanda、ClickHouse、MinIO 的位置。
- 图中必须标明哪些服务在 K3s 中，哪些状态组件第一阶段部署在宿主机。

第一阶段部署架构图如下：

```mermaid
flowchart TD
    subgraph Host["一台服务器宿主机"]
        PG["PostgreSQL"]
        Redis["Redis"]
        MQ["Redpanda"]
        CH["ClickHouse"]
        MinIO["MinIO"]
        Monitor["Prometheus/Grafana/Loki"]
    end

    subgraph K3s["单节点 K3s / Kubernetes"]
        Ingress["Ingress 网关"]
        MG["merchant-gateway"]
        GG["game-gateway"]
        AG["admin-gateway"]
        Wallet["wallet-service"]
        Ledger["ledger-service"]
        Order["bet-order-service"]
        Settle["settlement-service"]
        Callback["callback-service"]
        Router["game-router"]
        Session["game-session-service"]
        Config["game-config-service"]
        Risk["risk-rtp-service"]
        Rank["ranking-service"]
        Chat["chat-service 后置按需"]
        Game1["game-pg-mahjong"]
        Game2["game-jili-superace"]
        Writer["warehouse-writer"]
        Report["report-service"]
    end

    Internet["商户/玩家/后台"] --> Ingress
    Ingress --> MG
    Ingress --> GG
    Ingress --> AG

    MG --> Wallet
    MG --> Order
    Wallet --> Ledger
    Order --> Settle
    Settle --> Wallet
    Settle --> Callback

    GG --> Session
    GG --> Router
    Router --> Game1
    Router --> Game2
    Game1 --> Config
    Game1 --> Risk
    Game2 --> Config
    Game2 --> Risk

    AG --> Report
    AG --> Config
    AG --> Risk

    Wallet --> PG
    Ledger --> PG
    Order --> PG
    Config --> PG
    Risk --> PG

    Session --> Redis
    Rank --> Redis
    Chat --> Redis
    Game1 --> Redis
    Game2 --> Redis

    Order --> MQ
    Wallet --> MQ
    Game1 --> MQ
    Game2 --> MQ
    Callback --> MQ
    MQ --> Writer
    Writer --> CH
    Report --> CH
    Config --> MinIO

    Monitor --> K3s
```

### 18.3 文档验收要求

后续每开发一个服务，必须同时交付：

```text
1. 服务中文文档
2. API 文档
3. 数据库表说明
4. Redis key 说明
5. 消息队列 topic 说明
6. 本地启动命令
7. Docker 构建命令
8. K8s 部署命令
9. 常见故障排查命令
10. 最小可运行验证命令
```

没有中文文档的服务，不允许进入正式联调。

## 19. Go 微服务开源架构选型要求

本项目的 Go 微服务架构不能闭门造车。所有核心框架、服务治理、代码结构、RPC、HTTP 网关、配置管理、日志、链路追踪、测试方式，都必须参考当前 GitHub 上成熟、活跃、生产级的开源项目。

选型原则：

- 优先选择 GitHub 活跃维护、社区成熟、生产案例多的开源项目。
- 优先选择高性能、低延迟、适合高并发游戏场景的 Go 框架。
- 优先选择云原生、Kubernetes 友好、可观测性完善的方案。
- 不使用长期无人维护、文档不完整、生态过小的冷门框架。
- 不为了追求“新”而牺牲稳定性。
- 每一个核心选型都必须写清楚 GitHub 地址、选择理由、替代方案、放弃原因。

### 19.1 当前推荐的 Go 技术底座

第一优先推荐使用 CloudWeGo 生态作为高并发 Go 微服务底座：

```text
HTTP 网关框架：CloudWeGo Hertz
内部 RPC 框架：CloudWeGo Kitex
网络库：CloudWeGo Netpoll
JSON 序列化：CloudWeGo Sonic
IDL：Protobuf / Thrift
内部通信：Kitex RPC / gRPC 兼容
```

推荐原因：

- Hertz 和 Kitex 都定位高性能微服务场景。
- Kitex 支持服务治理能力，包括服务发现、负载均衡、熔断、限流、重试、监控、链路追踪等扩展。
- Hertz 适合高并发 HTTP API 网关和外部接口。
- CloudWeGo 生态来自大规模生产实践，更适合游戏 API、商户 API、子游戏服务这种高 QPS 场景。
- 后续服务拆分、K8s 部署、服务治理可以统一在同一套生态中演进。

必须参考的开源项目：

```text
CloudWeGo Kitex
https://github.com/cloudwego/kitex

CloudWeGo Hertz
https://github.com/cloudwego/hertz

CloudWeGo 官方文档
https://www.cloudwego.io/
```

### 19.2 候选框架和取舍

除 CloudWeGo 外，还需要重点调研以下 Go 微服务框架：

```text
Kratos
https://github.com/go-kratos/kratos

go-zero
https://github.com/zeromicro/go-zero

Go Micro
https://github.com/micro/go-micro
```

取舍建议：

```text
CloudWeGo Hertz + Kitex
- 适合最高并发、低延迟、游戏主链路。
- 推荐作为本项目主选型。

Kratos
- 云原生微服务框架，工程结构清晰，适合后台、配置、报表等服务。
- 可作为备选方案或用于参考项目结构。

go-zero
- 工具链完整，脚手架效率高，适合快速生成 API/RPC 服务。
- 可参考其工程规范和代码生成方式。

Go Micro
- 抽象完整，内置服务发现、RPC、Pub/Sub。
- 但本项目更偏高性能游戏交易链路，第一优先级低于 CloudWeGo。
```

最终建议：

```text
主链路服务：CloudWeGo Hertz + Kitex
服务内部结构：Clean Architecture / Hexagonal Architecture
接口定义：Protobuf / Thrift
数据库访问：pgx / sqlc 优先，核心账本避免滥用重 ORM
事件通信：Redpanda Kafka 协议
链路追踪：OpenTelemetry
日志：zap 或 zerolog
配置：Viper + 环境变量 + K8s ConfigMap/Secret
```

### 19.3 服务内部代码结构要求

每个 Go 服务内部必须采用清晰的分层结构，推荐 Clean Architecture 或 Hexagonal Architecture。

推荐目录结构：

```text
service-name/
├── cmd/
│   └── service-name/
│       └── main.go
├── api/
│   ├── proto/
│   └── openapi/
├── internal/
│   ├── domain/
│   ├── usecase/
│   ├── adapter/
│   │   ├── http/
│   │   ├── grpc/
│   │   ├── repository/
│   │   └── messaging/
│   ├── infrastructure/
│   │   ├── postgres/
│   │   ├── redis/
│   │   ├── kafka/
│   │   └── config/
│   └── bootstrap/
├── deploy/
│   └── k8s/
├── docs/
├── test/
├── Dockerfile
├── Makefile
└── README.md
```

分层规则：

- domain 层只放业务实体、领域规则、领域错误。
- usecase 层编排业务流程。
- adapter 层负责 HTTP、gRPC、Repository、消息队列适配。
- infrastructure 层负责具体技术实现。
- domain 不允许依赖数据库、Redis、Kafka、HTTP 框架。
- 核心业务逻辑必须能脱离外部组件做单元测试。

可参考的开源模板：

```text
evrone/go-clean-template
https://github.com/evrone/go-clean-template
```

### 19.4 每次技术选型必须形成记录

后续每次选型都必须在文档中记录。

记录格式：

```text
选型名称：
用途：
GitHub 地址：
官方文档：
当前 Star/Fork/Release 情况：
最近更新时间：
选择理由：
替代方案：
放弃替代方案原因：
风险：
验证 Demo：
最终结论：
```

示例：

```text
选型名称：CloudWeGo Kitex
用途：内部高性能 RPC
GitHub 地址：https://github.com/cloudwego/kitex
选择理由：高性能、服务治理能力完整、适合 Go 微服务内部通信
替代方案：Kratos、go-zero、Go Micro、原生 gRPC
风险：团队需要学习 Kitex/IDL/治理扩展
最终结论：主链路内部 RPC 优先采用 Kitex
```

### 19.5 架构演进要求

第一阶段可以先用少量服务验证闭环，但技术选型不能写死成单机方案。

必须保证：

- 单机 K3s 可以跑。
- 多节点 K8s 可以平滑扩展。
- 服务发现、负载均衡、限流、熔断、追踪从第一阶段就留接口。
- 子游戏服务可以独立扩容。
- 框架选型支持高并发 HTTP 和高性能 RPC。
- 后续能接入 Service Mesh，但第一阶段不强制引入 Istio，避免运维复杂度过高。

## 20. 最终推荐技术栈

```text
后端语言：Go
部署：K3s / Kubernetes
HTTP 框架：CloudWeGo Hertz
内部 RPC 框架：CloudWeGo Kitex
服务内部架构：Clean Architecture / Hexagonal Architecture
接口定义：Protobuf / Thrift
交易数据库：PostgreSQL
缓存和实时状态：Redis
消息队列：Redpanda
数仓：ClickHouse
对象存储：MinIO
网关入口：Nginx Ingress 或 Traefik
监控：Prometheus + Grafana
日志：Loki
链路追踪：Tempo 或 Jaeger
配置格式：JSON / Protobuf / MessagePack
内部通信：gRPC
外部接口：HTTP REST / OpenAPI
实时通信：WebSocket
```

## 21. 结论

本架构第一阶段可以在一台服务器上部署，但服务边界、数据流、配置方式、K8s 部署方式都按未来高并发和多机扩展设计。

核心设计判断：

- 商户 API、游戏 API、后台 API 必须分离。
- 钱包账本必须强一致，所有账变不可变追加。
- 游戏返奖主路径必须走内存计算，不能每局查数据库。
- 采集的 slots 数据应进入配置中心和对象存储，按版本发布。
- 注单和账本必须用状态机和幂等保护。
- 玩家超时不代表下注失败，必须支持未展示结果恢复。
- 总后台统计必须查 ClickHouse 数仓，不能压交易主库。
- 每个子游戏独立 Deployment，支持按游戏独立扩容。
- 第一版先跑通一个 slots 游戏闭环，再扩展更多游戏。
