原则:能写代码的人很多,能设计系统的人很少。 高并发设计 + DDD 领域建模 + 技术方案评审 = 高级工程师的核心竞争力。
一、高并发系统设计(★★★★★)
1.1 秒杀系统完整方案
秒杀系统的核心矛盾:极少量库存 vs 海量并发请求
设计分层(从前到后):
┌─────────────────────────────────────────────┐
│ 第 1 层:前端限流 │
│ ├── 按钮置灰(点击后 5 秒内不可再点) │
│ └── 验证码/滑块(过滤脚本和机器请求) │
├─────────────────────────────────────────────┤
│ 第 2 层:网关限流 │
│ ├── Nginx 限流(limit_req_zone) │
│ └── Gateway 令牌桶限流(Sentinel) │
├─────────────────────────────────────────────┤
│ 第 3 层:应用层 │
│ ├── Redis 预减库存(Lua 脚本原子操作) │
│ ├── 内存标记(商品售罄后不再查 Redis) │
│ └── 消息队列异步下单(削峰填谷) │
├─────────────────────────────────────────────┤
│ 第 4 层:数据库层 │
│ └── 最终扣减库存(UPDATE ... WHERE stock > 0) │
├─────────────────────────────────────────────┤
│ 辅助措施: │
│ ├── CDN 静态化(商品详情页提前静态化) │
│ ├── Redis 缓存预热(秒杀开始前加载库存到 Redis) │
│ ├── 隔离部署(秒杀服务独立部署,不影响主流程) │
│ └── 降级预案(秒杀失败降级为排队等待) │
└─────────────────────────────────────────────┘1.2 库存扣减方案对比
方案 A:Redis 扣减 → MQ 异步同步到 DB
优点:性能最高
缺点:Redis 和 DB 数据可能不一致
方案 B:数据库直接扣减(UPDATE ... WHERE stock > 0)
优点:数据强一致
缺点:数据库压力大
方案 C:Redis Lua 原子扣减 + DB 最终扣减(推荐)
1. 秒杀开始前:预热库存到 Redis
2. 秒杀中:Redis Lua 脚本原子扣减
3. 秒杀后:MQ 异步同步到 DB,DB 做最终一致性兜底1.3 性能优化三层模型
┌──────────┬──────────────────────────────┐
│ 层级 │ 优化手段 │
├──────────┼──────────────────────────────┤
│ 代码层 │ 减少循环嵌套、异步并行、连接池 │
│ │ N+1 问题、Stream 并行流 │
├──────────┼──────────────────────────────┤
│ 缓存层 │ Redis 热数据缓存、本地缓存 │
│ │ Caffeine、多级缓存 │
├──────────┼──────────────────────────────┤
│ 数据库层 │ 索引优化、SQL 优化、读写分离 │
│ │ 分库分表、连接池配置 │
└──────────┴──────────────────────────────┘
优化思路:永远从最上层开始,缓存能解决的不要动数据库,
代码能解决的不要加机器。二、高可用架构设计
2.1 可用性保障手段
1. 冗余部署:多实例 + 多机房(消除单点故障)
2. 故障转移:健康检查 + 自动摘除故障节点
3. 超时控制:调用下游设置合理超时,避免级联阻塞
4. 重试机制:幂等 + 退避策略(指数退避,最大重试次数)
5. 服务降级:非核心功能自动关闭(如推荐系统故障降级为热门推荐)
6. 熔断:慢调用/异常比例超过阈值 → 快速失败
7. 限流:令牌桶/漏桶,保护系统不被突发流量打垮
8. 容灾:异地多活/两地三中心2.2 可用性指标
| 等级 | 全年不可用时间 | 可用性 |
|---|---|---|
| 3 个 9 | < 8.76 小时 | 99.9% |
| 4 个 9 | < 52.6 分钟 | 99.99% |
| 5 个 9 | < 5.26 分钟 | 99.999% |
4 个 9 是大多数互联网公司的目标。
三、DDD 领域驱动设计(★★★★☆)
3.1 核心概念
战略设计(宏观):
- 限界上下文(Bounded Context):业务边界,微服务拆分的依据
- 上下文映射(Context Map):限界上下文之间的关系
- 共享内核(Shared Kernel)
- 客户-供应商(Customer-Supplier)
- 防腐层(Anti-Corruption Layer)
- 开放主机服务(Open Host Service)
战术设计(微观):
- 聚合根(Aggregate Root):聚合的唯一入口,保证业务规则
- 实体(Entity):有唯一标识,可变
- 值对象(Value Object):无标识,不可变(如金额、地址)
- 领域服务(Domain Service):跨聚合的业务逻辑
- 仓储(Repository):聚合的持久化接口
- 领域事件(Domain Event):领域中发生的有意义的事件3.2 电商系统 DDD 建模示例
限界上下文划分:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户上下文 │ │ 订单上下文 │ │ 商品上下文 │ │ 支付上下文 │
│ User │ │ Order │ │ Product │ │ Payment │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
订单上下文内部(聚合设计):
Order(聚合根)
├── OrderItem(实体,订单项)
├── OrderAddress(值对象,收货地址)
└── OrderEvent(领域事件,订单已创建/已支付/已发货)
关键规则:
- 外部只能通过聚合根操作聚合内部实体
- 一个事务只修改一个聚合
- 聚合之间通过领域事件异步通信四、技术方案评审
4.1 方案文档结构
# [项目名称] 技术方案
## 1. 需求背景
- 业务痛点
- 核心指标(QPS/响应时间/数据量)
## 2. 方案对比
| 方案 | 优点 | 缺点 | 风险 |
|------|------|------|------|
| 方案 A | ... | ... | ... |
| 方案 B | ... | ... | ... |
| 推荐方案:方案 X,理由:...
## 3. 详细设计
- 系统架构图(用 draw.io 或 PlantUML)
- 核心流程图/时序图
- 数据库表设计(ER 图)
- 接口定义(请求/响应格式)
## 4. 关键决策
| 决策点 | 选项 | 选择 | 理由 |
|--------|------|------|------|
## 5. 风险评估
| 风险 | 概率 | 影响 | 应对措施 |
|------|------|------|---------|
## 6. 上线计划
- 灰度策略
- 监控告警
- 回滚方案4.2 评审发言框架
当别人评审你的方案时:
1. 讲背景,不讲细节:"这个问题的本质是..."
2. 讲权衡,不讲完美:"方案 A 更快但一致性弱,方案 B 一致但慢"
3. 讲风险,不讲理想:"最坏情况下可能发生..."
4. 讲数据,不讲感觉:"压测数据显示 QPS 从 1000 提升到 3000"
当你评审别人的方案时:
1. 先理解业务需求,再评价技术方案
2. 提问代替结论:"这里考虑过 XX 情况吗?"
3. 关注边界条件和异常路径
4. 给建设性建议,不只说"不好"面试自查清单
□ 秒杀系统的 4 层架构能画出来(前端→网关→应用→数据库)
□ 库存扣减 3 种方案的优缺点和选型依据
□ 4 个 9 可用性 = 全年不可用 < 52.6 分钟
□ DDD 聚合根、实体、值对象的区别 + 仓储的作用
□ 上下文映射的 4 种关系能各举例一个
□ 技术方案文档的标准结构(6 部分)
□ 性能优化的三层模型(代码→缓存→数据库)