7.8 KiB
7.8 KiB
第32天:应用架构综合实战——设计一个 SaaS 平台
今天你将学到什么
今天是第四阶段的收尾。我们用一个完整的 SaaS(软件即服务)平台案例,把容器、CI/CD、API Gateway、Step Functions、微服务等知识串联起来。
项目背景:在线协作文档平台
假设你要做一个类似"腾讯文档"的简化版平台:
- 用户可以创建、编辑、分享文档
- 支持多人实时协作编辑
- 支持文档导出为 PDF
- 有团队管理和权限控制
- 需要支持百万级用户
整体架构
Web 前端 / 移动端
↓
CloudFront(静态资源 + API 加速)
↓
API Gateway(REST API 入口)
↓
┌─────────────────────────────────────────────────┐
│ ECS Fargate 集群 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 用户服务 │ │ 文档服务 │ │ 团队服务 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 权限服务 │ │ 搜索服务 │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ 数据层 │
│ Aurora(用户、团队、权限) │
│ DynamoDB(文档内容、版本历史) │
│ ElastiCache Redis(会话、协作状态) │
│ S3(文档附件、导出的 PDF) │
│ OpenSearch(全文搜索) │
└─────────────────────────────────────────────────┘
异步处理:
EventBridge → Step Functions → Lambda
(文档导出、通知发送、数据分析)
实时协作:
API Gateway WebSocket → Lambda → DynamoDB + Redis
各服务职责
用户服务
- 注册、登录、个人信息管理
- 集成 Cognito 做身份认证
- 数据库:Aurora(用户表)
文档服务
- 创建、读取、更新、删除文档
- 管理文档版本历史
- 数据库:DynamoDB(文档内容,支持高频读写)
团队服务
- 创建团队、邀请成员、管理角色
- 数据库:Aurora(团队和成员关系)
权限服务
- 判断用户对某个文档有没有权限
- 缓存:Redis(权限判断需要极快响应)
搜索服务
- 全文搜索文档内容和标题
- 引擎:OpenSearch(Elasticsearch 托管版)
关键流程设计
流程一:用户编辑文档
1. 用户打开文档
→ API Gateway → 权限服务(检查权限)→ 文档服务(获取内容)
2. 用户编辑
→ WebSocket 连接 → Lambda → DynamoDB(保存变更)
→ Redis(广播给其他协作者)
3. 自动保存
→ 每 5 秒将变更批量写入 DynamoDB
→ 保留版本历史(最近 100 个版本)
流程二:文档导出 PDF(Step Functions)
用户点击"导出 PDF"
↓
API Gateway → Lambda(创建导出任务)→ 返回任务 ID 给用户
↓
Step Functions 工作流启动:
↓
获取文档内容(Task)
↓
渲染为 PDF(Task,可能需要 30 秒)
↓
上传到 S3(Task)
↓
生成下载链接(Task)
↓
通知用户"PDF 已就绪"(Task → SNS → 推送通知)
为什么用 Step Functions?因为 PDF 渲染可能需要较长时间,不适合让用户同步等待。
流程三:新用户注册
用户注册
↓
Cognito 创建用户
↓
EventBridge 发布"用户注册"事件
↓
├── Lambda:创建默认工作空间
├── Lambda:发送欢迎邮件(SES)
├── Lambda:创建示例文档
└── Lambda:记录注册统计
CI/CD 流水线
开发者推送代码(GitHub)
↓
CodePipeline 触发
↓
CodeBuild:
- 运行单元测试
- 构建 Docker 镜像
- 推送到 ECR
- 运行安全扫描
↓
部署到 Staging 环境:
- 更新 ECS 服务
- 运行集成测试
- 运行 E2E 测试
↓
人工审批(团队负责人确认)
↓
部署到 Production:
- ECS 蓝绿部署
- 金丝雀发布(5% → 25% → 100%)
- 自动回滚(如果错误率上升)
每个微服务有自己独立的流水线,可以独立部署。
扩展性设计
| 组件 | 扩展方式 | 触发条件 |
|---|---|---|
| ECS 服务 | 自动扩展任务数 | CPU > 70% 或请求队列增长 |
| DynamoDB | 自动扩展读写容量 | 使用率 > 70% |
| Aurora | 增加只读副本 | 读取延迟 > 100ms |
| Redis | 增加分片 | 内存使用 > 80% |
| Lambda | 自动(无需配置) | 并发请求增加 |
成本优化策略
| 策略 | 节省 | 实现方式 |
|---|---|---|
| Fargate Spot | 最多 70% | 非关键服务使用 Spot 容量 |
| DynamoDB 按需模式 | 避免过度预置 | 流量不稳定的表用按需模式 |
| S3 生命周期 | 存储费用 | 30 天前的版本转到低频存储 |
| CloudFront 缓存 | 减少源站请求 | 静态资源缓存 24 小时 |
| Reserved Capacity | 最多 60% | Aurora 和 Redis 用预留实例 |
监控与告警
CloudWatch Dashboard(统一视图):
├── 业务指标:活跃用户数、文档创建数、API 调用量
├── 性能指标:API 延迟 P99、错误率、数据库连接数
├── 资源指标:CPU、内存、磁盘使用率
└── 成本指标:每日花费、各服务占比
告警规则:
├── API 错误率 > 1% → 通知开发团队(Slack)
├── P99 延迟 > 2s → 通知运维团队
├── 数据库连接数 > 80% → 自动扩展 + 通知
└── 月度成本超预算 20% → 通知管理层
架构决策总结
| 决策 | 选择 | 原因 |
|---|---|---|
| 服务运行 | ECS Fargate | 不想管服务器,按需付费 |
| API 入口 | API Gateway | 统一认证、限流、监控 |
| 实时协作 | WebSocket + Redis | 低延迟双向通信 |
| 文档存储 | DynamoDB | 高频读写、灵活 schema |
| 用户数据 | Aurora | 关系型数据、复杂查询 |
| 异步处理 | EventBridge + Step Functions | 解耦、可视化、错误处理 |
| 搜索 | OpenSearch | 全文搜索、模糊匹配 |
| 部署 | 蓝绿 + 金丝雀 | 零停机、低风险 |
今天的小测验
- 为什么文档内容用 DynamoDB 而不是 Aurora?
- 文档导出 PDF 为什么用 Step Functions 而不是同步处理?
- 这个架构中,哪些部分可以独立扩展?
- 如果某个微服务出了 bug,对其他服务有什么影响?
延伸阅读
明天预告
进入第五阶段:监控与运维。明天学习 CloudWatch——AWS 的监控核心。了解如何监控你的应用和基础设施,设置告警,在问题发生前就发现它。