BeeX 架构与部署 · 对齐稿

v0.1 · 2026-06-05 · 基于 id-test 真实环境梳理 · 用于团队对齐

一、两个维度:国家 × 环境

BeeX 按 国家(country)环境(env) 两个维度切分,域名约定 {服务}-{国家}-{环境}.beexofficial.com。每个格子是一套独立的栈。

testprod
印尼 IDid-test 已上线id 待上线
马来 MYmy-test 规划中my 规划中

例:api-id-test / h5-id-test / admin-id-test / admin-api-id-test。当前真正运行的只有 id-test 一套。

二、单套栈架构图(以 id-test 为例)

全部组件在 Jakarta(ap-southeast-5)。C 端走 CDN+core API,运营走 admin 前端+admin 后端;core 与 admin 后端是两台独立 ECS,但共用同一套 id-test 库

图 1 · id-test 单套栈
flowchart TB
  subgraph U["用户侧"]
    direction LR
    H5B["浏览器 H5"]
    APP["Flutter App
WebView 载 H5
离线包 / 在线"] OPS["运营 / 管理员"] end subgraph EDGE["CDN / OSS · 静态资源"] direction LR H5CDN["h5-id-test
OSS: beex-id-test-h5"] ADCDN["admin-id-test
React · 一套按 env 切换"] end subgraph JKT["ECS + 数据 · Jakarta ap-southeast-5"] CORE["core 服务
api-id-test · :7002"] ADBE["admin 后端
admin-api-id-test · :7003"] DB[("MySQL RDS
seahub_x_id_test")] RDS[("Redis")] end H5B --> H5CDN APP --> H5CDN OPS --> ADCDN H5B -->|"API (HTTPS)"| CORE APP -->|"API (HTTPS)"| CORE ADCDN -->|"API"| ADBE ADBE -->|"提现审批代理
X-ADMIN-TOKEN"| CORE CORE --> DB CORE --> RDS ADBE --> DB classDef store fill:#fff7d6,stroke:#e6c200; class DB,RDS store;
已核实admin 后端 health 实测 db id-test0 + redis 都 UP,且我的 admin 接口能读到 core 建表/种子的 rebate_fund_config → 两服务确为同一套库。建表/种子在服务启动时 @PostConstruct 自动跑。

三、组件清单(均已核实)

组件仓库技术跑在哪域名部署
H5(C端)beex-app-h5Nuxt3 静态OSS+CDNh5-id-test云效 4987658 → OSS/CDN
原生 Appseahub-x-appFlutter应用商店WebView 载 H5(离线包从 OSS / 在线 CDN)
core 服务seahub-x-serviceSpring Boot :7002ECS #1api-id-test云效 4914249 · VMDeploy(push 自动)
admin 前端seahub-x-adminReact/Vite 静态OSS+CDNadmin-id-test云效 4938728 → OSS/CDN(push 自动)
admin 后端seahub-x-service
(admin-bootstrap)
Spring Boot :7003ECS #2 独立admin-api-id-test云效 5018487(今天新建 · ssh 发 jar)
数据MySQL RDS + RedisJakarta服务启动自动建表

四、CI/CD 流水线(云效 Yunxiao)

源码 GitHub(chaokongzwp),企业 ID 69f064d1…。5 条流水线对应不同部署目标:静态走 OSS/CDN、core 走 VMDeploy 机器组、admin 后端走 ssh 发 jar。

图 2 · 流水线 → 部署目标
flowchart LR
  subgraph GH["GitHub"]
    R1["beex-app-h5"]
    R2["seahub-x-service"]
    R3["seahub-x-admin"]
  end
  subgraph YX["云效流水线"]
    P2["4987658
h5 OSS/CDN"] P1["4914249
core · VMDeploy"] P3["4938728
admin 前端"] P4["5018487
admin 后端 · ssh"] end subgraph TGT["部署目标"] T1["OSS+CDN
h5-id-test"] T2["ECS#1
api-id-test"] T3["OSS+CDN
admin-id-test"] T4["ECS#2
admin-api-id-test"] end R1 --> P2 --> T1 R2 --> P1 --> T2 R3 --> P3 --> T3 R2 --> P4 --> T4
两点待清理(admin 后端那条)① ECS 密码当前内联在流水线 YAML(明文)→ 建议挪进加密变量组;② API 新建的流水线 GitHub webhook 未自动装 → push 暂不自动触发,需控制台「流水线源」重存一次。

五、提现请求时序(端到端)

提现审批:H5 申请 → core 冻结余额 → 运营在 admin 审批(经 admin 后端代理,带 X-ADMIN-TOKEN 调 core)→ core 发起 Xendit 出款 → Xendit 回调结算。

图 3 · 提现时序
sequenceDiagram
  autonumber
  participant U as 用户 (H5)
  participant C as core 服务
  participant A as admin 后端
  participant X as Xendit
  U->>C: 申请提现 apply(选银行/钱包账户)
  C->>C: 冻结余额, 状态 REQUESTED
  A->>C: 审批通过 approve (X-ADMIN-TOKEN)
  C->>X: 发起出款 disbursement
  C-->>A: 状态 PROCESSING
  X-->>C: 回调 webhook (COMPLETED / FAILED)
  C->>C: 成功→扣冻结·PAID / 失败→解冻退回·FAILED
        

六、多国家架构 —— 已定:A 独立栈

✅ 已拍板(2026-06-05)一个国家 = 一套独立 ECS + DB + Redis,硬隔离、互不干扰(路线 A)。admin 前端是一套,靠 env 切换按钮决定后面走哪个国家的后端(一对多前端 → 各国独立后端)。第一阶段做印尼,马来为未来规划,接 MY 时复制一套独立栈即可。下面 A/B 对比保留作背景参考。

路线 A · 每国一套独立栈

按域名约定推断的方向:复制一套栈,独立库(ID 数据与 MY 数据物理隔离,利于数据合规),admin 前端复用一套(已有 env 切换器)。

图 4 · 路线 A(独立栈)
flowchart TB
  ADFE["admin 前端(一套)
env 切换器: id-test / id / my-test / my"] subgraph IDS["印尼栈 · Jakarta"] IDBE["core + admin 后端
api-id-test / admin-api-id-test"] IDDB[("seahub_x_id_test")] end subgraph MYS["马来栈 · 新加坡/吉隆坡"] MYBE["core + admin 后端
api-my-test / admin-api-my-test"] MYDB[("seahub_x_my_test")] end ADFE -.->|切 ID| IDBE ADFE -.->|切 MY| MYBE IDBE --> IDDB MYBE --> MYDB classDef store fill:#fff7d6,stroke:#e6c200; class IDDB,MYDB store;

路线 B · 一套后端多国共服(country_code 区分)

同一套服务 + 同一个库,按 country_code 区分。现状种子已同时塞 ID+MY 两国数据,说明代码本就按 B 写的;但 ID/MY 数据同库,印尼数据本地化合规可能有问题。

图 5 · 路线 B(单后端 country_code)
flowchart TB
  ADFE["admin 前端"]
  subgraph ONE["一套后端"]
    BE["core + admin 后端"]
    DB[("一个库
ID + MY 同库
按 country_code 区分")] end ADFE --> BE BE --> DB classDef store fill:#fff7d6,stroke:#e6c200; class DB store;
A 独立栈
数据物理隔离(合规友好)
故障/容量互不影响
运维成本翻倍(多套 ECS/DB/流水线)
B 单后端
运维成本低、代码现成
ID/MY 同库,合规风险
单点影响多国

结论(已定):走 A。决定因素是合规(碰钱+实名,印尼/马来数据本地化)与故障隔离。关键澄清:A ≠ 重写代码 —— 同一套代码部署多次 + 每国独立库,代价是运维(多套 ECS/DB),不是开发。接 MY 是选 A 最便宜的时机(MY 库空,零迁移)。

七、待对齐的决策清单

#问题现状需决定
1MY 走 A(独立栈)还是 B(单后端 country_code)已定:A 一国一套 ECS/DB/Redis 隔离—— 已拍板
2admin 鉴权(前端一套按 env 切换,门必须在后端)现状:零鉴权·公网裸奔(实测外网可读用户 PII)已定方向:飞书 SSO + 后端 RBAC · 开发阶段暂缓,接真实用户/上 prod 前必补
3admin 后端 ssh 部署 + 密码内联新建流水线临时方案挪进加密变量组 / 改 VMDeploy
4admin 后端 ECS 与 core 分离两台独立 ECS,同库是否合并 / 是否同区

本页是「单 HTML + Mermaid」效果预览。满意的话下一步搭 VitePress 文档站(可搜索/导航/暗色,发到 docs-id-test),把 PRD / 参数配置 / 提现流程都迁进去。