架构设计
架构设计 #
本文档整理了分布式系统与架构设计的核心知识点,适用于Java后端架构师面试准备。
📚 学习路径 #
一、消息与流处理系统 #
Apache Kafka #
面试高频 ⭐⭐⭐⭐⭐
核心设计亮点 #
| 特性 | 技术实现 | 面试考点 |
|---|---|---|
| 高吞吐 | 顺序读写磁盘 + 零拷贝(Zero-Copy) | 如何实现百万级TPS? |
| 持久化 | Topic分区存储 | 消息如何保证不丢失? |
| 水平扩展 | Partition + Broker集群 | 如何扩容? |
| 消费者组 | 多消费者并行消费 | Rebalance机制是什么? |
学习价值 #
- 分布式日志存储
- 生产者-消费者解耦
- 大规模数据管道设计
Apache Pulsar #
核心设计亮点 #
架构特点:
- 分层存储: Broker(计算) 与 BookKeeper(存储) 分离
- 多租户: Tenant + Namespace 资源隔离
- 高性能: 支持多种订阅模式
学习价值 #
- 云原生消息系统的分层架构
- 多租户支持实现
Kafka vs Pulsar #
| 对比维度 | Kafka | Pulsar |
|---|---|---|
| 架构模式 | 紧耦合 | 分层存储 |
| 运维复杂度 | 较低 | 较高 |
| 多租户 | 社区版弱 | 原生支持 |
二、分布式数据库与存储 #
Apache Cassandra #
CAP理论实践 ⭐⭐⭐⭐
核心设计亮点 #
技术要点 #
| 设计选项 | 实现方式 |
|---|---|
| 分片策略 | 一致性哈希(Consistent Hashing) |
| 一致性级别 | ONE、QUORUM、ALL 可配置 |
| 副本复制 | 异步多副本 |
学习价值 #
- 无中心化分布式存储设计
- CAP权衡实践
CockroachDB #
分布式SQL数据库 ⭐⭐⭐⭐
核心设计亮点 #
特性:
- 全局一致性: 基于Raft协议
- SQL兼容: 兼容PostgreSQL协议
- 自动分片: Range分片 + 自动迁移热点
学习价值 #
- 分布式SQL数据库实现
- 多数据中心容灾
Amazon DynamoDB #
Serverless数据库典范 ⭐⭐⭐
核心设计亮点 #
- 存储引擎:LSM树优化
- 索引:全局二级索引
- 扩展:按需吞吐量和存储
学习价值 #
- Serverless数据库设计
- 存储引擎优化
三、分布式协调与服务发现 #
Apache ZooKeeper #
核心组件源码学习 ⭐⭐⭐⭐⭐
核心设计亮点 #
| 机制 | 用途 | 应用场景 |
|---|---|---|
| ZAB协议 | 强一致性保证 | leader选举 |
| 临时节点 | 服务存活检测 | 服务注册发现 |
| Watcher | 事件驱动 | 配置中心 |
典型应用场景 #
// 分布式锁实现示例
public class DistributedLock {
// 实现要点:
// 1. 创建临时顺序节点
// 2. 获取比自己小的节点
// 3. 监听前一节点的删除事件
}
学习价值 #
- 分布式锁
- 选主算法
- 配置管理
etcd #
Kubernetes核心 ⭐⭐⭐⭐
核心设计亮点 #
对比 ZooKeeper #
| 特性 | ZooKeeper | etcd |
|---|---|---|
| 协议 | ZAB | Raft |
| 性能 | 较低 | 更高 |
| API风格 | 复杂 | 简洁RESTful |
四、服务网格与流量治理 #
Istio #
微服务治理标准 ⭐⭐⭐⭐
核心设计亮点 #
学习价值 #
- 微服务流量治理
- 可观测性
- 安全(mTLS)标准化实现
Netflix Hystrix #
容错设计模式 ⭐⭐⭐⭐
核心设计亮点 #
核心机制 #
| 机制 | 目的 |
|---|---|
| 熔断 | 防止级联故障 |
| 降级 | 保证核心可用 |
| 资源隔离 | 线程池/信号量隔离 |
五、大数据与计算引擎 #
Apache Flink #
流批一体 ⭐⭐⭐⭐
核心设计亮点 #
特点:
- 流批一体: 统一API处理流批
- 状态管理: Exactly-Once语义
- 容错机制: Chandy-Lamport算法
学习价值 #
- 流式计算引擎容错
- 状态管理最佳实践
Google Bigtable #
NoSQL鼻祖 ⭐⭐⭐
核心设计亮点 #
- 存储引擎:LSM树(高写入吞吐)
- 元数据管理:Chubby协调
- 数据组织:列族(Column Family)
学习价值 #
- 分布式NoSQL底层引擎设计
六、云原生基础设施 #
Kubernetes #
容器编排金标准 ⭐⭐⭐⭐⭐
架构核心 #
核心概念速查 #
| 概念 | 描述 | 面试要点 |
|---|---|---|
| Pod | 最小调度单元 | 为什么需要Pod? |
| Service | 服务发现/负载均衡 | ClusterIP/NodePort/LoadBalancer |
| Deployment | 声明式应用管理 | RollingUpdate策略 |
| Ingress | HTTP/S路由 | 与NodePort区别 |
| Operator | 有状态应用管理 | CRD + Controller模式 |
学习价值 #
- 声明式API设计
- 控制器模式
- 扩展机制
Envoy #
七层代理 ⭐⭐⭐⭐
核心设计亮点 #
卖点:
- 热更新: xDS协议动态配置
- 协议支持: HTTP/2, gRPC
- 可观测性: Metrics/Tracing/Access Log
学习价值 #
- 高性能代理设计
- 服务网格数据平面实现
七、经典闭源系统 #
Google Spanner #
全球强一致性 ⭐⭐⭐⭐⭐
核心设计亮点 #
学习价值 #
- 全球强一致性数据库
- 时钟同步机制
Amazon S3 #
对象存储标杆 ⭐⭐⭐⭐
核心设计亮点 #
| 特性 | 实现 |
|---|---|
| 一致性模型 | Quorum机制(3副本写2成功) |
| 扩展性 | 分片 + 前缀哈希 |
| 高可用 | 跨区域复制 |
🔧 学习建议 #
从论文入手 #
| 系统 | 论文 | 难度 |
|---|---|---|
| Bigtable | Bigtable: A Distributed Storage System | ⭐⭐⭐ |
| Spanner | Spanner: Google's Globally-Distributed Database | ⭐⭐⭐⭐ |
| DynamoDB | Dynamo: Amazon's Highly Available Key-value Store | ⭐⭐ |
| Raft | In Search of an Understandable Consensus Algorithm | ⭐⭐⭐ |
阅读源码 #
推荐深入阅读的开源项目:
动手实践 #
// 1. 用ZooKeeper实现分布式锁
public class ZKDistributedLock {}
// 2. 实现简易Raft算法
public class SimpleRaft {}
// 3. 实现一致性哈希
public class ConsistentHash {}
关注Trade-off #
每个系统都是权衡的结果:
📝 面试高频问题汇总 #
消息队列 #
- Kafka高性能原理
- 消息不丢失/不重复/顺序消费
- Kafka Rebalance机制
分布式事务 #
- CAP理论与BASE
- 2PC/3PC/TCC/Saga对比
- 分布式事务XA方案
高可用 #
- 服务熔断降级方案
- 限流算法(令牌桶/漏桶/滑动窗口)
- 故障转移与灾备设计
📝 面试题答案详解 #
消息队列篇 #
1. Kafka高性能原理 #
答案:
Kafka高性能来源于多层优化:
| 优化技术 | 原理 | 性能提升 |
|---|---|---|
| 顺序读写磁盘 | Kafka数据追加写入,避免随机IO | 10倍+ |
| 零拷贝技术 | 直接从内核缓冲区到网卡,减少拷贝次数 | 减少2-3次数据拷贝 |
| 批量发送 | 多条消息合并为Batch发送 | 减少网络IO次数 |
| Page Cache | 利用操作系统页缓存,不强制flush | 减少磁盘IO |
| 压缩传输 | Gzip/Snappy/LZ4/Zstd压缩 | 减少网络传输量 |
| 分区并行 | Topic分为多个Partition,并行消费 | 吞吐量线性提升 |
顺序读写 vs 随机读写:
机械硬盘:
顺序读: ~500MB/s
随机读: ~5MB/s (慢100倍!)
顺序写: ~300MB/s
随机写: ~3MB/s
2. 消息不丢失/不重复/顺序消费 #
答案:
(1) 消息不丢失保证 #
三端保证:
| 端 | 保证措施 | 配置 |
|---|---|---|
| 生产者端 | ACK等待所有副本确认 | acks=all, retries=Integer.MAX_VALUE |
| Broker端 | 副本机制 ≥2 | replication.factor ≥ 2 |
| 消费者端 | 关闭自动提交offset | enable.auto.commit=false |
代码示例:
// 生产者配置
Properties props = new Properties();
props.put("acks", "all"); // 等待所有副本确认
props.put("retries", Integer.MAX_VALUE); // 无限重试
props.put("enable.idempotence", "true"); // 幂等性
// 消费者配置
enable.auto.commit = false; // 关闭自动提交
// 业务逻辑处理成功后手动提交
consumer.commitSync();
(2) 消息不重复消费 #
幂等性设计:
| 方案 | 实现 | 适用场景 |
|---|---|---|
| 唯一索引 | MySQL唯一键约束 | 数据库操作 |
| 分布式锁 | Redis SETNX 或 Zookeeper | 任意场景 |
| 幂等表 | 记录已处理消息ID | 通用方案 |
| 版本号 | 乐观锁机制 | 更新操作 |
代码示例:
// Redis记录已处理消息
String messageId = record.key();
Boolean isNew = redisOps.opsForValue().setIfAbsent("msg:" + messageId, "1", 3600, TimeUnit.SECONDS);
if (!isNew) {
return; // 已处理,跳过
}
// 幂等表方案
INSERT INTO idempotent (message_id, create_time) VALUES (?, ?);
-- 唯一索引冲突说明已处理
(3) 消息顺序性保证 #
Kafka默认:
- 分区内有序,分区间无序
全局有序方案:
| 方案 | 实现 | 优缺点 |
|---|---|---|
| 单分区 | Topic只设置1个分区 | 吞吐量低,不推荐 |
| Key分区 | 相同Key的消息发同一分区 | 推荐方案,性能好 |
| 单线程消费 | 消费者单线程处理 | 性能低 |
示例:
userA: order1 → partition 1
userA: order2 → partition 1
userA: order3 → partition 1
userB: order1 → partition 2
userB: order2 → partition 2
同一用户的订单保证顺序
3. Kafka Rebalance机制 #
答案:
什么是Rebalance? 消费者组内的消费者数量变化时,重新分配分区的过程。
触发条件:
- 消费者加入组(新Consumer)
- 消费者离开组(宕机、主动离开)
- Topic分区数变化
- 消费者订阅的Topic变化
Rebalance流程:
阶段详解:
| 阶段 | 说明 | 参与者 |
|---|---|---|
| Join Group | 消费者加入组,选举Leader | 所有消费者 |
| Sync Group | Leader发送分配方案,消费者同步 | 所有消费者 |
分区分配策略:
| 策略 | 原理 | 特点 |
|---|---|---|
| Range | 按分区范围分配 | 默认策略,可能不均 |
| RoundRobin | 轮询分配 | 更均匀 |
| Sticky | 粘性分配,尽可能保持之前分配 | 减少不必要重分配 |
Rebalance问题:
- 消费暂停:Rebalance期间消费会暂停
- 重复消费:正在处理的消息可能重复
- 解决:静态成员、增量协同分配
分布式事务篇 #
1. CAP理论与BASE #
答案:
CAP理论:
| 特性 | 说明 |
|---|---|
| 一致性 Consistency | 所有节点同一时刻看到同样的数据 |
| 可用性 Availability | 每个请求都能收到非错误响应 |
| 分区容错 Partition tolerance | 系统在网络分区时仍能工作 |
CAP权衡:
| 选择 | 说明 | 场景 | 示例 |
|---|---|---|---|
| CP | 强一致性 + 分区容错 | 金融交易 | ZooKeeper、HBase |
| AP | 高可用 + 分区容错 | 社交网络 | Eureka、Redis |
| CA | 一致性 + 可用性 | 单机数据库 | MySQL、PostgreSQL |
BASE理论(CAP的妥协):
| 缩写 | 含义 | 说明 |
|---|---|---|
| BA | Basically Available | 基本可用,允许部分功能降级 |
| S | Soft State | 软状态,允许中间状态 |
| E | Eventually Consistent | 最终一致性,一定时间后一致 |
强一致性 vs 最终一致性对比:
| 对比项 | 强一致性 | 最终一致性 |
|---|---|---|
| 复杂度 | 高 | 低 |
| 性能 | 低 | 高 |
| 一致性保证 | 强 | 弱 |
| 适用场景 | 金融、交易 | 社交、日志 |
2. 2PC/3PC/TCC/Saga对比 #
答案:
四种分布式事务方案对比:
| 方案 | 原理 | 一致性 | 侵入性 | 复杂度 | 适用场景 |
|---|---|---|---|---|---|
| 2PC | 两阶段提交 | 强一致性 | 低 | 中 | 传统企业应用 |
| 3PC | 三阶段提交 | 强一致性 | 低 | 高 | 很少实际使用 |
| TCC | Try-Confirm-Cancel | 最终一致性 | 高 | 高 | 金融、高一致性 |
| Saga | 长事务 + 补偿 | 最终一致性 | 中 | 中 | 微服务、长流程 |
详细解析:
(1) 2PC 两阶段提交 #
优点:
- ✅ 原理简单,易于理解
- ✅ 强一致性保证
缺点:
- ❌ 同步阻塞:事务期间资源锁定
- ❌ 单点故障:协调者宕机导致事务悬空
- ❌ 数据不一致:极端情况
(2) TCC 补偿事务 #
三个阶段:
| 阶段 | 说明 | 示例(订单) |
|---|---|---|
| Try | 资源预占,数据检查 | 预扣库存、创建待支付订单、扣减优惠券 |
| Confirm | 确认执行业务 | 订单状态更新为已支付 |
| Cancel | 回滚取消 | 释放库存、删除订单、返还优惠券 |
代码示例:
public interface OrderTccService {
// Try阶段:预占资源
boolean tryCreateOrder(Order order);
// Confirm阶段:确认执行
boolean confirmCreateOrder(Order order);
// Cancel阶段:补偿回滚
boolean cancelCreateOrder(Order order);
}
(3) Saga 模式 #
两种实现方式:
| 方式 | 说明 | 复杂度 |
|---|---|---|
| 编排式 Orchestration | 中心协调器控制流程 | 中 |
| 协同式 Choreography | 服务间事件驱动 | 高 |
Saga vs TCC:
- Saga:适合长事务,不需要资源锁定
- TCC:适合需要资源锁定的场景
3. 分布式事务XA方案 #
答案:
XA是什么? X/Open组织定义的分布式事务标准,基于2PC。
XA架构:
XA接口:
xa_start():开始分支事务xa_end():结束分支事务xa_prepare():准备阶段xa_commit():提交xa_rollback():回滚
Seata AT模式(XA的演进):
Seata AT优势:
- ✅ 自动补偿,零业务侵入
- ✅ 一阶段本地提交,性能好
- ✅ 自动生成回滚SQL
分布式事务方案选择指南:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 传统企业应用 | 2PC/XA | 强一致性,简单 |
| 金融、高一致性 | TCC | 性能比2PC好,可控性强 |
| 微服务、长流程 | Saga | 无锁,高吞吐 |
| 互联网应用 | Seata AT | 低侵入,适合大多数场景 |
| 极致性能 | 本地消息表 | 最终一致性,性能最好 |
高可用篇 #
1. 服务熔断降级方案 #
答案:
熔断器三种状态:
| 状态 | 说明 | 行为 |
|---|---|---|
| Closed | 正常状态 | 所有请求正常通过 |
| Open | 熔断状态 | 快速失败,不调用下游 |
| Half-Open | 半开状态 | 尝试少量请求,验证下游是否恢复 |
熔断 vs 降级 vs 限流:
| 对比项 | 熔断 | 降级 | 限流 |
|---|---|---|---|
| 目的 | 防止级联故障 | 保证核心功能可用 | 防止系统过载 |
| 触发条件 | 错误率高 | 系统负荷高 | QPS超过阈值 |
| 措施 | 停止调用下游 | 牺牲非核心功能 | 拒绝部分请求 |
| 状态 | 状态机 | 无状态 | 计数器 |
Sentinel示例:
// 资源定义
@SentinelResource(
value = "getUser",
blockHandler = "handleBlock", // 限流/熔断处理
fallback = "handleFallback" // 异常降级
)
public User getUser(Long id) {
return userRepository.findById(id);
}
// 限流处理
public User handleBlock(Long id, BlockException ex) {
return User.builder().name("限流用户").build();
}
// 降级处理
public User handleFallback(Long id, Exception ex) {
// 从缓存读取
return cacheService.getUser(id);
}
熔断降级框架对比:
| 框架 | 优势 | 劣势 | 推荐场景 |
|---|---|---|---|
| Sentinel | 轻量级、控制台、热点限流 | 生态较新 | 新项目首选 |
| Hystrix | 成熟、社区活跃 | 已停止维护 | 旧项目继续使用 |
| Resilience4j | 轻量、函数式 | 功能相对少 | Java 8+新项目 |
2. 限流算法(令牌桶/漏桶/滑动窗口) #
答案:
四种限流算法对比:
| 算法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 固定窗口 | 单位时间计数 | 简单 | 边界突增问题 | 基础限流 |
| 滑动窗口 | 窗口滑动计数 | 平滑 | 存储成本高 | 精确限流 |
| 令牌桶 | 固定速率放令牌 | 允许突发流量 | 实现稍复杂 | 保护自身服务 |
| 漏桶 | 固定速率流出 | 强制平滑 | 不支持突发 | 保护下游服务 |
详细解析:
(1) 固定窗口计数器 #
时间窗口 1: 00:00-01:00 → 计数100 → OK
时间窗口 2: 01:00-02:00 → 计数100 → OK
问题:00:59-01:01 → 200请求(边界突增!)
特点:
- ✅ 实现简单
- ❌ 边界突增问题
(2) 滑动窗口 #
窗口大小: 1分钟
切片: 10个 × 6秒
时间线: [6s][6s][6s]...[6s]
00:00-00:06: 计数20
00:06-00:12: 计数15
...
00:54-01:00: 计数10
总计: 100
窗口滑动:丢弃最早的切片,加入新切片
特点:
- ✅ 平滑,无边界突增
- ❌ 需要存储多个切片
(3) 令牌桶算法 #
原理:
- 固定速率生成令牌(如100/s)
- 令牌桶有容量限制
- 请求来临时,取令牌,有则通过
- 桶内令牌积累,允许突发流量
代码示例:
// Guava RateLimiter 实现
RateLimiter rateLimiter = RateLimiter.create(100.0); // 100 QPS
// 尝试获取令牌
if (rateLimiter.tryAcquire()) {
// 处理请求
} else {
// 限流
}
(4) 漏桶算法 #
原理:
- 水滴(请求)进入桶
- 桶满时,水滴溢出(拒绝请求)
- 桶底以固定速率流出(处理请求)
令牌桶 vs 漏桶:
| 对比项 | 令牌桶 | 漏桶 |
|---|---|---|
| 流量控制 | 允许突发流量 | 强制平滑输出 |
| 适用对象 | 保护自身服务 | 保护下游服务 |
| 灵活性 | 高 | 低 |
Sentinel限流配置示例:
// 限流规则
private void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("getUser");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(100); // QPS阈值
rule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); // 默认快速失败
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
3. 故障转移与灾备设计 #
答案:
高可用架构层级:
| 层级 | 可用性 | RTO/RPO | 成本 |
|---|---|---|---|
| 单实例 | 99% | 高 | 低 |
| 集群部署 | 99.9% | 中 | 中 |
| 多可用区 | 99.95% | 低 | 中高 |
| 多活架构 | 99.99% | 极低 | 高 |
| 异地灾备 | 99.999% | 极低 | 极高 |
故障转移策略:
(1) 健康检查 #
// 健康检查方式
- TCP 端口检查
- HTTP 接口检查 (如 /health)
- 脚本检查
- gRPC/Ping 检查
// 检查频率
- 正常状态:5s一次
- 异常状态:1s一次(快速发现)
(2) 故障转移流程 #
灾备方案对比:
| 方案 | RTO | RPO | 成本 | 场景 |
|---|---|---|---|---|
| 冷备 | 小时/天 | 小时/天 | 低 | 非核心业务 |
| 温备 | 分钟级 | 分钟级 | 中 | 一般业务 |
| 热备 | 秒级 | 秒级 | 高 | 核心业务 |
| 双活/多活 | 秒级/0 | 0/秒级 | 极高 | 金融核心 |
RTO vs RPO:
| 指标 | 全称 | 说明 |
|---|---|---|
| RTO | Recovery Time Objective | 恢复时间目标,业务中断多长时间能恢复 |
| RPO | Recovery Point Objective | 恢复点目标,允许丢失多少数据 |
两地三中心架构:
设计要点:
- 同城灾备:同步复制,RPO≈0
- 异地灾备:异步复制,RPO≈秒级
- 切换演练:定期演练,确保可用
多级容灾策略:
| 级别 | 措施 | 应对场景 |
|---|---|---|
| L1 | 集群内部故障转移 | 单机故障 |
| L2 | 机房内多可用区部署 | 单可用区故障 |
| L3 | 同城双活 | 单机房故障 |
| L4 | 异地灾备 | 城市级别灾难 |
🔗 相关笔记 #
- 微服务
- 分布式系统
- 中间件选型
- 性能优化
🔗 相关笔记 #
- 分布式系统
- 中间件选型
- 性能优化
- 系统设计
最后更新: 2026-04-29