架构决策记录Skill architecture-decision-records

这个技能用于编写、管理和维护架构决策记录(ADRs),帮助团队捕获重要技术决策的背景、选项、决策理由和后果。适用于文档化技术选择、记录设计权衡、新成员培训、历史决策回顾和建立决策流程。关键词包括:架构决策记录、ADR、技术文档、软件开发、架构设计、决策流程。

架构设计 0 次安装 0 次浏览 更新于 3/22/2026

name: 架构决策记录 description: 编写和维护架构决策记录(ADRs),遵循技术决策文档化的最佳实践。适用于记录重要技术决策、回顾过往架构选择或建立决策流程。 license: MIT metadata: version: “1.0.0” domain: 架构 triggers: ADR, 架构决策记录, 技术决策, 决策文档化 role: 架构师 scope: 系统设计 output-format: 架构 related-skills: 架构模式

架构决策记录

创建、维护和管理架构决策记录(ADRs)的综合模式,捕获重要技术决策的背景和理由。

使用此技能的时机

  • 做出重要架构决策
  • 文档化技术选择
  • 记录设计权衡
  • 新团队成员入职
  • 回顾历史决策
  • 建立决策流程

不应使用此技能的时机

  • 只需记录小的实现细节
  • 更改是小的补丁或日常维护
  • 没有架构决策需要捕获

指令

  1. 捕获决策背景、约束和驱动因素。
  2. 文档化考虑的选项及其权衡。
  3. 记录决策、理由和后果。
  4. 链接相关ADRs并随时间更新状态。

核心概念

1. 什么是ADR?

一个架构决策记录捕获:

  • 背景:为什么需要做出决策
  • 决策:我们决定了什么
  • 后果:结果会发生什么

2. 何时编写ADR

编写ADR 跳过ADR
新框架采用 次要版本升级
数据库技术选择 错误修复
API设计模式 实现细节
安全架构 日常维护
集成模式 配置更改

3. ADR生命周期

提议 → 接受 → 弃用 → 被取代
              ↓
           拒绝

模板

模板1:标准ADR(MADR格式)

# ADR-0001: 使用PostgreSQL作为主数据库

## 状态

已接受

## 背景

我们需要为新电商平台选择主数据库。系统将处理:
- 约10,000并发用户
- 具有层次类别的复杂产品目录
- 订单和支付的交易处理
- 产品的全文搜索
- 商店定位的地理空间查询

团队有MySQL、PostgreSQL和MongoDB的经验。我们需要金融交易的ACID合规性。

## 决策驱动因素

* **必须有ACID合规性** 用于支付处理
* **必须支持复杂查询** 用于报告
* **应支持全文搜索** 以减少基础设施复杂性
* **应有良好的JSON支持** 用于灵活的产品属性
* **团队熟悉度** 减少上手时间

## 考虑选项

### 选项1: PostgreSQL
- **优点**: ACID合规,优秀的JSON支持(JSONB),内置全文搜索,PostGIS用于地理空间,团队有经验
- **缺点**: 复制设置比MySQL略复杂

### 选项2: MySQL
- **优点**: 团队非常熟悉,简单复制,大型社区
- **缺点**: JSON支持较弱,无内置全文搜索(需要Elasticsearch),无扩展无地理空间

### 选项3: MongoDB
- **优点**: 灵活模式,原生JSON,水平扩展
- **缺点**: 无多文档事务的ACID(在决策时),团队经验有限,需要模式设计纪律

## 决策

我们将使用**PostgreSQL 15**作为主数据库。

## 理由

PostgreSQL提供了最佳平衡:
1. **ACID合规性** 对电商交易至关重要
2. **内置能力**(全文搜索、JSONB、PostGIS)减少基础设施复杂性
3. **团队熟悉度** 对SQL数据库减少学习曲线
4. **成熟生态系统** 有优秀的工具和社区支持

复制的小复杂性被减少额外服务(无需单独的Elasticsearch)所抵消。

## 后果

### 积极
- 单一数据库处理交易、搜索和地理空间查询
- 减少运营复杂性(管理服务较少)
- 金融数据的强一致性保证
- 团队可杠杆现有SQL专业知识

