文章 585
评论 5
浏览 226854
架构师都在用的 5 个系统设计决策框架——别再拍脑袋选方案了

架构师都在用的 5 个系统设计决策框架——别再拍脑袋选方案了

一、引言

系统设计中最痛苦的不是"怎么做",而是"选哪个方案"。

面对多个看似可行的技术选型,很多架构师靠直觉和经验做决定,结果上线后发现各种问题。今天我要分享 5 个架构师常用的决策框架,让你的技术选型有理有据。


二、框架一:CAP 三角决策法

2.1 CAP 定理精解

CAP 定理:在分布式系统中,三个特性最多只能同时满足两个:

  • C (Consistency):一致性。所有节点同时看到相同的数据
  • A (Availability):可用性。每个请求都能得到响应,不会超时或失败
  • P (Partition Tolerance):分区容错性。网络分区时系统仍能继续运行

⚠️ 关键澄清:很多人误解 CAP 为"三选二",但 P 在分布式系统中是必须的。网络分区是不可避免的事实,你无法选择"不要 P"。真正的选择是:在发生网络分区时,你是选择 C(一致性)还是 A(可用性)

正常运行时(没有分区),你可以同时拥有 C、A、P。

2.2 CP vs AP 决策矩阵

场景选择理由
银行转账CP数据一致性优先,宁可失败也不能出现资金不一致
电商库存AP可用性优先,显示过期库存比无法下单好(下单时再校验实际库存)
社交动态AP用户体验优先,刷不出最新动态比无法打开好
订单状态CP订单状态必须准确,防止重复下单
缓存系统AP缓存降级时返回过期数据比报错好(缓存未命中时回源数据库)

2.3 实战案例:电商库存系统

场景:大促期间,库存服务需要承受高并发

决策过程:
1. 是否允许分区?→ 是(分布式部署,网络分区不可避免)
2. 分区时优先 C 还是 A?
   - C:库存不一致 → 用户下单后发现没货 → 体验差
   - A:显示过期库存 → 用户下单后校验实际库存 → 可以接受
3. 结论:选择 AP

技术选型:
┌─────────────────────────────────────────────────────┐
│  服务层:Redis(AP,最终一致性)                     │
│          ↓ 异步同步                                 │
│  存储层:MySQL(强一致性)                           │
│          ↓ 库存扣减                                 │
│  校验层:下单时再次检查实际库存                       │
└─────────────────────────────────────────────────────┘

2.4 CAP 决策步骤

步骤 1:确认是否为分布式系统
       → 是 → 继续
       → 否 → CAP 不适用,考虑 ACID

步骤 2:定义业务一致性需求
       → 强一致性?(银行转账、订单状态)
       → 最终一致性?(缓存、消息队列)

步骤 3:分区时的权衡
       → 选择 CP:使用 Zookeeper、Etcd、MySQL
       → 选择 AP:使用 Redis、Cassandra、MongoDB

步骤 4:设计补偿机制
       → CP:设计重试和回滚机制
       → AP:设计最终一致性同步和冲突解决机制

三、框架二:非功能需求优先级矩阵

3.1 四大非功能需求

任何系统设计都需要在四个维度之间做权衡:

维度含义典型需求
性能系统响应速度和吞吐量P99 < 100ms,QPS > 10000
可用性系统正常运行的时间比例99.9%,故障恢复 < 5min
一致性数据的正确性和完整性强一致、最终一致
成本资源投入和运维开销服务器数量、云费用

3.2 权衡关系图

性能
                   ╱ ╲
                  ╱   ╲
                 ╱     ╲
            一致性───────可用性
                 ╲     ╱
                  ╲   ╱
                   ╲ ╱
                    成本

权衡关系:
- 性能 ↑ → 成本 ↑(需要更多资源)
- 一致性 ↑ → 可用性 ↓(需要同步等待)
- 可用性 ↑ → 一致性 ↓(需要容忍过期数据)
- 成本 ↓ → 性能 ↓ / 可用性 ↓(资源不足)

⚠️ 注意:这不是"只能选两个"的硬性规则,而是权衡光谱。你可以在四个维度之间找到平衡点,但提高一个维度通常会牺牲另一个。

