前置知识: 云计算

云架构设计

6 min高级

云架构设计原则、微服务架构、事件驱动架构、无服务器架构、多区域高可用、灾备策略与架构评审。

1. 云架构设计原则

1.1 Well-Architected Framework

AWS Well-Architected Framework 定义了六大支柱:

支柱核心关注关键实践
卓越运营运维自动化、事件响应IaC、可观测性、Runbook
安全性数据保护、身份认证最小权限、加密、审计
可靠性故障恢复、弹性伸缩多 AZ、自动恢复、混沌工程
性能效率资源选型、高效利用按需选型、缓存、压缩
成本优化消除浪费、合理定价Reserved Instance、Right-sizing
可持续性资源效率、碳足迹Graviton、Spot、弹性调度

1.2 云原生设计原则

  • 不可变基础设施:服务器不手动修改,通过替换实现变更
  • 声明式 API:描述期望状态,系统自动收敛
  • 自服务:开发团队自助获取资源,无需审批瓶颈
  • 松耦合:服务间通过 API 通信,独立部署与扩展
  • 可观测:指标、日志、链路追踪三位一体

1.3 设计权衡

架构设计本质是权衡,常见决策点:

CAP⇒一致性 vs 可用性 vs 分区容错\text{CAP} \Rightarrow \text{一致性 vs 可用性 vs 分区容错} 延迟 vs 一致性⇒强一致(同步复制) vs 最终一致(异步复制)\text{延迟 vs 一致性} \Rightarrow \text{强一致(同步复制) vs 最终一致(异步复制)} 成本 vs 可靠性⇒单区域 vs 多区域\text{成本 vs 可靠性} \Rightarrow \text{单区域 vs 多区域}

2. 微服务架构

2.1 微服务拆分策略

领域驱动设计(DDD) 是微服务拆分的核心方法论:

flowchart LR
    subgraph BC[限界上下文 Bounded Context]
        O[订单上下文<br/>Aggregate Order]
        P[支付上下文<br/>Aggregate Payment]
        S[库存上下文<br/>Aggregate Stock]
    end

拆分原则:

  • 单一职责:每个服务聚焦一个业务能力
  • 独立部署:服务可独立发布,不影响其他服务
  • 数据自治:每个服务拥有自己的数据存储
  • 接口契约:服务间通过明确定义的 API 交互

2.2 服务通信模式

同步通信:

协议适用场景特点
REST/HTTPCRUD 操作简单通用,但开销大
gRPC服务间高频调用高性能,强类型,流式
GraphQL前端聚合查询按需获取,减少过度获取

异步通信:

模式适用场景代表技术
点对点任务分发RabbitMQ、SQS
发布/订阅事件通知Kafka、SNS
事件溯源审计追踪EventStoreDB

2.3 服务网格(Service Mesh)

服务网格将通信逻辑从应用代码中抽离到基础设施层:

flowchart LR
    subgraph Mesh[Service Mesh]
        A[Service A<br/>Sidecar] <--> B[Service B<br/>Sidecar]
        CP[Control Plane<br/>Pilot / Citadel / Galley]
    end

核心能力:流量管理、安全通信(mTLS)、可观测性、故障注入。

3. 事件驱动架构

3.1 事件驱动核心概念

flowchart LR
    Prod[事件生产者] -->|事件| Router[事件路由器] -->|事件| Cons[事件消费者]
    Router --> Store[事件存储<br/>可选,用于事件回放]

事件 vs 命令 vs 查询:

类型意图响应期望示例
命令请求执行操作期望成功/失败CreateOrder
事件通知已发生事实无期望OrderCreated
查询请求信息期望返回数据GetOrderStatus

3.2 事件溯源(Event Sourcing)

不存储当前状态,而是存储所有状态变更事件:

传统方式:  Order { id: 1, status: "shipped", total: 99.9 }

事件溯源:  OrderCreated   { id: 1, items: [...], total: 99.9 }
           OrderPaid      { id: 1, paymentId: "pay_123" }
           OrderShipped   { id: 1, trackingNo: "SF123456" }

当前状态通过重放事件获得:

Statecurrent=Apply(Event1,Event2,…,Eventn)\text{State}_{current} = \text{Apply}(\text{Event}_1, \text{Event}_2, \ldots, \text{Event}_n)

为避免每次全量重放,使用快照(Snapshot):

Statecurrent=Apply(Snapshotk,Eventk+1,…,Eventn)\text{State}_{current} = \text{Apply}(\text{Snapshot}_k, \text{Event}_{k+1}, \ldots, \text{Event}_n)

3.3 CQRS 模式

命令查询职责分离(Command Query Responsibility Segregation):

flowchart LR
    W[Write Side API] -->|Command| CM[Command Model OLTP] -->|Event| QM[Query Model OLAP]
    R[Read Side API] <-->|Query| QM

优势:读写模型独立优化,读侧可水平扩展;代价:最终一致性、复杂度增加。

4. 无服务器架构

4.1 Serverless 核心理念

