架构设计 #

本文档整理了分布式系统与架构设计的核心知识点,适用于Java后端架构师面试准备。


📚 学习路径 #

基础理论

分布式基础

中间件选型

高可用架构

性能优化


一、消息与流处理系统 #

Apache Kafka #

面试高频 ⭐⭐⭐⭐⭐

核心设计亮点 #

特性 技术实现 面试考点
高吞吐 顺序读写磁盘 + 零拷贝(Zero-Copy) 如何实现百万级TPS?
持久化 Topic分区存储 消息如何保证不丢失?
水平扩展 Partition + Broker集群 如何扩容?
消费者组 多消费者并行消费 Rebalance机制是什么?

学习价值 #

  • 分布式日志存储
  • 生产者-消费者解耦
  • 大规模数据管道设计

Apache Pulsar #

核心设计亮点 #

架构特点:
  - 分层存储: Broker(计算)  BookKeeper(存储) 分离
  - 多租户: Tenant + Namespace 资源隔离
  - 高性能: 支持多种订阅模式

学习价值 #

  • 云原生消息系统的分层架构
  • 多租户支持实现

Kafka vs Pulsar #

对比维度 Kafka Pulsar
架构模式 紧耦合 分层存储
运维复杂度 较低 较高
多租户 社区版弱 原生支持

二、分布式数据库与存储 #

Apache Cassandra #

CAP理论实践 ⭐⭐⭐⭐

核心设计亮点 #

Cassandra

去中心化

最终一致性

线性扩展

技术要点 #