3.3 优先级矩阵示例

优先级排序:
┌─────────────────────────────────────────────────────┐
│ 系统类型       │ 优先级 1 │ 优先级 2 │ 优先级 3 │
├─────────────────────────────────────────────────────┤
│ 支付系统       │ 一致性   │ 可用性   │ 性能     │
│ 搜索引擎       │ 性能     │ 可用性   │ 一致性   │
│ 内部管理系统   │ 成本     │ 可用性   │ 性能     │
│ 实时监控系统   │ 性能     │ 一致性   │ 可用性   │
└─────────────────────────────────────────────────────┘

3.4 实战案例:内部管理系统

场景:企业内部的员工管理系统

决策过程:
1. 性能:中等即可,并发量低(< 100 QPS)
2. 可用性:较高,工作时间需要可用(99.5%)
3. 一致性:较高,员工数据不能出错
4. 成本:优先级最高,控制在最小投入

技术选型:
┌─────────────────────────────────────────────────────┐
│ 架构:单体应用(Spring Boot)                       │
│ 数据库:MySQL(单实例,主从备份)                    │
│ 部署:单台服务器(云服务器最低配置)                  │
│ 监控:基础日志(无需复杂监控系统)                    │
└─────────────────────────────────────────────────────┘

权衡说明:
- 牺牲性能:单体架构性能不如微服务,但足够用
- 牺牲高可用:单实例部署,故障时服务中断,但恢复快
- 保证成本:最小资源投入,满足业务需求

四、框架三:"不做清单"法

4.1 为什么"不做清单"很重要

列出"不支持什么"比列出"支持什么"更有价值:

  1. 明确边界:避免无限扩展需求范围
  2. 管理预期:让业务方清楚系统能力边界
  3. 减少返工:避免后续因为遗漏而重做

4.2 "不做清单"示例

系统:电商订单系统

【支持的能力】
├─ 下单、支付、退款
├─ 订单状态查询
├─ 订单导出(CSV)
└─ 订单消息通知

【不支持的能力】
├─ 不支持跨平台订单同步
├─ 不支持订单合并拆分
├─ 不支持批量退款(单次最多 10 笔)
├─ 不支持实时库存扣减(延迟 ≤ 5 秒)
├─ 不支持自定义订单状态
└─ 不支持订单数据修改(只允许新增和查询)

4.3 "不做清单"的类型

类型示例
功能限制单次批量操作上限、文件大小限制
性能限制QPS 上限、响应时间承诺
数据限制数据保留期限、历史数据查询范围
业务限制不支持的业务场景、特殊流程
技术限制不支持的协议、不兼容的版本

4.4 实战案例:消息队列系统

系统:内部消息队列服务

【支持的能力】
├─ 消息生产和消费
├─ 消息持久化
├─ 消息重试(最多 3 次)
├─ 死信队列
└─ 消息追踪

【不做清单】
├─ 不支持事务消息
├─ 不支持消息顺序保证
├─ 不支持消息延迟发送(超过 24 小时)
├─ 不支持跨区域消息同步
├─ 不支持消息广播(只支持点对点)
├─ 不支持消息过滤(消费端全量订阅)
└─ 不支持消息优先级

【后续规划】
├─ V2.0:支持事务消息
├─ V2.1:支持消息顺序保证
└─ V2.2:支持跨区域同步

五、框架四:反模式检查表

5.1 五大常见反模式

在评审方案前,用这 5 个反模式快速自检:

反模式 1:分布式单体

特征:拆分成多个服务,但所有服务共享同一个数据库和配置,部署和发布必须同步。

检测信号

  • "我们有 10 个微服务,但每次发布都要一起上线"
  • "某个服务出问题,所有服务都挂了"
  • "数据库连接池经常被占满"

解决方案

  • 每个服务独立数据库
  • 服务间通过 API 或消息队列通信
  • 支持独立部署和发布

反模式 2:共享数据库

特征:多个服务直接访问同一个数据库表,绕过服务边界。

