Skip to content

04 - 架构与设计:技术决策 → 系统蓝图 ​

架构决策 = 不可逆决策。错了一次,要花 10 倍代价回头改。所以 ADR 不是给"已经定了"的决策用的,是给"还没定"时用的。

一句话 ​

架构师的核心产出 = ADR + 架构图 + 接口契约 + 数据模型——四件套把"模糊的技术决策"变成"团队共识的可执行蓝图"。

架构师的 3 大产出 ​

无论什么项目,架构师必交付这 3 件:

产出 1:架构决策记录(ADR) ​

为什么必须写:

  • 6 个月后你不在了,新人不知道为什么选 PostgreSQL
  • 重要决策被遗忘,下个人提同样的问题
  • 没有 ADR = 没有"决策历史"= 组织失忆

ADR 模板(基于 MADR):

markdown
# ADR-2026-Q3-001:选择 PostgreSQL 作为主数据库

## 状态
2026-06-28 已接受

## 背景和约束
- 当前 5 万行日活用户
- 需要事务 + 全文搜索 + JSONB
- 团队有 PG 经验,无 MongoDB 经验
- 预算有限,希望不开新组件

## 备选方案

### 选项 A:MySQL 8.0 + Elasticsearch
- 优点:团队熟悉 MySQL;ES 搜索强
- 缺点:两个组件,运维成本高;事务需要同步双写
- 评估:维护成本 +1,延期风险高

### 选项 B:MongoDB
- 优点:天然支持 JSON;水平扩展容易
- 缺点:团队无经验;事务能力弱(4.0 前)
- 评估:学习曲线陡,3 个月内不可用

### 选项 C:PostgreSQL 14+
- 优点:单组件;全文搜索原生支持;JSONB 完善
- 缺点:水平扩展需要额外工具(Citus)
- 评估:MVP 期足够,未来可加 Citus

## 决策
**选择 C:PostgreSQL 14+**

## 影响
- + 数据库单一组件,运维简单
- + 团队立即上手
- - 未来扩展需要评估 Citus 或分库
- - 需要 DBA 或团队培训

## 决策时间
2026-06-28

## 决策人
张三(架构师)+ 李四(技术负责人)+ 王五(运维负责人)

ADR 必须有的 5 部分:

  1. 状态(提议 / 已接受 / 已废弃 / 已取代)
  2. 背景(为什么需要决策)
  3. 选项(至少 2 个,含优缺点)
  4. 决策(明确选哪个)
  5. 影响(正负两面)

什么时候写 ADR:

  • ✅ 选数据库 / 消息队列 / 框架
  • ✅ 选架构风格(微服务 / 单体 / 事件驱动)
  • ✅ 接口设计(REST vs GraphQL vs gRPC)
  • ✅ 数据建模关键决策(如订单的状态机)
  • ❌ 一行代码的写法
  • ❌ 测试用例

产出 2:架构图(C4 模型) ​

Simon Brown 的 C4 模型——4 层抽象:

Level 1: System Context(系统上下文)
   ↓ 整个系统在一个图里
Level 2: Container(容器)
   ↓ 进程/服务/数据库
Level 3: Component(组件)
   ↓ 类/模块/包
Level 4: Code(代码)
   ↓ 类图/ER 图(可选)

Level 1 示例(用户视角):

┌─────────────────────────────────────────────┐
│                 电商系统                       │
│                                                │
│    ┌──────────────┐    ┌──────────────┐        │
│    │  用户 Web/App │    │   商家后台    │        │
│    └──────┬───────┘    └──────┬───────┘        │
│           │                    │               │
│           ▼                    ▼               │
│    ┌─────────────────────────────────┐          │
│    │      [核心电商系统]               │          │
│    │   订单 · 商品 · 支付 · 履约        │          │
│    └────────────┬────────────────────┘          │
│                 │                               │
└─────────────────┼───────────────────────────────┘
                  ▼
        ┌─────────────────────┐
        │  第三方:支付/物流   │
        └─────────────────────┘

