使用 AWS Serverless 架构构建新扑克变体
Source: Dev.to
我如何使用 AWS 无服务器基础设施设计并构建实时多人游戏平台
编码前的设计
在编写任何代码之前,我制作了一份 36 页的低层设计(LLD)文档。LLD 迫使我在一开始就考虑所有的边缘情况、状态转换和故障模式——这正是生产系统的构建方式。
按数字看
- 7 个 AWS 服务
- 8 个 DynamoDB 表
- 36 页 LLD
- 0 台服务器需要管理
Source:
架构概览
Point Game 是一个完全无服务器、事件驱动的系统。客户端使用 REST API 进行账户和桌子操作,使用 WebSocket 进行实时游戏。
基础设施概览
| 组件 | 技术 |
|---|---|
| CDN 与静态资源 | CloudFront + S3 |
| API 层 | API Gateway(REST + WebSocket) |
| 计算 | AWS Lambda |
| 数据库 | DynamoDB |
| 认证 | Cognito |
| 调度 | EventBridge |
关键洞察:DynamoDB 是唯一的真相来源。所有游戏状态、操作日志和连接映射都存放在 DynamoDB 中。Lambda 函数是无状态的——它们读取状态、处理操作、写入状态并进行广播。这使得系统能够水平扩展并对故障具有弹性。
Client Action → API Gateway → Lambda → DynamoDB → Broadcast
数据模型
| 表格 | 用途 |
|---|---|
| Game State | 当前手牌状态、座位、奖池、棋盘 |
| Action Log | 只追加的每个操作记录 |
| Hand Snapshots | 手牌结束时的状态快照,用于回放/审计 |
| Connection Store | WebSocket ID → 玩家映射 |
| Turn Timers | 计划的超时跟踪 |
| Inter‑Round Queue | 待处理的加入/离开/配置操作 |
| Users | 账户数据和余额 |
| Ledger | 买入/兑现历史 |
Source: …
困难问题
挑战 1:乐观并发控制
同时的玩家操作可能会破坏状态。我实现了 基于序列的版本控制:每次状态变更都包含一个预期的序列号。如果序列号不匹配,写入失败,客户端会重新同步,从而消除竞争条件和动作丢失。
挑战 2:回合计时系统
Lambda 函数无法 “等待”。我使用 EventBridge 定时事件:当回合开始时,调度一个带有计时序列的未来事件。超时的 Lambda 检查该序列是否仍然是当前的;如果玩家已经行动,则忽略计时,否则自动让玩家弃牌。
挑战 3:隐私过滤广播
每位玩家必须看到个性化的视图(自己的暗牌 vs. 对手的牌背)。广播器加载权威状态,针对每个接收者过滤掉私有信息,并发送定制的 WebSocket 消息。
挑战 4:回合间动作队列
玩家可能在一手牌进行时加入、离开或更改设置。这些动作被存入队列,并在 手牌之间 原子处理,既保持游戏状态的一致性,又能适应真实玩家的行为。
挑战 5:复杂游戏规则
点数游戏包含许多边缘情况——尤其是涉及边池、分池和多名赢家的摊牌逻辑。将这些规则转化为可靠的代码,需要在并发负载下进行细致的状态管理,且全部在无专用服务器的环境中完成。
为什么这超出行业标准
- 一个 实时分布式系统,使用 WebSocket 状态同步
- 事件驱动架构,配合计划触发器和异步处理
- 生产级一致性保证,通过乐观并发实现
- 领域特定游戏逻辑,处理多个同步玩家和游戏的复杂状态机
我设计、编写文档并构建了整个平台,能够解释每一个架构决策。
亲身体验
玩游戏:
加入社区: