BeeX ID 生产环境资源架构与成本规划
范围: 印尼生产环境 id-prod · 状态: 已部署上线 · 多可用区
计费方式
生产全部包年包月(锁价至 2031-07)
1. 结论
生产环境不要沿用 id-test 单机部署。
第一版采用独立生产资源 + 公网 ALB + 按服务进程拆分 + 生产 RDS/Redis/MQ + OSS/CDN + SLS/ARMS/CloudMonitor。先小规格多实例上线, 活动期临时按量扩容。
| 服务 | 是否独立 ECS | 第一版实例数 | 说明 |
beex-api | 是 | 2 | App/H5 用户主链路, 必须双实例。 |
beex-wa-service | 是 | 2 | WhatsApp 登录、消息、客服、裂变入口。 |
beex-worker | 是 | 2 | 与 beex-webhook 混部在 2 台 ECS, 做订单同步、分佣、结算、通知、券发放。定时任务通过分布式锁保证同一窗口只执行一次。 |
beex-webhook | 是 | 2 | 与 beex-worker 混部在 2 台 ECS, 承接 Xendit/TikTok/Shopee/飞书等非 WA 第三方回调。 |
beex-admin-api | 是 | 1 | 管理后台内部服务, 独立 2C2G 起步。 |
这不是最终高峰架构, 而是第一版生产基线。活动期通过按量 ECS 快速扩容, 活动后释放。
测试环境按同构低配建设
测试环境不复制生产容量, 但复制服务拆分、域名路由、数据隔离和第三方回调链路。上线前再临时扩成生产同构, 作为线上预演环境。
2. 当前阿里云资源与部署现状
核对时间: 2026-07-23(直接查阿里云账号 DescribeInstances / DescribeDBInstances / DescribeDBInstanceAttribute 复核), 地域 ap-southeast-5。生产 C 端业务与测试环境已完全隔离, 不共用 RDS/Redis/ECS。
本次复核相对 07-17 的三处变化:①生产 ECS/RDS/Redis 已由按量付费转为包年包月(锁价至 2031-07);②只读库已购 1 台标准只读副本(rr-k1a2236tll31wgf6y),但应用侧 SEAHUB_DB_READONLY_URL 仍为空、读流量暂时仍全走主库,尚未接入;③另有一台 07-17 误购的分析型只读(myduckro,曾开每月自动续)已于 07-23 退订释放。
2.1 生产环境 id-prod
| 类型 | 资源 | 规格 | 计费方式 | 可用区 |
| ECS | id-prod-api-a / id-prod-api-c | ecs.u1-c1m2.large 2C4G ×2, 角色 API, 端口 7002 | 包年包月(至2031-07) | 5a / 5c |
| ECS | id-prod-worker-a / id-prod-worker-c | ecs.u1-c1m2.large 2C4G ×2, 角色 WORKER, 端口 7020 | 包年包月(至2031-07) | 5a / 5c |
| ECS | id-prod-edge-a / id-prod-edge-c | ecs.u1-c1m2.large 2C4G ×2, 同机跑 seahub-x-wa(7010) + seahub-x-webhook(7030) 两个独立进程 | 包年包月(至2031-07) | 5a / 5c |
| ECS | id-prod-admin-c | ecs.e-c1m1.large 2C2G ×1, seahub-x-admin, 端口 7003 | 包年包月(至2031-07) | 5c |
| ECS(运维) | beex-id-ops-ai-01 | ecs.u1-c1m2.large 2C4G ×1, 自愈 watchdog / Uptime Kuma / 飞书告警桥, 非业务链路 | 包年包月(至2029-06) | 5c |
| RDS | id-prod-mysql (rm-k1afrpwr336b1o7r6) | MySQL 8.0 高可用 mysql.x2.medium.2c, 100G ESSD | 包年包月(至2031-07) | 主 5a / 备 5c |
| 只读库 | id-prod-mysql-readonly (rr-k1a2236tll31wgf6y) | mysqlro.n2.medium.1c 2C4G, 100G ESSD, 挂主库 rm-k1afrpwr336b1o7r6。已购但应用未接入(SEAHUB_DB_READONLY_URL 为空, 读仍全走主库) | 包年包月(至2031-07) | 5a |
| Redis | id-prod-redis-ha | redis.master.small.default, 1G, 主备 | 包年包月 | 主 5a / 备 5c |
| ALB | id-prod-alb | 公网 ALB | 已创建 | - |
| NAT Gateway | id-prod-nat | - | 已创建 | - |
| RocketMQ | - | - | 未购买 | - |
| OSS/CDN | 生产 H5、离线包、图片、日志包等 bucket | 已有 | 按量 | - |
2.2 测试环境 id-test(全部已包年包月锁价)
| 类型 | 资源 | 规格 | 计费方式 |
| ECS | beex-id-test-service | ecs.u1-c1m4.large 2C8G, 同机跑 beex-api、beex-wa-service、beex-worker、beex-webhook、beex-admin-service 五个独立进程(端口 7002/7010/7020/7030/7003) | 包年包月(已买 5 年) |
| ECS | id-test | ecs.e-c1m1.large 2C2G | 包年包月 |
| ECS | admin | ecs.e-c1m1.large 2C2G, SSO/证书续期/回滚兜底 | 包年包月 |
| RDS | x-test | mysql.n1e.small.1 | 包年包月(已买 5 年) |
| Redis | beex-id-shared-redis | redis.shard.small.2.ce, 1G | 包年包月(已买 5 年) |
2.3 域名对应
| 域名 | 环境 | 承载 |
api-id.beexofficial.com | 生产 | ALB → id-prod-api-a / id-prod-api-c |
admin-api-id.beexofficial.com | 生产 | id-prod-admin-c |
h5-id.beexofficial.com | 生产 | OSS/CDN |
sso.beexofficial.com | 统一 | beex-sso 服务 |
admin.beexofficial.com | 统一 | 管理后台前端 OSS/CDN |
api-id-test.beexofficial.com | 测试 | beex-id-test-service:7002 |
admin-api-id-test.beexofficial.com | 测试 | beex-id-test-service:7003 |
h5-id-test.beexofficial.com | 测试 | OSS/CDN |
2.4 容量实测(压测, 详见 LOADTEST.md)
| 路径 | 吞吐 | 瓶颈 |
| 读(2 节点) | 8,016/s · p95 65ms | api CPU(可弹性伸缩) |
| 简单写(2 节点) | 4,062/s · p95 71ms | RDS |
| 充值 create(单节点) | 1,398/s | api CPU |
| 提现 apply(单节点) | 22.8/s | BCrypt 支付密码(随 api 扩) |
结论: 当前规格远超印尼早期真实量; 读/计算可弹性伸缩, RDS 写入是终极天花板(扩容阶梯见 rds-scaling-roadmap.html)。
3. 生产目标架构图
生产环境每个国家独立部署。下面是印尼生产环境 id-prod 的第一版目标拓扑。
图 1 · BeeX ID 生产目标拓扑
flowchart TD
subgraph Client["用户端 / 外部平台"]
App["BeeX App / H5"]
WAUser["WhatsApp 用户"]
Xendit["Xendit"]
Tiktok["TikTok Shop"]
Shopee["Shopee"]
Feishu["飞书"]
end
subgraph Static["静态资源层"]
CDN["CDN"]
OSS["OSS
H5 / 离线包 / 图片 / 日志包"]
CDN --> OSS
end
subgraph Entry["公网入口层"]
DNS["DNS
beexofficial.com"]
ALB["公网 ALB
HTTPS / 路由 / 健康检查"]
end
subgraph Service["业务服务层 - ECS"]
API1["beex-api-01
2C4G"]
API2["beex-api-02
2C4G"]
WA1["beex-wa-service-01
2C4G"]
WA2["beex-wa-service-02
2C4G"]
Mix1["worker-webhook-01
beex-worker + beex-webhook
2C4G"]
Mix2["worker-webhook-02
beex-worker + beex-webhook
2C4G"]
Admin1["beex-admin-api-01
2C2G"]
end
subgraph Data["数据与中间件"]
RDS["RDS MySQL 主库
正式写库"]
RDSRO["RDS 只读实例
后台 / 报表查询"]
Redis["Redis 主备
缓存 / 登录态 / 验证码 / 锁 / 幂等"]
MQ["RocketMQ
异步消息 / 削峰"]
end
subgraph Obs["监控与日志"]
SLS["SLS 日志"]
ARMS["ARMS APM"]
Monitor["CloudMonitor + 飞书告警"]
end
App --> CDN
App --> DNS
WAUser --> DNS
Xendit --> DNS
Tiktok --> DNS
Shopee --> DNS
Feishu --> DNS
DNS --> ALB
ALB -->|"/api/**"| API1
ALB -->|"/api/**"| API2
ALB -->|"/webhooks/whatsapp"| WA1
ALB -->|"/webhooks/whatsapp"| WA2
ALB -->|"/webhooks/xendit/** / tiktok/** / shopee/** / feishu/**"| Mix1
ALB -->|"/webhooks/xendit/** / tiktok/** / shopee/** / feishu/**"| Mix2
ALB -->|"/admin/**"| Admin1
API1 --> RDS
API2 --> RDS
API1 --> Redis
API2 --> Redis
API1 --> MQ
API2 --> MQ
WA1 --> RDS
WA2 --> RDS
WA1 --> Redis
WA2 --> Redis
WA1 --> MQ
WA2 --> MQ
Mix1 --> RDS
Mix1 --> Redis
Mix1 --> MQ
Mix2 --> RDS
Mix2 --> Redis
Mix2 --> MQ
Admin1 --> RDSRO
Admin1 --> RDS
Admin1 --> Redis
RDS --> RDSRO
API1 --> SLS
API2 --> SLS
WA1 --> SLS
WA2 --> SLS
Mix1 --> SLS
Mix2 --> SLS
Admin1 --> SLS
API1 --> ARMS
API2 --> ARMS
WA1 --> ARMS
WA2 --> ARMS
Mix1 --> ARMS
Mix2 --> ARMS
Admin1 --> ARMS
SLS --> Monitor
ARMS --> Monitor
4. 测试环境与线上预演架构
测试环境的目标不是承载真实用户高峰, 而是验证服务拆分、域名路由、HTTPS、Webhook、第三方授权、分佣、钱包、发布回滚和告警链路。原则是 架构同构、容量缩小、凭证隔离、数据隔离。
4.1 常态测试环境
beex-id-test-service 2C8G 运行 beex-api、beex-wa-service、beex-worker、beex-webhook、beex-admin-service 五个独立进程; admin ECS 保留 SSO、证书续期、回滚兜底; id-test ECS 空闲。正式管理后台后端使用独立生产资源 id-prod-admin-c,不接入测试 ECS、RDS 或 Redis。下一步可再新增 1 台 2C8G,与当前 2C8G 组成测试双节点,再接测试 ALB。
图 2 · ID 测试环境常态部署拓扑
flowchart TD
subgraph Client["测试用户 / 三方测试平台"]
App["BeeX App
88.88.88 调试版本"]
WA["WhatsApp 测试号"]
Xendit["Xendit Sandbox"]
Tiktok["TikTok / Shopee 测试或低风险账号"]
Feishu["飞书测试群"]
end
subgraph Static["测试静态资源"]
H5["h5-id-test.beexofficial.com"]
OSS["beex-id-test-h5
H5 / 离线包 / 图片 / 日志包"]
H5 --> OSS
end
subgraph Entry["测试入口"]
ALB["测试 ALB
api-id-test.beexofficial.com"]
end
subgraph Service["测试服务层 - 当前建议"]
Node1["beex-id-test-service
2C8G
api + wa + worker + webhook + admin-api"]
Node2["test-biz-02
2C8G
api + wa + worker + webhook
下一步新增"]
Admin["admin ECS
2C2G
sso + rollback"]
end
subgraph Data["测试数据层"]
RDS["RDS MySQL Test
测试库 + admin 独立库"]
Redis["Redis Test
测试 DB + admin 独立 DB"]
MQ["RocketMQ Test
可先低配或按需打开"]
end
App --> H5
App --> ALB
WA --> ALB
Xendit --> ALB
Tiktok --> ALB
Feishu --> ALB
ALB -->|"/api/**"| Node1
ALB -->|"/api/**"| Node2
ALB -->|"/webhooks/whatsapp"| Node1
ALB -->|"/webhooks/whatsapp"| Node2
ALB -->|"/webhooks/xendit/** / tiktok/** / shopee/** / feishu/**"| Node1
ALB -->|"/webhooks/xendit/** / tiktok/** / shopee/** / feishu/**"| Node2
ALB -->|"/admin/**"| Node1
Node1 --> RDS
Node2 --> RDS
Admin --> RDS
Node1 --> Redis
Node2 --> Redis
Admin --> Redis
Node1 --> MQ
Node2 --> MQ
| 模块 | 常态测试配置 | 说明 |
beex-id-test-service | 已购 1 台 2C8G | 当前同机跑 beex-api、beex-wa-service、beex-worker、beex-webhook、beex-admin-service 五个独立进程。 |
test-biz-02 | 下一步新增 1 台 2C8G | 与 beex-id-test-service 对等承载 C 端核心进程, 用于验证双节点、滚动发布、worker 抢锁和故障切换。 |
beex-admin-api-test | 当前放在 beex-id-test-service | 管理后台后端低并发, 测试环境可与业务服务同机; 旧 admin ECS 暂留回滚兜底。 |
beex-admin-api-id-prod | id-prod-admin-c 2C2G | 独立生产管理后台后端;不使用测试 ECS、RDS 或 Redis。 |
| RDS Test | 独立测试实例, 1C1G 起 | 只承载测试业务和测试管理后台数据,不允许生产服务接入。 |
| Redis Test | 独立测试实例, 1G 起 | 只承载测试环境缓存,不允许生产服务接入。 |
| ALB Test | 建议新增 1 个测试 ALB | 路由结构要和生产一致; 如果短期省钱, 可临时用 Nginx, 但上线预演必须走 ALB。 |
| OSS/CDN Test | 独立 bucket/domain | H5、离线包、图片、日志包和生产隔离。 |
| SLS/ARMS Test | 独立 project 或 test logstore | 日志和生产隔离。 |
常态测试也应该具备双业务节点
它可以不是生产容量, 但要能提前验证多实例部署、worker 抢锁、webhook 幂等、滚动发布和单机故障。
4.2 临时扩成线上预演环境
上线前、活动前或大版本发布前, 把测试环境临时扩成生产同构模式。预演通过后允许生产发布, 预演结束释放临时 ECS。
图 3 · 测试环境扩容为线上预演
flowchart LR
Normal["常态测试
test-biz x2
admin-test x1"] --> Expand["容量预演
临时增加生产拆分节点
api x2
wa x2
worker-webhook x2"]
Expand --> Rehearsal["线上预演
ALB 多实例路由
滚动发布
Worker 抢锁
Webhook 幂等
全链路回归"]
Rehearsal --> Decision{"结果是否通过"}
Decision -->|通过| Release["允许生产发布"]
Decision -->|不通过| Fix["修复后重新预演"]
Release --> Shrink["预演结束
释放临时容量节点
回到常态测试"]
Fix --> Expand
| 模块 | 预演配置 | 用途 |
test-biz | 2 台 2C8G | 常态即保持双节点, 每台跑 API/WA/worker/webhook。 |
beex-admin-api-test | 1 台 | 管理后台低并发, 不需要双实例。 |
| RDS/Redis/MQ | 继续使用测试实例 | 预演验证拓扑即可; 如做压测再临时升配。 |
预演规格选择
验证拓扑、发布、幂等时, 2 台 2C8G 测试业务节点即可; 验证容量或压测时, 临时按生产拆分方式新增 2C4G 节点, 或把测试节点挂更多副本。
4.3 预演必须覆盖的场景
| 场景 | 验证点 |
| ALB 多实例路由 | 任意摘除一台 API/WA/worker-webhook 节点, 流量仍可用。 |
| 滚动发布 | 先发布一台, 健康检查通过后再发布下一台。失败时能回滚。 |
| Worker 双实例 | 两台 worker 同时触发定时任务, 只有一台抢到锁并执行。 |
| 订单同步幂等 | 同一订单重复拉取不会重复入库、重复分佣、重复入账。 |
| Webhook 幂等 | Xendit/TikTok/Shopee/飞书重复回调不会重复处理。 |
| WhatsApp 登录 | 用户发登录码后, 双实例下也能正确完成登录态。 |
| H5/离线包 | 测试包、正式包、回滚包都能被 App 正确识别和切换。 |
| 告警 | 故意制造 5xx、worker 失败、MQ 堆积, 飞书能收到告警。 |
4.4 测试和生产的隔离要求
| 类型 | 测试环境 | 生产环境 |
| 域名 | api-id-test.beexofficial.com, h5-id-test.beexofficial.com, admin-api-id-test.beexofficial.com | api-id.beexofficial.com, h5-id.beexofficial.com, admin-api-id.beexofficial.com |
| 数据库 | 测试 RDS / 测试 schema,只允许测试服务接入 | 生产 RDS / 生产 schema,只允许生产服务接入 |
| Redis | 测试 Redis, key 前缀 beex:id:test:* | 生产 Redis, key 前缀 beex:id:prod:* |
| OSS/CDN | beex-id-test-* | beex-id-prod-* |
| WhatsApp | 测试 WABA/测试号码或测试专用号码 | 正式 WABA/正式号码 |
| Xendit | Sandbox key + test webhook | Live key + prod webhook |
| TikTok/Shopee | 测试/低风险授权账号 | 正式授权账号 |
| 飞书 | 测试群机器人 | 生产告警群机器人 |
隔离边界
测试与生产只共用阿里云账号层面的管理能力;ECS、RDS、Redis、OSS、日志、第三方凭证和回调路由必须按环境隔离。管理后台属于生产系统的一部分,同样不得复用测试数据层。
5. 每类资源怎么使用
| 资源 | 使用方式 |
| VPC | 印尼生产环境私有网络。ECS、RDS、Redis、MQ 都放同一个 VPC 内, 使用内网互通。 |
| VSwitch | 至少 2 个可用区, 例如 ap-southeast-5a、ap-southeast-5c。跨可用区仍走同 VPC 内网, 不走公网。 |
| 公网 ALB | api-id.beexofficial.com 的统一公网入口, 承担 HTTPS、路径路由、健康检查、负载均衡。 |
| NAT Gateway + EIP | ECS 不直接挂公网 IP。ECS 访问 TikTok、Shopee、Meta、Xendit 统一从 NAT 出口出去。三方若要 IP 白名单, 填 NAT EIP。 |
ECS beex-api | 用户实时接口: 登录结果查询、首页、搜索、商品解析、转链、钱包、我的页面。 |
ECS beex-wa-service | WhatsApp 通道服务: WA webhook、登录码、商品链接、ORDERS/WALLET 指令、客服会话、出站消息。 |
ECS worker-webhook 混部节点 | 2 台 ECS, 每台同时跑 beex-worker 与 beex-webhook 两个独立进程。Webhook 经 ALB 双实例承接回调; Worker 定时任务通过分布式锁抢占执行权, 再用幂等 key 和唯一约束兜底, 避免重复拉取/重复入账。 |
ECS beex-admin-api | 管理后台接口。内部服务, 独立部署, 低并发, 第一版 2C2G 起步。 |
| RDS MySQL 主库 | 正式业务写库。存用户、关系树、订单、佣金、钱包、券、活动、WA 消息、配置版本。 |
| RDS 只读实例 | 管理后台、报表、列表查询、BI 查询优先走只读实例, 避免拖慢用户主链路。代码层已按“已有只读库”预留读写分离: 配置 SEAHUB_DB_READONLY_URL 后读请求自动走只读库; 不配置时自动回退主库。 |
| Redis 主备 | 登录态、验证码、WA login intent、分布式锁、幂等 key、首页/商品/活动配置缓存、限流计数。 |
| RocketMQ | 异步削峰。WA 入站消息、订单同步结果、佣金结算、钱包入账、通知发送等通过 MQ 解耦。 |
| OSS + CDN | H5 静态资源、App 离线包、用户头像、反馈日志 zip、蜜源圈图片、活动素材。 |
| SLS | 所有服务日志。建议按服务拆 logstore: beex-api-prod, beex-wa-prod, beex-worker-prod, beex-webhook-prod, beex-admin-prod。 |
| ARMS | Java APM。看接口耗时、错误率、慢 SQL、JVM、线程池、调用链。 |
| CloudMonitor | 监控 ECS、RDS、Redis、ALB、MQ、NAT, 告警到飞书群。 |
5.1 数据源路由边界
BeeX 的国家隔离是部署级隔离, 不是在同一个服务进程里根据请求动态切国家库。
| 场景 | 是否运行时路由 | 说明 |
| 国家 / 环境 | 否 | id-prod 服务进程只连印尼正式库; my-prod 服务进程只连马来正式库; id-test 服务进程只连印尼测试库。国家和环境由部署配置固定。 |
| 读写分离 | 是 | 同一国家、同一环境内, 写操作走主库, 查询/报表/后台列表优先走只读库。 |
| 未来单国分片 | 预留 | 如果印尼单国数据量非常大, 未来可在 id-prod 内按用户或关系树做分片, 但这不是第一版上线范围。 |
countryCode 在接口和表里的作用是业务自描述、审计、BI 汇总和排查, 不能作为当前服务切换国家数据库的依据。例如 api-id.beexofficial.com 收到 countryCode=MY 的请求时, 正确策略应该是拒绝或规范化校验, 而不是尝试连接马来数据库。
- 部署时通过环境变量固定主库:
SEAHUB_DB_URL / SEAHUB_DB_USERNAME / SEAHUB_DB_PASSWORD。
- 可选配置同环境只读库:
SEAHUB_DB_READONLY_URL / SEAHUB_DB_READONLY_USERNAME / SEAHUB_DB_READONLY_PASSWORD。
- 不配置只读库时, 只读路由自动回退主库, 保证测试环境和灰度环境可以先跑起来。
- 管理后台查询类接口已标记只读事务, 后续只读库填上后自动走只读库。
6. 域名与 ALB 路由
图 4 · ALB 路由拆分
flowchart LR
DNS["api-id.beexofficial.com"] --> ALB["公网 ALB"]
H5["h5-id.beexofficial.com"] --> CDN["CDN / OSS"]
AdminWeb["admin.beexofficial.com"] --> AdminCDN["管理后台 OSS/CDN"]
ALB --> Api["/api/**
beex-api x2"]
ALB --> WA["/webhooks/whatsapp
beex-wa-service x2"]
ALB --> Webhook["/webhooks/xendit/**
/webhooks/tiktok/**
/webhooks/shopee/**
/webhooks/feishu/**
beex-webhook x2
混部在 worker-webhook 节点"]
AdminApi["admin-api-id.beexofficial.com"] --> Admin["beex-admin-api"]
SSO["sso.beexofficial.com"] --> SSOService["SSO 服务"]
| 域名 / 路径 | 转发目标 |
h5-id.beexofficial.com | CDN / OSS, 印尼正式 H5 和离线包。 |
api-id.beexofficial.com/api/** | beex-api |
api-id.beexofficial.com/webhooks/whatsapp | beex-wa-service |
api-id.beexofficial.com/webhooks/xendit/** | beex-webhook x2, 混部在 worker-webhook 节点。 |
api-id.beexofficial.com/webhooks/tiktok/** | beex-webhook x2, 混部在 worker-webhook 节点。 |
api-id.beexofficial.com/webhooks/shopee/** | beex-webhook x2, 混部在 worker-webhook 节点。 |
api-id.beexofficial.com/webhooks/feishu/** | beex-webhook x2, 混部在 worker-webhook 节点。 |
admin-api-id.beexofficial.com/** | beex-admin-api |
admin.beexofficial.com | 管理后台前端 CDN/OSS。 |
sso.beexofficial.com | 管理后台统一登录服务。 |
ALB 的价值
一个域名后面挂多台 ECS; 按路径把流量分到不同服务; 统一管理 HTTPS 证书; 健康检查自动摘除异常实例; 活动时新增 ECS 后快速挂到后端服务组。
7. 服务部署数量
7.1 第一版生产基线
| 服务 | ECS 数量 | 起步配置 |
beex-api | 2 | 2C4G |
beex-wa-service | 2 | 2C4G |
beex-worker | 2 | 2C4G, 与 beex-webhook 混部。 |
beex-webhook | 2 | 2C4G, 与 beex-worker 混部。 |
beex-admin-api | 1 | 2C2G |
混部边界
用户主链路 beex-api、WhatsApp 主入口 beex-wa-service、管理后台 beex-admin-api 仍独立部署。beex-worker 与 beex-webhook 属于低并发/后台型服务, 可以在 2 台 2C4G ECS 上混部, 用较低成本换到双节点高可用。
7.2 Worker 双实例如何避免重复拉取
两台 worker-webhook ECS 都会启动 beex-worker 进程, 也都会触发定时器。真正执行任务前必须先抢分布式锁, 没抢到的实例直接跳过本轮。
图 5 · Worker 双实例定时任务抢锁
flowchart LR
T["定时触发
每 5/15 分钟"] --> W1["worker-01"]
T --> W2["worker-02"]
W1 --> L["Redis/DB 分布式锁
job:ID:TIKTOK_ORDER_SYNC:account"]
W2 --> L
L -->|抢到锁| Run["执行拉取
TikTok/Shopee 订单"]
L -->|没抢到| Skip["本轮 skip
只打日志/指标"]
Run --> Upsert["幂等写入
platform + order_id 唯一键"]
Upsert --> Reward["触发分佣/钱包/通知"]
| 措施 | 要求 |
| 锁粒度 | 按国家 + 平台 + 平台账号 + 任务类型拆锁, 例如 job:id:tiktok:cap_order_sync:{accountId}。不同平台账号可以并行, 同一账号同一窗口只能一个 worker 执行。 |
| 锁时长 | 锁过期时间必须大于任务最长预期执行时间, 例如任务正常 2 分钟, 锁设置 5-10 分钟; 长任务需要续租。 |
| 失败恢复 | worker 宕机后锁自动过期, 下一轮由另一台接管。不能使用永不过期锁。 |
| 幂等兜底 | 订单表用 platform + platform_order_id 唯一键; 佣金表用 order_id + reward_type + receiver_user_id 唯一键; 钱包流水用业务幂等 key。 |
| 可观测 | 记录 lock_acquired、lock_skipped、last_success_at、拉取数量、失败原因。超过一个周期没有成功执行要告警。 |
7.3 后续演进触发信号
| 触发信号 | 动作 |
| API p95 超过 800ms, 且不是三方接口慢 | beex-api 加实例或升 4C8G。 |
| WA 回复延迟超过 10-30 秒 | beex-wa-service 加实例。 |
| 订单同步延迟超过 15 分钟 | worker-webhook 混部节点加实例, 或单独拆出 beex-worker。 |
| Xendit/平台回调 5xx 或排队 | worker-webhook 混部节点加实例, 或单独拆出 beex-webhook。 |
| 管理后台慢查询影响主库 | 后台全部走只读库, 必要时增加只读实例。 |
| Redis 内存超过 70% | Redis 升 8G。 |
| RDS CPU 长期超过 60% 或慢 SQL 增多 | 优化索引/SQL, 必要时主库升 4C8G。 |
8. 活动临时扩容方案
平时按基础规格跑, 活动前 1-2 天临时扩容, 活动后释放按量资源。
图 6 · 活动扩容节奏
flowchart LR
Normal["平时
api x2
wa x2
worker-webhook x2
admin x1"] --> Before["活动前 1-2 天
api x4
wa x4
worker-webhook x4
admin x1"]
Before --> Day["活动当天
盯 p95/p99
WA 延迟
MQ 堆积
RDS/Redis
三方错误率"]
Day --> After["活动后
确认 MQ 追平
订单同步追平
佣金无异常
释放临时 ECS"]
| 阶段 | 建议配置 |
| 平时 | beex-api 2 台, beex-wa-service 2 台, worker-webhook 混部节点 2 台, beex-admin-api 1 台。 |
| 活动前 | beex-api 扩到 4 台, beex-wa-service 扩到 4 台, worker-webhook 混部节点扩到 4 台。 |
| 活动当天 | 重点看 API p95/p99、WA 延迟、MQ 堆积、RDS CPU/连接/慢 SQL、Redis 内存/命中率、三方接口错误率。 |
| 活动后 | 确认 MQ 无堆积、订单同步追平、佣金结算无异常, 再释放临时 ECS。 |
9. 成本清单
阿里云官方定价计算器实际查询结果, 地域 ap-southeast-5, 币种 CNY, 含 75 折参考列。生产环境已于 2026-07 由按量付费转为包年包月(锁价至 2031-07), 下表为 1/3/5 年报价, 数量按 §2.1 实测台数计算(2C4G ×6 + 2C2G ×1), 含只读库。
9.1 生产环境转包年包月报价
| 资源 | 规格 | 数量 | 状态 | 1年原价 | 3年原价 | 5年原价 | 1年×75% | 3年×75% | 5年×75% |
| 主数据库 | RDS mysql.x2.medium.2c, 100G, 高可用 | 1 | 已购·包年包月 | 8,064.00 | 15,552.00 | 17,280.00 | 6,048.00 | 11,664.00 | 12,960.00 |
| 只读数据库 | RDS mysql.x2.medium.2c, 100G, 高可用(实购 mysqlro.n2.medium.1c 2C4G 单节点, 成本低于此报价) | 1 | 已购(未接入) | 4,950.72 | 11,139.12 | 12,376.80 | 3,713.04 | 8,354.34 | 9,282.60 |
| Redis | 1G(id-prod-redis-ha) | 1 | 已购·包年包月 | 1,200.00 | 2,250.00 | 3,000.00 | 900.00 | 1,687.50 | 2,250.00 |
| ECS 单价 | 2C4G ecs.u1-c1m2.large | 单价 | - | 2,450.00 | 4,655.00 | 7,759.16 | 1,837.50 | 3,491.25 | 5,819.37 |
| ECS 小计 | 2C4G ×6(api/worker/edge) | 6 | 已购·包年包月 | 14,700.00 | 27,930.00 | 46,554.96 | 11,025.00 | 20,947.50 | 34,916.22 |
| ECS 单价 | 2C2G ecs.e-c1m1.large | 单价 | - | 1,457.00 | 2,674.00 | 3,880.00 | 1,092.75 | 2,005.50 | 2,910.00 |
| ECS 小计 | 2C2G ×1(admin) | 1 | 已购·包年包月 | 1,457.00 | 2,674.00 | 3,880.00 | 1,092.75 | 2,005.50 | 2,910.00 |
9.2 合计(含只读库)
| 周期 | 原价合计 | 75折合计 |
| 1 年 | 30,371.72 | 22,778.79 |
| 3 年 | 59,545.12 | 44,658.84 |
| 5 年 | 83,091.76 | 62,318.82 |
只读库单独增量成本
1 年 4,950.72(75折 3,713.04) / 3 年 11,139.12(75折 8,354.34) / 5 年 12,376.80(75折 9,282.60)。这是在"现状转包年包月"基础上, 新增只读库要多付的钱。
5 年期折扣提醒
RDS(主库/只读库)从 3 年买到 5 年, 折算到每年还能再省 33%; 2C4G 这台 ECS(占比最大)从 3 年到 5 年折算到每年基本没有再降价。RDS 建议买 5 年, 2C4G 这 6 台买 3 年即可, 5 年不会更便宜。
9.3 其它规格参考价(需要升配时用)
| 资源 | 月付 | 买 1 年 | 买 3 年 | 买 5 年 |
ECS 2C8G ecs.u1-c1m4.large + 80G | ¥413.32 | ¥2,975.91 | ¥5,654.22 | ¥9,423.71 |
RDS 高可用 4C8G/100G mysql.x2.large.2 | ¥3,139.00 | ¥26,367.60 | ¥50,851.80 | ¥56,502.00 |
Redis 主备 8G redis.basic.large.default | ¥350.00 | ¥3,360.00 | ¥6,300.00 | ¥8,400.00 |
10. 流量费用
流量费用是最大不确定项, 不适合写成固定月费。预算表必须单独列。
| 流量类型 | 是否收费 | 说明 |
| 用户访问 H5 / 图片 / 离线包 CDN | 是 | CDN 下行流量, 活动时明显上涨。 |
| 用户访问 API / Webhook | 是 | ALB LCU + 公网流量相关费用。 |
| ECS 访问 TikTok/Shopee/Meta/Xendit | 是 | NAT Gateway + EIP 出公网流量。 |
| OSS 存储和回源 | 是 | 图片、H5 包、离线包、日志包。 |
| SLS 日志写入和索引 | 是 | 日志量越大费用越高。 |
| 同 VPC 内 ECS/RDS/Redis 内网通信 | 通常不按公网收费 | 不走公网; 跨可用区可能有少量内网流量费。 |
CDN 流量估算
| CDN 月流量 | 费用估算 |
| 100GB | 约 ¥78 |
| 1TB | 约 ¥780 |
| 5TB | 约 ¥3,900 |
| 10TB | 约 ¥7,800 |
NAT 出公网流量估算
| NAT 出公网流量 | 费用估算 |
| 100GB | 约 ¥80-150 |
| 1TB | 约 ¥800-1,500 |
第一年度总预算口径
| 场景 | 预算口径 |
| 不含只读库 · 保守启动 | 基础资源买 1 年约 ¥30,185.94 + 低流量按量资源约 ¥12,000-24,000 / 年 = 约 ¥42,000-55,000 / 年。 |
| 不含只读库 · 正常推广 | 基础资源买 1 年约 ¥30,185.94 + 推广期按量资源约 ¥36,000-72,000 / 年 = 约 ¥66,000-103,000 / 年。 |
| 含只读库 · 正常推广 | 基础资源买 1 年约 ¥42,475.14 + 推广期按量资源 = 约 ¥78,000-115,000 / 年。 |
| 活动高峰月 | 按量资源可能到 ¥8,000-20,000+ / 月, 取决于 CDN 流量、SLS 日志量、NAT 出公网和临时 ECS 数量。 |
控制流量成本的优先级
H5 使用离线包; 静态资源文件名带 hash 并长缓存; 图片转 WebP; 首页、活动图、离线包提前预热 CDN; 商品详情尽量引用平台原图, 避免重复转存大图。
11. 第一批购买建议
| 资源 | 配置 |
ECS beex-api | 2 台 2C4G u1, 买 1 年。 |
ECS beex-wa-service | 2 台 2C4G u1, 买 1 年。 |
ECS worker-webhook 混部节点 | 2 台 2C4G u1, 每台同时跑 beex-worker 与 beex-webhook, 买 1 年。 |
ECS beex-admin-api | 1 台 2C2G e, 买 1 年。 |
| RDS 主库 | MySQL 8.0 高可用 2C4G/100G, 买 1 年。 |
| Redis | 主备 4G, 买 1 年。 |
| ALB | 公网标准版, 按量。 |
| NAT + EIP | 按量。 |
| RocketMQ | 托管版, 按量/基础规格。 |
| OSS/CDN | 按量 + 视情况买流量包。 |
| SLS/ARMS | 按量/套餐, 先开必要监控。 |
| 可选资源 | 建议 |
| RDS 只读库 | 如果管理后台报表、订单查询、BI 查询会频繁使用, 上线前加; 否则灰度阶段可暂缓。 |
| Redis 8G | 活动前或 Redis 内存超过 70% 时升。 |
| RDS 4C8G | 活动前压测确认主库压力后再升。 |
| 只读库配置项 | 说明 |
SEAHUB_DB_READONLY_URL | RDS 只读实例内网地址。为空时读请求仍走主库。 |
SEAHUB_DB_READONLY_USERNAME | 只读库账号。为空时复用主库账号。 |
SEAHUB_DB_READONLY_PASSWORD | 只读库密码。为空时复用主库密码。 |
SEAHUB_DB_READONLY_MAX_POOL_SIZE | 主业务只读连接池上限, 默认 5。 |
SEAHUB_ADMIN_DB_READONLY_MAX_POOL_SIZE | 管理后台只读连接池上限, 默认 5。 |
路由规则: 写入、订单同步、分佣、钱包、提现等资金相关操作始终走主库; 标记为只读事务的查询接口优先走只读库。当前管理后台概览、用户、订单、佣金、支付、提现、WA 消息、集成账号、风控事件、审计日志查询已按只读事务处理。如果只读库发生秒级延迟, 资金状态仍以主库为准, 用户关键链路不依赖只读库。
| 测试环境资源 | 建议 |
当前 admin ECS | 保留, 继续跑 beex-sso、证书续期、回滚兜底等内部服务; beex-admin-service 已迁到 2C8G 测试业务主机。 |
当前 id-test ECS | 从业务测试主入口迁出, 目前空闲; 正式管理后台后端 admin-api-id.beexofficial.com 实际用的是独立生产资源 id-prod-admin-c, 没有部署在这台上。 |
| 新增常态测试业务 ECS | 当前已购买 1 台 2C8G 并运行 beex-api、beex-wa-service、beex-worker、beex-webhook、beex-admin-service; 下一步再购买 1 台 2C8G 做双节点预演。 |
| 测试 ALB | 建议新增, 路由规则和生产保持一致, 域名使用 *-test。如果短期不用 ALB, 必须在上线预演前补上。 |
| 线上容量预演 ECS | 不长期购买, 活动前或正式发布前按量新增到生产拆分形态 api x2 + wa x2 + worker-webhook x2。 |
| 测试 RDS/Redis | 只承载测试业务与测试管理后台;所有生产服务使用独立生产 RDS/Redis。 |
| 测试三方凭证 | WhatsApp/Xendit/TikTok/Shopee/飞书全部和生产隔离。 |
12. 上线前必须具备的工程前提
服务能独立启动
beex-api、beex-wa-service、beex-worker、beex-webhook、beex-admin-api 能以不同 profile 独立启动。beex-worker 与 beex-webhook 可以混部, 但仍是两个独立进程。
Worker 幂等
Worker 任务必须有分布式锁、幂等和唯一约束, 避免多实例重复发佣金。
资金链路唯一键
订单、佣金、钱包流水必须有唯一键和幂等 key。
Redis key 带前缀
例如 beex:id:prod:api:*, 防止不同服务/环境互相污染。
管理后台鉴权和审计
管理后台写操作必须有服务端鉴权和审计。
正式凭证隔离
生产配置不能复用测试凭证, WhatsApp/TikTok/Shopee/Xendit 均要正式账号配置。
流水线可回滚
云效流水线要支持按服务部署、健康检查、失败回滚和飞书通知。
告警先上线
SLS/ARMS/CloudMonitor 告警先于正式推广上线。
测试环境先做线上预演
测试环境需要先从当前单体部署迁移到 2 台 test-biz 业务节点。正式发布前必须跑完 ALB 双实例、滚动发布、worker 抢锁、webhook 幂等、订单同步和钱包入账回归。
13. 后续目标态
| 组件 | 目标态 |
beex-api | 4-8 台。 |
beex-wa-service | 4-8 台。 |
worker-webhook 混部节点 | 3-6 台; 若某一侧压力明显更高, 再拆成独立机器组。 |
beex-admin-api | 1-2 台。 |
| RDS 主库 | 4C8G 或更高。 |
| RDS 只读库 | 1-2 台。 |
| Redis | 8G-16G。 |
| MQ | 按堆积和 TPS 扩。 |
不要把目标态当第一天购买清单。
第一版先买稳定基线, 活动用按量扩容。压测和真实流量回来后, 再决定哪些资源长期升配。