检测信号

  • "服务 A 需要查服务 B 的数据,直接连数据库查"
  • "数据库表越来越多,没人知道谁在用"
  • "改一张表需要协调 5 个团队"

解决方案

  • 每个服务只访问自己的数据库
  • 通过 API 获取其他服务的数据
  • 使用共享视图或数据同步机制

反模式 3:聊天式微服务

特征:服务间调用链过长,一个请求需要经过 5+ 个服务。

检测信号

  • "用户打开一个页面需要调用 8 个服务"
  • "P99 响应时间 500ms,但单个服务都很快"
  • "链路追踪图像蜘蛛网"

解决方案

  • 合并细粒度服务
  • 使用聚合层(API Gateway)
  • 引入本地缓存减少调用

反模式 4:上帝服务

特征:一个服务承担了所有核心业务逻辑,其他服务只是空壳。

检测信号

  • "订单服务包含了支付、库存、物流逻辑"
  • "90% 的代码都在一个服务里"
  • "每次发布都怕影响核心功能"

解决方案

  • 按业务边界拆分
  • 识别核心领域和支撑领域
  • 逐步迁移非核心功能

反模式 5:过早优化

特征:在需求不明确的阶段投入大量精力做架构优化。

检测信号

  • "我们需要设计一个支持百万级 QPS 的系统"
  • "现在只有 100 个用户,但要做分布式"
  • "为了可能的需求预留了很多扩展点"