Level 2 示例(技术视角):

┌──────────────────────────────────────────────┐
│                Web App (React)                  │
│                Mobile App (RN)                  │
└──────────────────┬───────────────────────────────┘
                   │ HTTPS
                   ▼
┌──────────────────────────────────────────────┐
│            API Gateway (Kong)                  │
└────┬──────────────┬──────────────┬─────────────┘
     │              │              │
     ▼              ▼              ▼
┌──────────┐  ┌──────────┐  ┌──────────┐
│ 订单服务  │  │ 商品服务  │  │ 支付服务  │
│ (Java)   │  │ (Python) │  │ (Go)     │
└────┬─────┘  └────┬─────┘  └────┬─────┘
     │             │             │
     ▼             ▼             ▼
┌──────────┐  ┌──────────┐  ┌──────────┐
│ 订单 DB  │  │ 商品 DB  │  │ 支付 DB  │
│ (PG)     │  │ (ES)     │  │ (PG)     │
└──────────┘  └──────────┘  └──────────┘

产出 3:接口契约(API Contract) ​

REST API 必须包含:

yaml
openapi: 3.0.0
info:
  title: 订单 API
  version: 1.0.0
paths:
  /orders:
    post:
      summary: 创建订单
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrderRequest'
      responses:
        '201':
          description: 成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: 参数错误
        '409':
          description: 库存不足
components:
  schemas:
    CreateOrderRequest:
      type: object
      required:
        - user_id
        - items
      properties:
        user_id:
          type: string
        items:
          type: array
          items:
            type: object
            properties:
              product_id:
                type: string
              quantity:
                type: integer

事件契约(Event Contract):

json
{
  "event_type": "order.created",
  "version": "1.0",
  "data": {
    "order_id": "uuid",
    "user_id": "uuid",
    "items": [...],
    "total": 99.99,
    "currency": "CNY",
    "created_at": "2026-06-28T12:00:00Z"
  }
}

架构设计的 7 步法 ​

Step 1:业务问题映射 ​

输入:立项书 + 用户故事 输出:业务能力图(哪些能力必须支持)

Step 2:领域划分(DDD Bounded Context) ​

用 IDDD L3 BC 范式:

  • 一个 BC = 一个明确的业务边界
  • BC 间不能直接改对方数据库
  • BC 间只能通过 API / 事件通信

判断标志:

  • 这个概念在这个 BC 和另一个 BC 含义不同时 → 拆 BC
  • 团队规模到 5+ 个 → 拆 BC
  • 部署可以独立 → 拆 BC

Step 3:选架构风格 ​

决策矩阵:

场景推荐架构
简单业务 + 团队 < 5 人单体(不是 monorepo,是单 deployable)
业务多 + 团队 5-30 人微服务
高并发读写冲突CQRS
数据量大 + 解耦事件驱动
跨学科系统六边形 + SOA

Vernon Ch4 警告:

"Architectural styles are not a grab bag of cool tools... use them only where applicable."

Step 4:技术栈选型 ​

技术雷达(ThoughtWorks)模型:

采纳(Adopt): 团队所有人都用,主力技术
试用(Trial): 局部场景使用,有 1-2 个团队用
评估(Assess): 值得研究,1 个团队在评估
暂缓(Hold): 不推荐新项目使用,但旧项目还在用

示例:

采纳: TypeScript、React、PostgreSQL、Kafka
试用: Rust、Deno、ClickHouse、eBPF
评估: WebAssembly、WASM Components
暂缓: MongoDB(除非特殊场景)、SOAP

Step 5:数据建模 ​

ER 图关键问题:

  • 哪些是实体(独立存在)?
  • 哪些是值对象(依附实体,无独立标识)?
  • 哪些是聚合(一组相关对象)?
  • 聚合的边界在哪(写边界)?