Serverless 不是没有服务器,而是无需管理服务器:

  • FaaS(Function as a Service):按请求执行代码
  • BaaS(Backend as a Service):托管后端服务(数据库、认证、存储)

4.2 FaaS 执行模型

flowchart LR
    A[请求到达] --> B[冷启动] --> C[初始化运行时] --> D[执行函数] --> E[返回结果] --> F[实例保活] --> G[超时回收]
    G -.->|下次请求,若实例已回收| B

冷启动时间参考:

运行时冷启动时间备注
Node.js100-300ms较快
Python200-500ms中等
Java1-3sJVM 启动开销
Go50-200ms编译型,启动快
Rust50-150ms编译型,启动快
.NET500ms-2sCLR 初始化

4.3 Serverless 适用场景

适合:

  • 事件驱动型工作负载(Webhook、定时任务)
  • 流量波动大的 API
  • 数据处理管道(ETL)
  • 实时文件处理(图片/视频转码)

不适合:

  • 长时间运行任务(>15min)
  • 低延迟要求(冷启动不可控)
  • 需要持久连接(WebSocket、gRPC 流)
  • 高频小请求(调用费用累积)

4.4 Serverless 成本模型

月成本=请求数×单价/百万请求+∑i(执行时间i×内存i×单价/GB⋅s)\text{月成本} = \text{请求数} \times \text{单价/百万请求} + \sum_{i} (\text{执行时间}_i \times \text{内存}_i \times \text{单价/GB·s})

与传统方案的成本交叉点:

当 请求量×平均执行时间时间窗口<服务器利用率阈值 时,Serverless 更优\text{当 } \frac{\text{请求量} \times \text{平均执行时间}}{\text{时间窗口}} < \text{服务器利用率阈值} \text{ 时,Serverless 更优}

5. 多区域高可用架构

5.1 高可用层级

flowchart TD
    GLB[全球负载均衡 DNS/CDN]
    subgraph RA[区域 A]
        ALB1[ALB 多 AZ]
        AZ1[AZ1] AZ2[AZ2] AZ3[AZ3]
        DB1[数据库主]
    end
    subgraph RB[区域 B]
        ALB2[ALB 多 AZ]
        BZ1[AZ1] BZ2[AZ2] BZ3[AZ3]
        DB2[数据库从]
    end
    GLB --> ALB1
    GLB --> ALB2

5.2 RPO 与 RTO

指标含义典型值
RPO(恢复点目标)可容忍的最大数据丢失量0(同步复制)- 数小时
RTO(恢复时间目标)可容忍的最大服务中断时间秒级 - 数小时
可用性=MTBFMTBF+MTTR=1−MTTRMTBF+MTTR\text{可用性} = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}} = 1 - \frac{\text{MTTR}}{\text{MTBF} + \text{MTTR}}

其中 MTBF 为平均故障间隔时间,MTTR 为平均恢复时间。

5.3 灾备策略

策略RPORTO成本实现方式
备份与恢复小时级小时级低定期备份到对象存储
预置备用分钟级分钟级中备用区域保持最小容量
温备用秒级分钟级中高备用区域持续运行但流量低
多活接近零接近零高多区域同时服务

6. 架构评审

6.1 架构决策记录(ADR)

每个重要架构决策应记录:

ADR-001: 选择事件驱动架构处理订单流程

状态: 已接受

背景:
  订单系统需要与支付、库存、物流等多个系统交互,
  同步调用导致级联故障风险和响应延迟增加。

决策:
  采用事件驱动架构,订单服务发布领域事件,
  下游服务异步订阅处理。

后果:
  正面: 松耦合、弹性提升、可独立扩展
  负面: 最终一致性、调试复杂度增加、需要事件排序机制

6.2 架构评审检查清单

可靠性:

  • 单点故障是否消除
  • 是否有自动故障转移机制
  • 是否有重试与熔断策略
  • 是否有混沌工程验证

安全性:

  • 数据是否加密(传输中 + 静态)
  • 身份认证与授权是否完备
  • 是否有网络分段与隔离
  • 是否有安全扫描与审计

可扩展性:

  • 是否支持水平扩展
  • 是否有自动伸缩策略
  • 是否有缓存策略
  • 数据库是否有分片方案

可观测性:

  • 是否有指标监控
  • 是否有分布式追踪
  • 是否有结构化日志
  • 是否有告警与 Runbook

小结

  • 初学者要点:架构设计的起点是 Well-Architected 六支柱的权衡,不是技术选型; 微服务拆分跟着业务边界(限界上下文)走,而不是跟着团队人数或技术潮流走; 灾备先定 RPO/RTO 再选策略,预算决定形态。
  • 进阶注意:Serverless 的冷启动与常驻成本模型要用真实流量回放验证; 多区域架构从「备份恢复 → 预置备用 → 温备 → 多活」逐级演进,直接上多活是 最常见的过度设计;重要决策沉淀为 ADR,半年后没人记得”当时为什么这么选”。