设计选项 实现方式
分片策略 一致性哈希(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核心 ⭐⭐⭐⭐

核心设计亮点 #

etcd

Raft协议

Lease机制

Watch长轮询

对比 ZooKeeper #

特性 ZooKeeper etcd
协议 ZAB Raft
性能 较低 更高
API风格 复杂 简洁RESTful

四、服务网格与流量治理 #

Istio #

微服务治理标准 ⭐⭐⭐⭐

核心设计亮点 #

Service Mesh (控制平面: Istio)

Pilot (服务发现/路由)

Citadel (安全认证)

Galley (配置验证)

Data Plane (Sidecar: Envoy Proxy)

学习价值 #

  • 微服务流量治理
  • 可观测性
  • 安全(mTLS)标准化实现

Netflix Hystrix #

容错设计模式 ⭐⭐⭐⭐

核心设计亮点 #

正常状态

失败率超阈值

尝试恢复

调用成功

调用失败

Closed

Open

HalfOpen

核心机制 #

机制 目的
熔断 防止级联故障
降级 保证核心可用
资源隔离 线程池/信号量隔离

五、大数据与计算引擎 #

流批一体 ⭐⭐⭐⭐

核心设计亮点 #

特点:
  - 流批一体: 统一API处理流批
  - 状态管理: Exactly-Once语义
  - 容错机制: Chandy-Lamport算法

学习价值 #

  • 流式计算引擎容错
  • 状态管理最佳实践

Google Bigtable #

NoSQL鼻祖 ⭐⭐⭐

核心设计亮点 #

  • 存储引擎:LSM树(高写入吞吐)
  • 元数据管理:Chubby协调
  • 数据组织:列族(Column Family)

学习价值 #

  • 分布式NoSQL底层引擎设计

六、云原生基础设施 #

Kubernetes #

容器编排金标准 ⭐⭐⭐⭐⭐

架构核心 #

用户

kubectl

API Server

Controller Manager

调度器

etcd

Node

Pod

Container

核心概念速查 #

概念 描述 面试要点
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 #

全球强一致性 ⭐⭐⭐⭐⭐

核心设计亮点 #

TrueTime API

[earliest, latest]

时间区间(由原子钟+GPS提供)

全局事务一致性保证

学习价值 #

  • 全球强一致性数据库
  • 时钟同步机制

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 ⭐⭐⭐

阅读源码 #

推荐深入阅读的开源项目:

源码学习

消息中间件

Kafka

Pulsar

分布式协调

ZooKeeper

etcd

Curator

容器编排

Kubernetes

etcd

流计算

Flink

动手实践 #

// 1. 用ZooKeeper实现分布式锁
public class ZKDistributedLock {}

// 2. 实现简易Raft算法
public class SimpleRaft {}

// 3. 实现一致性哈希
public class ConsistentHash {}

关注Trade-off #

每个系统都是权衡的结果:

一致性 (C)

强一致

Spanner

CockroachDB

可用性 (A)

AP系统

Cassandra

DynamoDB

分区容错性 (P)

网络分区必须容忍

所有分布式系统


📝 面试高频问题汇总 #

消息队列 #

  1. Kafka高性能原理
  2. 消息不丢失/不重复/顺序消费
  3. Kafka Rebalance机制

分布式事务 #

  1. CAP理论与BASE
  2. 2PC/3PC/TCC/Saga对比
  3. 分布式事务XA方案

高可用 #

  1. 服务熔断降级方案
  2. 限流算法(令牌桶/漏桶/滑动窗口)
  3. 故障转移与灾备设计

📝 面试题答案详解 #

消息队列篇 #

1. Kafka高性能原理 #

答案:

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=all

ISR同步

手动提交offset

生产者

Broker

副本

消费者

消费确认

三端保证:

保证措施 配置
生产者端 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? 消费者组内的消费者数量变化时,重新分配分区的过程。

触发条件:

  1. 消费者加入组(新Consumer)
  2. 消费者离开组(宕机、主动离开)
  3. Topic分区数变化
  4. 消费者订阅的Topic变化

Rebalance流程:

触发Rebalance

Coordinator确定

1. Join Group

2. Sync Group

Leader分配方案

所有消费者同步

开始消费

阶段详解:

阶段 说明 参与者
Join Group 消费者加入组,选举Leader 所有消费者
Sync Group Leader发送分配方案,消费者同步 所有消费者

分区分配策略:

策略 原理 特点
Range 按分区范围分配 默认策略,可能不均
RoundRobin 轮询分配 更均匀
Sticky 粘性分配,尽可能保持之前分配 减少不必要重分配

Rebalance问题:

  • 消费暂停:Rebalance期间消费会暂停
  • 重复消费:正在处理的消息可能重复
  • 解决:静态成员、增量协同分配

分布式事务篇 #

1. CAP理论与BASE #

答案:

CAP理论:

分布式系统

一致性 C

可用性 A

分区容错 P

特性 说明
一致性 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 两阶段提交 #

Prepare

Prepare

Prepare

Yes/No

Yes/No

Yes/No

Commit/Rollback

Commit/Rollback

Commit/Rollback

协调者

参与者A

参与者B

参与者C

优点:

  • ✅ 原理简单,易于理解
  • ✅ 强一致性保证

缺点:

  • ❌ 同步阻塞:事务期间资源锁定
  • ❌ 单点故障:协调者宕机导致事务悬空
  • ❌ 数据不一致:极端情况
(2) TCC 补偿事务 #

Try阶段

资源预占

Confirm阶段

确认执行

Cancel阶段

补偿回滚

三个阶段:

阶段 说明 示例(订单)
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架构:

应用程序 AP (Application Program)

事务管理器 TM (Transaction Manager)

资源管理器 RM (Resource Manager)

JDBC

JMS

XA接口:

  • xa_start():开始分支事务
  • xa_end():结束分支事务
  • xa_prepare():准备阶段
  • xa_commit():提交
  • xa_rollback():回滚

Seata AT模式(XA的演进):

一阶段:业务SQL执行

解析SQL语义

查询前镜像数据(Before Image)

执行业务SQL

查询后镜像数据(After Image)

保存undo log

提交本地事务(释放锁)

二阶段:提交/回滚

提交:异步删除undo log

回滚:根据undo log反向生成补偿SQL

Seata AT优势:

  • ✅ 自动补偿,零业务侵入
  • ✅ 一阶段本地提交,性能好
  • ✅ 自动生成回滚SQL

分布式事务方案选择指南:

场景 推荐方案 理由
传统企业应用 2PC/XA 强一致性,简单
金融、高一致性 TCC 性能比2PC好,可控性强
微服务、长流程 Saga 无锁,高吞吐
互联网应用 Seata AT 低侵入,适合大多数场景
极致性能 本地消息表 最终一致性,性能最好

高可用篇 #

1. 服务熔断降级方案 #

答案:

熔断器三种状态:

正常状态

失败率>阈值

超时时间到

调用成功

调用失败

Closed

Open

HalfOpen

状态 说明 行为
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) 令牌桶算法 #

10/s放入

获取令牌

有令牌

无令牌

令牌生成器

令牌桶

请求

通过

拒绝

原理:

  • 固定速率生成令牌(如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 恢复点目标,允许丢失多少数据

两地三中心架构:

同步复制

异步复制

生产中心 (主)

同城灾备 (从)

异地灾备 (备)

设计要点:

  1. 同城灾备:同步复制,RPO≈0
  2. 异地灾备:异步复制,RPO≈秒级
  3. 切换演练:定期演练,确保可用

多级容灾策略:

级别 措施 应对场景
L1 集群内部故障转移 单机故障
L2 机房内多可用区部署 单可用区故障
L3 同城双活 单机房故障
L4 异地灾备 城市级别灾难

🔗 相关笔记 #

  • 微服务
  • 分布式系统
  • 中间件选型
  • 性能优化

🔗 相关笔记 #

  • 分布式系统
  • 中间件选型
  • 性能优化
  • 系统设计

最后更新: 2026-04-29