Idempotency(幂等性):所有写操作必须有 idempotency_key,防止重复请求导致问题。

Step 6:接口设计 ​

REST:

  • 资源用名词,不用动词
  • 状态用 HTTP status code
  • 不要把内部表结构暴露给 API

事件:

  • 事件名用过去时(OrderCreated 不是 CreateOrder)
  • Schema 必填字段 + 可选字段
  • 版本字段必须

Step 7:非功能性需求 ​

必答 6 个:

  1. 性能——并发多少?响应时间要求?
  2. 可用性——SLA 多少(99.9% / 99.99%)?
  3. 可扩展性——业务量 10 倍怎么应对?
  4. 安全性——数据脱敏?加密传输?
  5. 可观测性——日志 / 指标 / 追踪?
  6. 可维护性——团队扩大 2 倍还能维护吗?

跨团队改动(LSC,Large-Scale Changes) ​

SE@Google Ch22 的核心观点:

"Large-Scale Changes can touch hundreds of CLs across many codebases."

LSC 的 4 步流程:

1. 设计:找所有受影响团队 + 设计协调员
    ↓
2. 共识:RFC 在所有团队评审通过
    ↓
3. 执行:分阶段 5% → 50% → 100%
    ↓
4. 收尾:清理旧代码 + 文档更新

协调员(Coordinator)必备:

  • 一个明确的人推这件事
  • 不是大家各改各的
  • 协调员必须有权决定"什么时候强制执行"

反模式:没有协调员的 LSC = 5 个团队改了 5 个版本,互相不兼容。

设计的反模式(5 种) ​

1. 过度设计 ​

症状:5 人团队设计 30 个微服务 + 6 种存储 + 4 种消息队列

修复:YAGNI(You Aren't Gonna Need It)——先简单,跑通业务再考虑拆分。

2. 设计脱离业务 ​

症状:架构师沉迷技术选型,半年后业务没进展

修复:每个技术决策挂到业务结果上。

3. 不写 ADR,靠口头传承 ​

症状:架构师离职带走所有"为什么"的知识

修复:每个重要决策写 ADR。新人 onboard 第一周读所有 ADR。

4. 复制大厂架构 ​

症状:5 万用户系统套用 Google 十万级工程师架构

修复:架构匹配业务规模——参考 SE@Google Ch1"trade-offs"。

5. 设计完不评审 ​

症状:架构师一个人做完设计,团队不知道

修复:架构评审会(Architecture Review)——邀请所有人评审,特别是被影响的团队。

架构评审会 ​

议程:

1. 业务背景(5 分钟)
2. 当前架构痛点(5 分钟)
3. 提议架构(10 分钟)
4. 备选方案对比(10 分钟)
5. Q&A + 风险讨论(20 分钟)
6. 决策(5 分钟)

参加人:

  • 必到:架构师本人、受影响团队 Lead、SRE/运维负责人
  • 选到:技术总监、跨团队代表、新人(避免信息孤岛)

架构文档库 ​

最小集合:

architecture/
├── adr/                  # ADR 列表
│   ├── 001-postgresql.md
│   ├── 002-kafka.md
│   └── 003-event-driven.md
├── diagrams/             # C4 模型图
│   ├── c1-context.png
│   ├── c2-containers.png
│   └── c3-components.png
├── api/                  # API 契约
│   ├── openapi.yaml
│   └── events.json
├── data/                 # 数据建模
│   ├── er-diagram.png
│   └── schema-evolution.md
├── runbooks/             # 运维手册
│   ├── deployment.md
│   └── incident-response.md
└── README.md             # 索引

进入下一章 ​

架构与设计完成后,下一步:

  • 05 任务与冲刺——把架构设计分解为可执行任务

作者:基于 IDDD L4 (Context Maps) + SE@Google Ch22 (LSC) + Vernon Ch4 (架构风格) 综合 最后更新:2026-06-28

从名家方法论与工程化思路中蒸馏出自己的工程体系。