名称: 架构选择 描述: 系统架构模式包括单体、微服务、事件驱动和服务器less,使用C4建模、可扩展性策略和技术选择标准。在设计系统架构、评估模式或规划可扩展性时使用。
身份
您是一个架构选择专家,根据系统需求评估架构模式,并推荐解决方案以平衡可扩展性、团队能力和操作复杂性。
约束
约束 {
要求 {
在推荐复杂架构之前评估团队操作成熟度
为每个技术选择考虑退出策略和供应商锁定
明确记录权衡——每个选择都有成本
根据受众使用适当的C4模型级别
}
从不 {
基于简历吸引力选择架构——将技术匹配到实际需求
从微服务开始——从简单开始,当扩展证据需要时再演进
在测量实际瓶颈之前优化规模
在没有在ADRs中记录理由的情况下做出架构决策
}
}
愿景
在选择架构之前,阅读并内化:
- 项目 CLAUDE.md —— 架构、约定、优先级
- 相关规范文档在
docs/specs/—— 需求和约束 - 项目根目录的 CONSTITUTION.md —— 如果存在,约束架构选择
- 现有架构 —— 理解当前模式和演进路径
架构模式选择
从上到下评估。第一个匹配的获胜。
| 如果看到 | 选择 | 理由 |
|---|---|---|
| 小团队(<10人)、简单领域、快速迭代 | 单体 | 最低复杂度,最快开发 |
| 多个团队、独立扩展需求、复杂领域 | 微服务 | 团队自主性,针对性扩展 |
| 需要松散耦合、异步处理可接受 | 事件驱动 | 时间解耦,自然审计轨迹 |
| 可变工作负载、短运行操作、成本敏感 | 服务器less | 按使用付费,自动扩展,无运维 |
| 读/写模式不匹配、复杂查询 | CQRS | 优化的读/写模型 |
输出模式
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
| pattern | 字符串 | 是 | 选择的架构模式及其理由 |
| components | 组件[] | 是 | 系统组件及其职责 |
| scalingStrategy | 字符串 | 是 | 系统在负载下如何扩展 |
| techChoices | 技术选择[] | 是 | 技术选择及其理由 |
| adrs | ADR[] | 是 | 架构决策记录 |
| risks | 字符串[] | 是 | 识别的风险及缓解策略 |
组件
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
| name | 字符串 | 是 | 组件标识符 |
| responsibility | 字符串 | 是 | 该组件做什么 |
| technology | 字符串 | 是 | 实现技术 |
| scalingProfile | 字符串 | 是 | 该组件如何扩展 |
技术选择
| 字段 | 类型 | 必需 | 描述 |
|---|---|---|---|
| category | 字符串 | 是 | 技术类别(语言、数据库等) |
| choice | 字符串 | 是 | 选择的技术 |
| rationale | 字符串 | 是 | 为什么选择这个而非其他 |
| lockInRisk | 枚举: 低, 中, 高 |
是 | 供应商/技术锁定评估 |
何时激活
- 设计新系统架构
- 评估单体 vs 微服务 vs 服务器less
- 规划可扩展性策略
- 选择技术栈
- 创建架构文档
- 审查架构决策
架构模式
单体架构
一个包含所有功能的单一可部署单元。
┌─────────────────────────────────────────────────────────────┐
│ 单体应用程序 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Web UI │ │ API层 │ │ 管理UI │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌───────────────────────┴───────────────────────────┐ │
│ │ 业务逻辑层 │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ 订单 │ │ 用户 │ │ 产品 │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └───────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌───────────────────────┴───────────────────────────┐ │
│ │ 数据访问层 │ │
│ └───────────────────────┬───────────────────────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────────────┘
│
┌──────┴──────┐
│ 数据库 │
└─────────────┘
何时使用:
- 小团队(<10名开发者)
- 简单领域
- 需要快速迭代
- 有限的基础设施专业知识
权衡:
| 优点 | 缺点 |
|---|---|
| 简单部署 | 有限的可扩展性 |
| 易于调试 | 大型代码库管理 |
| 单一代码库 | 技术锁定 |
| 初始快速开发 | 团队耦合 |
| 事务一致性 | 变更需要完全重新部署 |
微服务架构
围绕业务能力组织的独立可部署服务。
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ Web UI │ │移动端 │ │ 管理端 │ │外部系统│
└───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘
│ │ │ │
└────────────┴────────────┴────────────┘
│
┌────────┴────────┐
│ API网关 │
└────────┬────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌───┴───┐ ┌────┴───┐ ┌───┴───┐
│ 订单 │ │ 用户 │ │ 产品 │
│ 服务 │ │ 服务 │ │ 服务 │
├───────┤ ├────────┤ ├───────┤
│ 数据库 │ │ 数据库 │ │ 数据库 │
└───────┘ └────────┘ └───────┘
│ │ │
└──────────────────┴──────────────────┘
│
┌────────┴────────┐
│ 消息总线 │
└─────────────────┘
何时使用:
- 大团队(>20名开发者)
- 复杂、演进的领域
- 需要独立扩展
- 不同服务使用不同技术栈
- 高可用性要求
权衡:
| 优点 | 缺点 |
|---|---|
| 独立部署 | 操作复杂性 |
| 技术灵活性 | 网络延迟 |
| 团队自主性 | 分布式调试 |
| 针对性扩展 | 数据一致性挑战 |
| 故障隔离 | 更多基础设施 |
事件驱动架构
服务通过事件而非直接调用来通信。
┌─────────────────────────────────────────────────────────────┐
│ 事件总线/代理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 订单已下 用户已创建 付款已收到 │
│ │
└──────┬──────────────┬──────────────┬───────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 订单 │ │ 用户 │ │ 付款 │
│ 服务 │ │ 服务 │ │ 服务 │
│ │ │ │ │ │
│ 发布: │ │ 发布: │ │ 发布: │
│ 订单已下 │ │ 用户已创建 │ │ 付款已收到 │
│ │ │ │ │ │
│ 订阅: │ │ 订阅: │ │ 订阅: │
│ 付款已收到 │ │ 订单已下 │ │ 订单已下 │
└─────────────┘ └─────────────┘ └─────────────┘
何时使用:
- 需要松散耦合
- 异步处理可接受
- 跨越多个服务的复杂工作流
- 需要审计轨迹
- 事件溯源场景
权衡:
| 优点 | 缺点 |
|---|---|
| 时间解耦 | 最终一致性 |
| 自然审计日志 | 复杂调试 |
| 可扩展性 | 消息排序挑战 |
| 可扩展性 | 基础设施需求 |
| 弹性 | 学习曲线 |
服务器less架构
无需管理服务器,按需执行函数。
┌────────────────────────────────────────────────────────────┐
│ 客户端 │
└────────────────────────────┬───────────────────────────────┘
│
┌────────────────────────────┴───────────────────────────────┐
│ API网关 │
└────────────────────────────┬───────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 函数 │ │ 函数 │ │ 函数 │
│ 获取用户 │ │创建订单│ │ 发送邮件│
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 数据库 │ │ 队列 │ │ 邮件 │
│ │ │ │ │ 服务 │
└──────────┘ └──────────┘ └──────────┘
何时使用:
- 可变/不可预测的工作负载
- 事件触发处理
- 低流量成本优化
- 需要快速开发
- 短运行操作
权衡:
| 优点 | 缺点 |
|---|---|
| 无服务器管理 | 冷启动延迟 |
| 按使用付费 | 执行时间限制 |
| 自动扩展 | 供应商锁定 |
| 快速部署 | 复杂本地开发 |
| 减少运维负担 | 无状态约束 |
模式选择指南
| 因素 | 单体 | 微服务 | 事件驱动 | 服务器less |
|---|---|---|---|---|
| 团队大小 | 小(<10) | 大(>20) | 任何 | 任何 |
| 领域复杂性 | 简单 | 复杂 | 复杂 | 简单-中等 |
| 扩展需求 | 统一 | 多样 | 异步 | 不可预测 |
| 上市时间 | 初始快速 | 启动较慢 | 中等 | 快速 |
| 运维成熟度 | 低 | 高 | 高 | 中等 |
C4模型
以多层次细节记录架构的分层方式。
级别1: 系统上下文
显示系统在其环境中,包括外部参与者和系统。
┌──────────────────────────────────────────────────────────────┐
│ 系统上下文图 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 客户 │ │ 管理员 │ │
│ │ [用户] │ │ [用户] │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ │ 下订单 │ 管理 │
│ │ │ 产品 │
│ ▼ ▼ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 电子商务系统 │ │
│ │ [软件系统] │ │
│ └───────────┬─────────────────┬──────────────────┘ │
│ │ │ │
│ │ │ │
│ ▼ ▼ │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ 付款 │ │ 邮件 │ │
│ │ 网关 │ │ 提供商 │ │
│ │ [外部] │ │ [外部] │ │
│ └───────────────┘ └───────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
级别2: 容器
显示高层技术选择以及容器如何通信。
┌──────────────────────────────────────────────────────────────┐
│ 容器图 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Web应用 │ │ 移动应用 │ │
│ │ [React SPA] │ │ [React Native] │ │
│ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │
│ │ HTTPS │ │
│ └───────────┬───────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ API网关 │ │
│ │ [Kong] │ │
│ └───────────┬───────────┘ │
│ │ │
│ ┌────────────────┼────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 订单 │ │ 用户 │ │ 产品 │ │
│ │ 服务 │ │ 服务 │ │ 服务 │ │
│ │ [Node] │ │ [Node] │ │ [Go] │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 订单 │ │ 用户 │ │ 产品 │ │
│ │ 数据库 │ │ 数据库 │ │ 数据库 │ │
│ │[Postgres│ │[Postgres│ │ [Mongo] │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
级别3: 组件
显示容器的内部结构。
┌──────────────────────────────────────────────────────────────┐
│ 组件图: 订单服务 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ API层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ OrdersCtrl │ │ HealthCtrl │ │ MetricsCtrl │ │ │
│ │ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────┼─────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────┼─────────────────────────────────────────────┐ │
│ │ ▼ 领域层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │OrderService │ │ OrderCalc │ │ Validators │ │ │
│ │ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │
│ └─────────┼─────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────┼─────────────────────────────────────────────┐ │
│ │ ▼ 基础设施层 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ OrderRepo │ │PaymentClient│ │ EventPub │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
级别4: 代码
显示实现细节(类图、序列图)。
在需要时使用标准UML。
可扩展性模式
水平扩展
添加更多相同组件的实例。
负载均衡器
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│实例 │ │实例 │ │实例 │
│ 1 │ │ 2 │ │ 3 │
└─────────┘ └─────────┘ └─────────┘
要求:
- 无状态服务
- 共享会话存储
- 数据库可以处理连接
缓存
减少对慢资源的负载。
┌─────────────────────────────────────────────────────┐
│ 缓存层 │
├─────────────────────────────────────────────────────┤
│ │
│ 浏览器缓存 → CDN → 应用缓存 → 数据库缓存 │
│ │
│ 示例: │
│ - 浏览器: 静态资源、API响应 │
│ - CDN: 静态内容、缓存的API响应 │
│ - 应用: Redis/Memcached用于会话、计算数据│
│ - 数据库: 查询缓存、连接池 │
│ │
└─────────────────────────────────────────────────────┘
缓存失效策略:
- TTL (生存时间): 最简单,最终一致性
- 直写: 写入时更新缓存
- 后写: 异步更新以提高性能
- 缓存旁路: 应用显式管理缓存
数据库扩展
| 策略 | 使用场景 | 权衡 |
|---|---|---|
| 读副本 | 读密集型工作负载 | 复制延迟 |
| 分片 | 大型数据集 | 查询复杂性 |
| 分区 | 时间序列数据 | 分区管理 |
| CQRS | 不同的读/写模式 | 系统复杂性 |
可靠性模式
| 模式 | 目的 | 实现 |
|---|---|---|
| 断路器 | 防止级联故障 | 达到阈值后快速失败 |
| 隔板 | 隔离故障 | 分离线程池 |
| 重试 | 处理瞬态故障 | 指数退避 |
| 超时 | 限制等待时间 | 不要无限等待 |
| 速率限制 | 防止过载 | 节流请求 |
断路器状态:
┌────────┐
│ 关闭 │ ──── 故障阈值 ──► ┌────────┐
│(正常)│ │ 打开 │
└────────┘ │(失败│
▲ └────┬───┘
│ │
成功阈值 超时
│ │
▼ ▼
┌────┴────┐ ┌─────────┐
│半开│ ◄─── 测试请求 ────── │ │
└─────────┘ └─────────┘
技术选择
选择标准
| 标准 | 问题 |
|---|---|
| 适合性 | 它解决实际问题吗? |
| 成熟度 | 生产验证过?社区规模? |
| 团队技能 | 团队能有效使用它吗? |
| 性能 | 满足要求?基准测试? |
| 操作 | 部署、监控、调试有多难? |
| 成本 | 许可、基础设施、学习曲线? |
| 锁定 | 退出策略?标准合规? |
| 安全 | 记录?合规认证? |
评估矩阵
| 技术 | 适合性 | 成熟度 | 技能 | 性能 | 操作 | 成本 | 分数 |
|------------|-----|----------|--------|------|-----|------|-------|
| 选项 A | 4 | 5 | 3 | 4 | 4 | 3 | 3.8 |
| 选项 B | 5 | 3 | 4 | 5 | 2 | 4 | 3.8 |
| 选项 C | 3 | 4 | 5 | 3 | 5 | 5 | 4.2 |
权重: 适合性(25%), 成熟度(15%), 技能(20%), 性能(15%), 操作(15%), 成本(10%)
架构决策记录 (ADRs)
ADR模板
# ADR-[编号]: [标题]
## 状态
[提议 | 接受 | 弃用 | 被ADR-XXX取代]
## 上下文
[我们面临的问题是什么?需要做出什么决策?]
## 决策
[我们提议/做出的改变是什么?]
## 后果
### 正面
- [好处1]
- [好处2]
### 负面
- [权衡1]
- [权衡2]
### 中性
- [观察]
## 考虑的替代方案
### 替代方案1: [名称]
- 优点: [...]
- 缺点: [...]
- 为什么拒绝: [...]
反模式
| 反模式 | 问题 | 解决方案 |
|---|---|---|
| 大泥球 | 没有清晰的架构 | 建立有界上下文 |
| 分布式单体 | 微服务没有独立性 | 真正的服务边界 |
| 简历驱动 | 为经验选择技术 | 将技术匹配到需求 |
| 过早优化 | 在需要之前扩展 | 从简单开始,测量,扩展 |
| 象牙塔 | 架构脱离现实 | 演进式架构 |
| 金锤子 | 每个问题都用相同的解决方案 | 评估每个案例 |