最佳实践
架构模式、设计原则与优化策略
本指南介绍经过大量部署验证的架构模式、设计原则和优化策略。
设计原则
1. 从简单开始,逐步演进
不要一开始就过度设计。先采用满足当前需求的最简单方案,再逐步演进。
好的做法: 单个数据库、单个应用服务器、负载均衡器 不好的做法: 第一天就在 5 个区域部署带事件溯源的微服务
2. 为故障做好设计
假设组件总会发生故障,构建冗余并支持优雅降级。
好的做法: 多可用区数据库、故障转移副本、熔断器 不好的做法: 任何位置存在单点故障
3. 先测量,再优化
不要在没有数据时优化。使用分析模块与监控。
好的做法: 运行可扩展性分析以识别真实瓶颈 不好的做法: “数据库可能很慢,加个缓存吧”
4. 理解取舍
每项架构决策都有取舍,务必记录。
好的做法: “为了更快上市,我们先用单体架构,在达到 10 万用户时迁移到微服务” 不好的做法: “为了可扩展性加上微服务”(却不理解复杂性方面的取舍)
5. 尽可能自动化
手动流程难以应对规模增长。将部署、监控和扩缩容自动化。
好的做法: 基础设施即代码(Terraform)、自动扩缩容组、CI/CD 流水线 不好的做法: 手动配置服务器、手动决定扩缩容
常用架构模式
模式:单体 Web 应用
适用场景: MVP、单个团队、少于 10 万用户
拓扑:
Users
↓
Load Balancer (ELB)
↓
App Servers (3+ instances, auto-scaled)
↓
Cache Layer (Redis)
↓
Database (Primary + Read Replicas)
↓
Object Storage (S3)优点:
- 开发和调试简单
- 易于部署和水平扩展
- 运维开销低
缺点:
- 代码库变大后难以维护
- 共享数据库限制扩展
- 受特定技术约束(语言、框架)
演进时机: 用户超过 5 万且遇到数据库瓶颈时
模式:微服务架构
适用场景: 大型团队、超过 10 万用户、多项服务
拓扑:
API Gateway
├─ Auth Service
├─ User Service
├─ Product Service
├─ Order Service
├─ Payment Service
├─ Notification Service
└─ Analytics Service
Shared Infrastructure:
- Service Mesh (Istio, Linkerd)
- Message Bus (Kafka, RabbitMQ)
- Distributed Tracing
- Centralized Logging优点:
- 各服务可独立扩展
- 团队可自主工作
- 技术选型灵活,可使用多种语言
- 易于单独部署服务
缺点:
- 运维复杂性增加
- 面临分布式系统挑战(最终一致性、调试)
- 服务间网络延迟
- 需要成熟的 DevOps 实践
适用时机: 单体已成为瓶颈,并且团队组织结构也能支撑微服务时
模式:无服务器(FaaS)
适用场景: 事件驱动、负载变化较大、重视成本的工作负载
拓扑:
API Gateway
↓
Lambda Functions (auto-scaled to zero)
├─ DynamoDB (serverless database)
├─ S3 (object storage)
├─ SQS/SNS (messaging)
└─ CloudWatch Logs优点:
- 仅为实际使用的计算时间付费
- 空闲时自动缩减至零
- 开发和部署简单
- 无需管理基础设施
缺点:
- 冷启动延迟
- 环境定制能力有限
- 厂商锁定(AWS Lambda、GCP Functions)
- 比传统服务器更难调试
适用场景: 流量突增、低频工作负载、运维资源有限的初创公司
模式:数据湖与分析
适用场景: 大数据、机器学习、分析工作负载
拓扑:
Data Sources (streaming + batch)
↓
Data Ingestion (Kafka, Kinesis, SQS)
↓
Data Lake (S3, Blob Storage)
↓
ETL/Transform (Spark, Glue, Dataflow)
↓
Data Warehouse (Redshift, BigQuery, Snowflake)
↓
BI/ML Tools (Tableau, DataStudio, SageMaker)注意事项:
- 数据质量与治理
- 模式灵活性(读时模式与写时模式)
- 个人身份信息(PII)处理与隐私合规
- 查询性能优化
优化策略
成本优化
1. 合理配置资源规格
- 监控实际使用量,而非最大容量
- 使用 CloudWatch 等工具识别使用规律
- 缩小配置过高的实例
2. 预留实例
- 预测稳定状态的工作负载
- 购买 1–3 年预留实例(优惠 20–40%)
- 配合自动扩缩容应对变化的负载
3. Spot 实例
- 用于容错、非关键工作负载
- 比按需实例便宜 70%
- 预计中断率为 2–5%
4. 缓存策略
- 在内存中缓存热点数据(Redis)
- 可减少 50–80% 的数据库负载
- 对静态资源使用 CDN(成本降低 80% 以上)
5. 数据传输优化
- 这往往是被忽略的高额成本项
- 使用 VPC 端点避免数据传输费用
- 压缩传输中的数据
- 使用 CloudFront 进行全球分发
可扩展性优化
1. 水平扩展
- 在负载均衡器后增加服务器
- 数据库:添加只读副本(主库与副本)
- 缓存:添加缓存节点
2. 分片(数据库)
- 按键拆分数据(用户 ID、区域、日期)
- 各分片可独立扩展
- 代价是分片协调更复杂
3. 连接池
- 复用数据库连接
- 吞吐量提高 2–3 倍
- 减少连接开销
4. 缓存策略
- 在应用层缓存热点数据
- 缓存 API 响应并制定失效策略
- 在 ORM 层缓存数据库查询
安全最佳实践
1. 加密
- 传输中:所有端点使用 TLS 1.3
- 静态存储:使用 KMS 密钥的 AES-256
- 数据库:加密卷,并对 PII 进行应用级加密
2. 身份验证与授权
- 所有用户账户启用 MFA
- 第三方集成使用 OAuth 2.0
- 遵循最小权限的 IAM 策略
- 对应用用户使用 RBAC
3. 网络安全
- VPC 隔离(数据库位于私有子网)
- 安全组仅开放必需端口
- 使用 NACL 增加防护层
- 在负载均衡器前使用 WAF(Web 应用防火墙)
4. 数据保护
- PII 令牌化与脱敏
- 对敏感数据进行字段级加密
- 数据保留策略(删除旧数据)
- 测试备份能否恢复
5. 监控与审计
- 用 CloudTrail 和审计日志记录所有 API 调用
- 使用 CloudWatch 告警发现异常
- 定期开展安全审计
- 制定事件响应手册
性能最佳实践
1. 延迟优化
- 对静态资源使用 CDN
- 为常用查询建立数据库索引
- 优化查询,避免 N+1 查询
- 批量发送 API 请求
2. 吞吐量优化
- 在服务器间进行负载均衡
- 对数据库连接使用连接池
- 异步处理耗时任务
- 对 CPU 密集型负载进行垂直扩展
3. 可靠性
- 带自动恢复的健康检查
- 对依赖项使用熔断器
- 带指数退避的重试
- 优雅降级
部署最佳实践
1. 基础设施即代码
- 全部使用 Terraform 或 CloudFormation 定义
- 纳入版本控制
- 应用前进行同行评审
- 先在预发布环境测试
2. 持续部署
- 自动测试(单元、集成、端到端)
- 金丝雀发布(逐步上线)
- 蓝绿部署(零停机)
- 回滚策略
3. 监控与可观测性
- 结构化日志(JSON)
- 分布式追踪(X-Ray、Jaeger)
- 指标采集(Prometheus、CloudWatch)
- 基于 SLO 而非仅错误触发告警
反模式(应避免的做法)
❌ 任何单点故障(没有冗余) ❌ 过度设计(在业务增长需要之前就采用复杂架构) ❌ 忽略成本影响(为不需要的功能选择服务) ❌ 手动扩缩容(应当自动化) ❌ 没有监控(无法了解运行状态) ❌ 没有灾难恢复计划(寄希望于运气不是策略) ❌ 所有资源都在一个可用区(无法抵御数据中心故障)