跳至主要内容

ADR 001 平台錢包是否需要單獨的伺服器

· 閱讀時間約 3 分鐘
Senior Engineer
  • Status: 📝Proposed
  • Maker: GameServer , Transaction Server Developer
  • Refs: none

Context

若平台採用 Single Wallet 架構,玩家所有資金最終都歸屬於平台錢包,而非遊戲內部帳戶。

在現行流程中,每一次下注(bet)前,GameServer 都必須向平台確認餘額是否足夠,並在下注成立時完成扣款或鎖款。

因此出現一個直觀的問題:「既然每次下注都要經過 GameServer,平台錢包是否可以直接掛載在 GameServer 上,而不需要一個獨立的 Wallet Server?」

危險

交易服務與 GameServer 即使在同一個主機上,我認為還是得 MUST DO 行程級別的隔離。

Options

  • 金流一致性是否可被遊戲邏輯影響
  • GameServer 的 scale in / out 行為
  • 失敗重試、補償、對帳需求
  • 平台是否需要跨多遊戲共享同一錢包
  • 未來是否支援非同步下注、回滾或爭議處理

錢包邏輯內嵌於 GameServer

做法是將錢包查詢與扣款邏輯,直接實作在 GameServer 中,由 GameServer 對平台 API 發送請求。

獨立 Wallet Server

平台錢包由一個獨立的 Wallet Server 管理,GameServer 只負責發送下注資訊,不持有最終資金狀態。

我們還是需要 Redis!

即使有 Bucket,交易還是得存入資料庫或是某個 Redis,Bucket 提供的是序列語意,消於看到同一個餘額的Race Condition。

資料庫/Redis 在這裡扮演的是持久性、可稽核性、恢復能力,也就是資料層。

原則上,Redis Cluster 可以替代 Bucket 的作法,但是我們還是得做其他的封裝。

即使 Game Server 同時更新 Redis + 發送一筆訊息到 MQ,但還是缺少一個聚合點。

對外我們顯示 Approve / Reject,但內部包含

  • 尚未開始
  • 扣款完成,但紀錄未完成(Redis 更新成功了,送入MQ失敗)
  • 紀錄完成,但扣款未完成(Redis 更新失敗了,送入MQ成功)
  • 兩者都完成

因此讀

Comparison

面向Wallet 作為 SDK 跟 GameServer 整合Wallet 作為 Service
平台選擇時機部署期決定,編譯或設定即固定部署期決定
平台整合責任平行於 GameServer 的 Process集中於 Wallet Service
呼叫路徑GameServer -> IPC -> PlatformGameServer -> Wallet -> Platform
Retry / TimeoutGameServer 內處理Wallet Service 統一處理
冪等性由 GameServer 負責可集中處理
對平台的保護分散在各 GameServer集中控管
憑證與金鑰管理分散在所有 GameServer集中於 Wallet Service
方便測試性質高,邊界少、路徑短中,高度依賴文件與紀律
初期實作成本最低較高
未來擴展性質受限於 GameServer 發佈節奏較高,但前提是確實需要

如果有跨遊戲或是對平台需要有統一性的操作:

  • 需要集中保護平台 QPS
  • 需要跨 GameServer 對帳與重放
  • 需要平台 API 變動時不重佈遊戲服務
  • 需要一個交易觀測與治理節點

我認為就有必要進一步討論,但是轉帳錢包應該得要是分開的伺服器。

Decision

討論中

Consequences

討論中