### 消极
- 需要学习PostgreSQL特定功能(JSONB、全文搜索语法)
- 垂直扩展限制可能较早需要读副本
- 一些团队成员需要PostgreSQL特定培训

### 风险
- 全文搜索可能不如专用搜索引擎扩展性好
- 缓解:设计为可能需要的Elasticsearch添加

## 实现说明

- 使用JSONB用于灵活的产品属性
- 用PgBouncer实现连接池
- 设置流复制用于读副本
- 使用pg_trgm扩展用于模糊搜索

## 相关决策

- ADR-0002: 缓存策略(Redis)- 补充数据库选择
- ADR-0005: 搜索架构- 如果需Elasticsearch可能被取代

## 参考

- [PostgreSQL JSON文档](https://www.postgresql.org/docs/current/datatype-json.html)
- [PostgreSQL全文搜索](https://www.postgresql.org/docs/current/textsearch.html)
- 内部:性能基准在`/docs/benchmarks/database-comparison.md`

模板2:轻量级ADR

# ADR-0012: 采用TypeScript进行前端开发

**状态**: 已接受
**日期**: 2024-01-15
**决策者**: @alice, @bob, @charlie

## 背景

我们的React代码库已增长至50多个组件,错误报告增加,涉及prop类型不匹配和未定义错误。PropTypes仅提供运行时检查。

## 决策

采用TypeScript用于所有新前端代码。逐步迁移现有代码。

## 后果

**好**: 编译时捕获类型错误,更好的IDE支持,自我文档化代码。

**坏**: 团队学习曲线,初始速度减慢,构建复杂性增加。

**缓解措施**: TypeScript培训课程,允许逐步采用`allowJs: true`。

模板3: Y-Statement格式

# ADR-0015: API网关选择

在**构建微服务架构**的背景下,
面对**需要集中式API管理、认证和速率限制**,
我们决定选择**Kong网关**
而非**AWS API网关和自定义Nginx解决方案**,
以实现**供应商独立、插件可扩展性和团队对Lua的熟悉度**,
接受**我们需要自己管理Kong基础设施**。

模板4: 弃用ADR

# ADR-0020: 弃用MongoDB,改用PostgreSQL

## 状态

已接受(取代ADR-0003)

## 背景

ADR-0003(2021)因模式灵活性需求选择MongoDB用于用户配置文件存储。自那时以来:
- MongoDB的多文档事务对我们的用例仍有问题
- 我们的模式已稳定并很少更改
- 我们现在从其他服务获得PostgreSQL专业知识
- 维护两个数据库增加运营负担

## 决策

弃用MongoDB并迁移用户配置文件到PostgreSQL。

## 迁移计划

1. **阶段1**(第1-2周):创建PostgreSQL模式,启用双写
2. **阶段2**(第3-4周):回填历史数据,验证一致性
3. **阶段3**(第5周):切换读到PostgreSQL,监控
4. **阶段4**(第6周):移除MongoDB写,停用

## 后果

### 积极
- 单一数据库技术减少运营复杂性
- 用户数据的ACID事务
- 团队可聚焦PostgreSQL专业知识

### 消极
- 迁移努力(约4周)
- 迁移期间数据问题风险
- 失去一些模式灵活性

## 学到的教训

从ADR-0003经验文档化:
- 模式灵活性益处被高估
- 多数据库的运营成本被低估
- 在技术决策中考虑长期维护

模板5: 征求意见(RFC)风格

# RFC-0025: 为订单管理采用事件溯源

## 总结

提议为订单管理领域采用事件溯源模式,以提高可审计性、启用时间查询和支持业务分析。

## 动机

当前挑战:
1. 审计要求需要完整订单历史
2. “在时间X订单状态是什么?”查询不可能
3. 分析团队需要事件流用于实时仪表板
4. 客户支持的订单状态重建是手动的

## 详细设计

### 事件存储

订单创建 { 订单Id, 客户Id, 物品[], 时间戳 } 订单物品添加 { 订单Id, 物品, 时间戳 } 订单物品移除 { 订单Id, 物品Id, 时间戳 } 付款接收 { 订单Id, 金额, 付款Id, 时间戳 } 订单发货 { 订单Id, 跟踪号码, 时间戳 }


### 投影

- **当前订单状态**: 用于查询的物化视图
- **订单历史**: 完整时间线用于审计
- **每日订单指标**: 分析聚合

### 技术

- 事件存储: EventStoreDB(专门构建,处理投影)
- 考虑的替代: Kafka + 自定义投影服务

## 缺点

- 团队学习曲线
- 复杂性增加 vs. CRUD
- 需要精心设计事件(存储后不可变)
- 存储增长(事件从不删除)

## 替代方案

1. **审计表**: 更简单但无法启用时间查询
2. **CDC从现有数据库**: 复杂,不改变数据模型
3. **混合**: 仅事件源用于订单状态更改

## 未解决问题

- [ ] 事件模式版本控制策略
- [ ] 事件保留策略
- [ ] 性能的快照频率

## 实现计划

1. 原型单个订单类型(2周)
2. 团队事件溯源培训(1周)
3. 完全实现和迁移(4周)
4. 监控和优化(持续)

## 参考

- [Martin Fowler的事件溯源](https://martinfowler.com/eaaDev/EventSourcing.html)
- [EventStoreDB文档](https://www.eventstore.com/docs)

ADR管理

目录结构

docs/
├── adr/
│   ├── README.md           # 索引和指南
│   ├── template.md         # 团队的ADR模板
│   ├── 0001-use-postgresql.md
│   ├── 0002-caching-strategy.md
│   ├── 0003-mongodb-user-profiles.md  # [弃用]
│   └── 0020-deprecate-mongodb.md      # 取代0003

ADR索引(README.md

# 架构决策记录

此目录包含[项目名称]的架构决策记录(ADRs)。

## 索引

| ADR | 标题 | 状态 | 日期 |
|-----|-------|--------|------|
| [0001](0001-use-postgresql.md) | 使用PostgreSQL作为主数据库 | 已接受 | 2024-01-10 |
| [0002](0002-caching-strategy.md) | 缓存策略与Redis | 已接受 | 2024-01-12 |
| [0003](0003-mongodb-user-profiles.md) | MongoDB用于用户配置文件 | 弃用 | 2023-06-15 |
| [0020](0020-deprecate-mongodb.md) | 弃用MongoDB | 已接受 | 2024-01-15 |

## 创建新ADR

1. 复制`template.md`到`NNNN-title-with-dashes.md`
2. 填写模板
3. 提交PR以供审查
4. 批准后更新此索引

## ADR状态

- **提议**: 正在讨论
- **已接受**: 决策已做,正在实施
- **弃用**: 不再相关
- **被取代**: 被另一个ADR取代
- **拒绝**: 考虑过但未采纳

自动化(adr-tools)

# 安装adr-tools
brew install adr-tools

# 初始化ADR目录
adr init docs/adr

# 创建新ADR
adr new "使用PostgreSQL作为主数据库"

# 取代ADR
adr new -s 3 "弃用MongoDB,改用PostgreSQL"

# 生成目录表
adr generate toc > docs/adr/README.md

# 链接相关ADRs
adr link 2 "补充" 1 "被补充"

审查流程

## ADR审查清单

### 提交前
- [ ] 背景清楚解释问题
- [ ] 所有可行选项已考虑
- [ ] 优点/缺点平衡且诚实
- [ ] 后果(积极和消极)已文档化
- [ ] 相关ADRs已链接

### 审查期间
- [ ] 至少2名高级工程师审查
- [ ] 已咨询受影响团队
- [ ] 已考虑安全影响
- [ ] 成本影响已文档化
- [ ] 已评估可逆性

### 接受后
- [ ] ADR索引已更新
- [ ] 团队已通知
- [ ] 实施票证已创建
- [ ] 相关文档已更新

最佳实践

应做

  • 尽早编写ADRs - 在实施开始前
  • 保持简短 - 最多1-2页
  • 诚实对待权衡 - 包括真实缺点
  • 链接相关决策 - 构建决策图
  • 更新状态 - 弃用时取代

不应做

  • 不要更改已接受的ADRs - 编写新的来取代
  • 不要跳过背景 - 未来读者需要背景
  • 不要隐藏失败 - 拒绝的决策有价值
  • 不要含糊 - 具体决策,具体后果
  • 不要忘记实施 - 无行动的ADR是浪费

资源