解决方案

  • YAGNI 原则(You Ain't Gonna Need It)
  • 先满足当前需求,再逐步优化
  • 使用简单方案,预留扩展接口

5.2 自检清单

评审前快速检查:
✅ 是否存在分布式单体?(所有服务共享数据库?)
✅ 是否存在共享数据库?(服务直接访问其他服务的表?)
✅ 是否存在聊天式微服务?(调用链 > 5 个服务?)
✅ 是否存在上帝服务?(一个服务承担所有核心逻辑?)
✅ 是否存在过早优化?(为不确定的需求做了大量设计?)

如果有任何一项为"是",需要重新审视方案!

六、框架五:N-1 降级法

6.1 什么是 N-1 降级

N-1 降级:设计系统时,明确"最坏情况下可以砍掉哪些功能",确保核心业务在极端条件下仍能运行。

6.2 降级策略层级

降级策略:
┌─────────────────────────────────────────────────────┐
│ 层级 1:核心功能(不可降级)                         │
│         └─ 下单、支付、库存扣减                      │
│                                                     │
│ 层级 2:重要功能(可降级为基础版)                    │
│         └─ 推荐商品 → 返回默认推荐                   │
│         └─ 优惠券计算 → 使用默认值                   │
│                                                     │
│ 层级 3:辅助功能(可完全关闭)                        │
│         └─ 商品详情页缓存                           │
│         └─ 用户行为分析                             │
│         └─ 非关键日志                               │
│                                                     │
│ 层级 4:可选功能(优先关闭)                         │
│         └─ 营销活动页面                             │
│         └─ 非核心数据统计                           │
└─────────────────────────────────────────────────────┘

6.3 降级实现方式

方式适用场景实现手段
断路器外部服务调用Sentinel、Hystrix
特性开关功能级降级LaunchDarkly、自研开关
限流降级高并发场景Nginx、Sentinel
缓存降级数据库压力Redis 返回过期数据
队列降级消息堆积丢弃非关键消息

6.4 实战案例:电商大促降级方案

场景:双 11 大促,流量预计是平时的 10 倍

降级方案设计:
┌─────────────────────────────────────────────────────┐
│ 正常状态(N):所有功能可用                          │
│                                                     │
│ N-1 状态(高负载):关闭非核心功能                    │
│ ├─ 关闭营销活动页面                                  │
│ ├─ 关闭用户行为分析                                  │
│ ├─ 关闭非核心数据统计                                │
│ └─ 推荐商品返回默认列表                              │
│                                                     │
│ N-2 状态(极高负载):进一步降级                      │
│ ├─ 优惠券计算使用缓存值                              │
│ ├─ 商品详情页返回简化版                              │
│ ├─ 关闭商品搜索(返回热门商品)                       │
│ └─ 限流非核心接口                                    │
│                                                     │
│ N-3 状态(极端负载):核心功能降级                    │
│ ├─ 库存查询返回缓存值                                │
│ ├─ 关闭退款功能                                      │
│ └─ 只保留下单和支付                                  │
└─────────────────────────────────────────────────────┘

触发条件:
┌─────────────────────────────────────────────────────┐
│ 指标              │ N-1 阈值   │ N-2 阈值   │ N-3 阈值 │
├─────────────────────────────────────────────────────┤
│ CPU 使用率        │ 70%        │ 85%        │ 95%      │
│ 内存使用率        │ 75%        │ 88%        │ 95%      │
│ 请求延迟 P99      │ 500ms      │ 1000ms     │ 2000ms   │
│ 数据库连接数      │ 80%        │ 90%        │ 95%      │
└─────────────────────────────────────────────────────┘

6.5 降级设计步骤

步骤 1:识别核心功能
       → 哪些功能是业务必须的?
       → 哪些功能可以暂时关闭?

步骤 2:定义降级层级
       → N-1:最小降级(关闭辅助功能)
       → N-2:中等降级(核心功能降级)
       → N-3:极端降级(只保留最核心)

步骤 3:设置触发条件
       → 基于监控指标(CPU、内存、延迟、错误率)
       → 自动触发或手动触发

步骤 4:设计恢复策略
       → 自动恢复(指标恢复正常后)
       → 手动恢复(需要人工确认)

步骤 5:编写降级文档
       → 每个层级的降级内容
       → 触发条件和恢复策略
       → 操作步骤和责任人

七、框架对比总结

7.1 决策框架对比

框架核心维度适用场景输出结果
CAP一致性 vs 可用性分布式系统选型CP 或 AP 技术栈
非功能优先级性能/可用性/一致性/成本系统整体设计优先级排序
不做清单功能边界需求定义明确的能力边界
反模式检查架构质量方案评审发现潜在问题
N-1 降级故障应对高可用设计降级策略文档

7.2 决策流程

完整决策流程:
┌─────────────────────────────────────────────────────┐
│ 1. 需求分析                                          │
│    └─ 使用"不做清单"明确边界                          │
│                                                     │
│ 2. 架构选型                                          │
│    └─ 使用 CAP 定理决定一致性模型                      │
│    └─ 使用非功能优先级矩阵权衡                        │
│                                                     │
│ 3. 方案评审                                          │
│    └─ 使用反模式检查表自检                            │
│                                                     │
│ 4. 高可用设计                                        │
│    └─ 使用 N-1 降级法设计容错方案                      │
│                                                     │
│ 5. 迭代优化                                          │
│    └─ 根据实际运行数据调整                            │
└─────────────────────────────────────────────────────┘

7.3 核心原则

  1. 没有银弹:每个框架都有适用场景,没有万能方案
  2. 数据驱动:基于实际指标做决策,不是拍脑袋
  3. 文档化:把决策过程和理由写下来,便于后续追溯
  4. 灵活性:方案要能适应变化,不要过度设计

八、总结

五个框架的核心价值

框架解决什么问题
CAP分布式系统中一致性和可用性的权衡
非功能优先级多个非功能需求之间的取舍
不做清单明确系统能力边界,避免需求膨胀
反模式检查在方案评审阶段发现潜在问题
N-1 降级确保系统在极端条件下仍能运行

架构师的核心能力

架构师不是技术专家,而是决策专家。好的决策框架能帮助你:

  1. 系统化思考:避免遗漏关键因素
  2. 有理有据:决策过程可追溯、可验证
  3. 减少风险:提前发现问题,避免事后补救

💡 互动话题:你在系统设计中常用哪些决策方法?有没有遇到过因为决策失误导致的问题?欢迎在评论区分享你的经验!


标题:架构师都在用的 5 个系统设计决策框架——别再拍脑袋选方案了
作者:jiangyi
地址:http://jiangyi.space/articles/2026/07/15/1783847403917.html
公众号:服务端技术精选

服务端开发博客:后端架构、高并发、性能优化与微服务实战教程

取消