微服务架构 #

分布式系统设计核心,涵盖服务拆分、服务治理、分布式事务等


📋 目录 #


微服务拆分原则 #

核心原则 #

微服务拆分

单一职责

每个服务一个业务能力

可独立开发部署

高内聚低耦合

内部模块紧密相关

服务间依赖最小

业务边界清晰

DDD领域划分

限界上下文

拆分方法 #

方法 说明 示例
业务功能拆分 按功能模块拆分 电商:用户、商品、订单、支付
数据模型拆分 数据独立性 每个服务独占地库
用户角色拆分 按角色权限 管理员服务、员工服务、客户服务

拆分流程 #

业务分析

确定粒度

定义边界

数据迁移

代码重构

测试部署

1. 业务分析
   - 分析业务模块关系
   - 识别服务边界

2. 确定拆分粒度
   - 太细:服务太多,管理复杂
   - 太粗:无法发挥微服务优势

3. 定义服务边界
   - 明确职责范围
   - 定义接口契约

4. 数据迁移
   - 垂直拆表(按业务)
   - 数据清理

5. 代码重构
   - 提取服务代码
   - 去除循环依赖

6. 测试部署
   - 单元测试
   - 集成测试
   - 灰度发布

拆分收益与挑战 #

收益 挑战
✅ 独立部署扩展 ❌ 运维复杂度增加
✅ 技术栈灵活 ❌ 分布式事务
✅ 可维护性提升 ❌ 服务间通信开销
✅ 团队自治 ❌ 数据一致性

服务治理 #

服务治理

服务注册发现

服务调用

负载均衡

熔断降级

配置管理

链路追踪

注册中心选型 #

对比项 Eureka Nacos Consul Zookeeper
一致性模式 AP AP/CP CP CP
健康检查 客户端 TCP/HTTP/K8s TCP/HTTP/Script KeepAlive
配置中心
Spring Cloud集成
适用场景 已有项目 新项目 K8s环境 遗留项目

服务发现 #

// 客户端服务发现
@FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/api/users/{id}")
    User getUser(@PathVariable Long id);
}

// 调用流程
// 1. Ribbon从注册中心获取可用服务列表
// 2. 选择一个实例(负载均衡)
// 3. 发起HTTP请求

负载均衡算法 #

算法 说明 适用场景
轮询 依次轮转 服务器性能相当
随机 随机选择 大量并发
加权轮询 按权重轮转 服务器性能不均
最小连接 选择连接最少 长连接场景
一致性哈希 相同请求落同一服务器 有状态服务

熔断降级 #

失败率>阈值

超时时间到

成功

失败

Closed
正常状态

Open
熔断状态,直接返回

Half-Open
半开状态,尝试调用

Sentinel 示例:

@SentinelResource(
    value = "getUser",
    blockHandler = "handleBlock"  // 降级处理
)
public User getUser(Long id) {
    return userRepository.findById(id);
}

public User handleBlock(Long id, BlockException ex) {
    // 降级逻辑:返回缓存数据或默认值
    return User.builder().name("降级用户").build();
}

限流算法 #

限流算法

固定窗口

滑动窗口

令牌桶

漏桶

算法 原理 优缺点 适用场景
固定窗口 单位时间计数 简单粗暴,边界突变 基础限流
滑动窗口 窗口滑动计数 更平滑 精确限流
令牌桶 固定速率放入令牌 允许突发流量 保护自身服务
漏桶 固定速率漏出 强制平滑输出 保护下游服务
// Sentinel 限流
@SentinelResource(
    value = "getUser",
    blockHandler = "handleBlock"
)
public User getUser(Long id) {
    return userRepository.findById(id);
}

// 配置规则
// 资源名: getUser
// 限流阈值: 100 QPS

分布式事务 #

2PC 两阶段提交 #

第一阶段: 准备 (Prepare)

    协调者 ───────> 参与者A: 准备提交
                    参与者B: 准备提交
                    参与者C: 准备提交

第二阶段: 提交/回滚 (Commit/Rollback)

    协调者 ───────> 参与者A: 提交
                    参与者B: 提交
                    参与者C: 提交
优点 缺点
✅ 强一致性 ❌ 同步阻塞
✅ 简单易理解 ❌ 单点故障

TCC 补偿事务 #

Try 阶段:
  - 资源预占
  - 数据预处理

Confirm 阶段:
  - 确认执行
  - 提交业务

Cancel 阶段:
  - 取消执行
  - 回滚数据

示例: 电商下单
  Try: 1. 预扣库存 2. 创建订单(待支付) 3. 扣减优惠券
  Confirm: 订单状态→已支付
  Cancel: 1. 释放库存 2. 删除订单 3. 返还优惠券

Saga 模式 #

失败

创建订单

扣减库存

扣减优惠券

支付

返还优惠券

恢复库存

取消订单

模式 说明
编排式 中心协调器控制流程
协同式 服务间事件触发

示例:

// 订单Service
public void createOrder(Order order) {
    try {
        // 1. 创建订单
        orderService.create(order);
        // 2. 扣库存
        inventoryService.deduct(order);
        // 3. 扣优惠券
        couponService.deduct(order);
        // 4. 支付
        paymentService.pay(order);
        // 5. 确认订单
        orderService.confirm(order.getId());
    } catch (Exception e) {
        // 补偿执行
        // 返还优惠券 → 恢复库存 → 取消订单
    }
}

Seata AT 模式 #

一阶段: 业务SQL执行
  - 解析SQL语义
  - 查询前镜像数据
  - 执行业务SQL
  - 查询后镜像数据
  - 保存undo log
  - 提交本地事务(释放锁)

二阶段: 提交/回滚
  - 提交: 异步删除undo log
  - 回滚: 根据undo log反向生成补偿SQL

三高架构 #

三高架构

高可用 HA

高性能 HP

高扩展 HS

冗余

故障转移

负载均衡

熔断降级

缓存

异步化

并行化

代码优化

分片

水平扩展

无状态化

微服务化

高可用 (High Availability) #

可用率: 99.99% (全年停机不超过52.6分钟)

实现:
  1. 冗余设计
     - 主从、集群、多活
  2. 故障转移
     - 心跳检测
     - 自动切换
  3. 负载均衡
     - 流量分发
     - 健康检查
  4. 熔断降级
     - 快速失败
     - 保护系统

典型: 金融系统 7×24h不间断服务

高性能 (High Performance) #

关键指标:
  - QPS (Queries Per Second)
  - TPS (Transactions Per Second)
  - 延迟 Latency (P95, P99)

优化手段:
  1. 异步化处理
     - 消息队列
  2. 多级缓存
     - 本地缓存 + Redis
  3. 并行计算
     - 分片处理
  4. 代码优化
     - 减少锁竞争
     - I/O优化

典型: 秒杀系统 10万+ QPS

高扩展 (High Scalability) #

扩展方式:
  - 水平扩展 (Scale-Out): 增加节点
  - 垂直扩展 (Scale-Up): 提升配置

设计原则:
  - 无状态服务
    - Session外置Redis
  - 松耦合架构
    - 微服务独立部署
  - 数据分片
    - 分库分表

典型: 云平台自动扩缩容

CAP 理论 #

分布式系统

一致性 C

可用性 A

分区容错 P

选择 说明 适用场景
CP 强一致性 + 分区容错 金融交易、ZooKeeper
AP 高可用 + 分区容错 社交网络Redis
CA 一致性 + 可用性 单机数据库

BASE 理论:

  • BA (Basically Available): 基本可用
  • S (Soft State): 软状态
  • E (Eventually Consistent): 最终一致性

实战案例 #

订单超时关闭 #

方案一: 延迟消息 (推荐)

流程:
  1. 创建订单后发送延迟消息 (30分钟后)
  2. 消息到期触发关闭订单
  3. 幂等性校验 (订单状态)

技术: RocketMQ Delay Message

优势:
  - 精准时延
  - 高吞吐
  - 解耦

方案二: 定时扫描 (兜底)

流程:
  1. 定时扫描待支付订单
  2. 检查创建时间 > 30分钟
  3. 批量关闭

技术: ElasticJob、XXL-Job

优化:
  - 分片扫描
  - 索引优化 (status + create_time)

限流降级策略 #

// 多级限流

第一级: 网关层
  - 基于IP限流
  - 基于用户限流

第二级: 服务层
  - 接口级限流
  - 方法级限流

第三级: 数据层
  - SQL限流
  - 连接池保护

// 白名单机制
if (whiteList.contains(userId)) {
    // 白名单用户不限流
    return;
}

面试题汇总 #

基础 #

  1. 微服务拆分原则?
  2. 单体 → 微服务迁移策略?
  3. 微服务 vs 分布式区别?
  4. 服务治理包含哪些?

注册中心 #

  1. Eureka vs Nacos vs Consul?
  2. 服务发现原理?
  3. 注册中心高可用方案?

服务调用 #

  1. OpenFeign vs RestTemplate?
  2. 负载均衡算法?
  3. 服务端负载均衡 vs 客户端负载均衡?

熔断降级 #

  1. 熔断器三种状态?
  2. 熔断 vs 降级 vs 限流?
  3. Sentinel vs Hystrix?

分布式事务 #

  1. 2PC原理及缺点?
  2. TCC事务流程?
  3. Saga模式补偿机制?
  4. Seata AT原理?

高并发 #

  1. 秒杀系统设计?
  2. 如何避免超卖?
  3. 三 high 设计?

面试题答案详解 #

基础篇 #

  1. 微服务拆分原则?

答案:

原则 说明
单一职责 每个服务只干一件事
高内聚低耦合 内部紧密,外部依赖少
按业务领域 DDD限界上下文划分
独立部署发布 能单独上线
团队自治 一个团队维护一个服务

常见拆分方法:

  • 按业务功能(用户/商品/订单)
  • 按数据模型
  • 按用户角色

  1. 单体 → 微服务迁移策略?

答案:

策略 说明
绞杀者模式 新建微服务,逐步替换旧系统
气泡模式 逐步把功能抽出来
DB优先 先拆库,再拆服务

推荐步骤:

  1. 先拆边缘功能
  2. 后拆核心功能
  3. 灰度发布验证
  4. 用消息队列解耦

  1. 微服务 vs 分布式区别?

答案:

对比 微服务 分布式
关注点 服务拆分、服务治理 多节点协作
场景 系统拆分 性能、高可用
关系 微服务是分布式的子集 分布式 > 微服务

总结:

  • 微服务 ≈ 分布式服务架构
  • 分布式系统不一定是微服务

  1. 服务治理包含哪些?

答案:

服务治理

注册发现

负载均衡

熔断降级

限流

链路追踪

配置中心

网关


注册中心 #

  1. Eureka vs Nacos vs Consul?

答案:

对比 Eureka Nacos Consul
CAP AP AP/CP CP
健康检查 Client心跳 TCP/HTTP/MySQL Script
配置中心
推荐 旧项目 新项目 多数据中心

推荐: 新项目选Nacos(注册中心+配置中心二合一)


  1. 服务发现原理?

答案:

注册

拉取

返回服务列表

选择服务

服务启动

注册中心

服务消费者

服务提供者

两种模式:

模式 说明
客户端发现 自己拉取列表,自己选(Ribbon)
服务端发现 通过网关/负载均衡器(Nginx)

  1. 注册中心高可用方案?

答案:

集群部署:

  • Eureka: 多节点互相注册
  • Nacos: 集群模式
  • Consul: Server集群

高可用要点:

  • 节点数3/5/7(奇数,避免脑裂)
  • 跨机房部署
  • 数据持久化

服务调用 #

  1. OpenFeign vs RestTemplate?

答案:

对比 RestTemplate OpenFeign
写法 手动拼接URL 声明式接口
集成 需手动配置 自动集成Ribbon/Sentinel
推荐

OpenFeign示例:

@FeignClient("user-service")
public interface UserClient {
    @GetMapping("/api/users/{id}")
    User getUser(@PathVariable Long id);
}

  1. 负载均衡算法?

答案:

算法 说明
轮询 挨个顺序来(默认)
随机 随机选
加权轮询 权重高的分配多
最少连接 选连接数最少的
一致性哈希 相同请求落同一服务

  1. 服务端负载均衡 vs 客户端负载均衡?

答案:

对比 服务端 客户端
实现 Nginx/网关 Ribbon/LoadBalancer
优缺点 统一管理,多一跳 少一跳,灵活
推荐 混合使用(网关+客户端)

熔断降级 #

  1. 熔断器三种状态?

答案:

正常状态

失败率超阈值

超时时间到

成功

失败

Closed

Open

HalfOpen

状态说明:

  • Closed: 正常,请求放行
  • Open: 熔断,快速失败
  • HalfOpen: 半开,尝试放行少量请求

  1. 熔断 vs 降级 vs 限流?

答案:

对比 熔断 降级 限流
目的 防雪崩 保核心 防过载
触发 错误率高 资源不足 QPS超阈值
示例 下游挂了 返回默认值 排队/拒绝

  1. Sentinel vs Hystrix?

答案:

对比 Hystrix Sentinel
状态 停更 活跃
功能 基本熔断 限流+熔断+热点+系统保护
控制台 简单 丰富
推荐

分布式事务 #

  1. 2PC原理及缺点?

答案:

2PC = 两阶段提交

阶段1: Prepare(协调者问各参与者:准备好了没?)
阶段2: Commit/Rollback(根据回答结果决定提交或回滚)

缺点:

  • 同步阻塞
  • 单点故障
  • 数据不一致风险

  1. TCC事务流程?

答案:

TCC = Try-Confirm-Cancel

阶段 说明
Try 资源预占
Confirm 确认提交
Cancel 补偿回滚

  1. Saga模式补偿机制?

答案:

Saga = 长事务 + 补偿

两种实现:

  • 编排式: 中心协调者控制
  • 协同式: 服务间事件驱动

核心: 每个事务都有对应的补偿事务


  1. Seata AT原理?

答案:

AT = 自动补偿事务

1. 一阶段: 执行业务SQL,保存镜像,提交
2. 二阶段: 提交(删除镜像)或回滚(根据镜像生成反向SQL)

优点: 对代码侵入性低,推荐


高并发 #

  1. 秒杀系统设计?

答案:

核心思路:

1. 前端: 按钮置灰、倒计时、防抖
2. 网关: 限流、防重复、WAF
3. 服务: Redis预扣库存、消息队列异步下单
4. 数据库: 乐观锁、分库分表、消息表

技术要点:

  • 热点数据放Redis
  • 消息队列削峰
  • 限流降级保护
  • 幂等性保证

  1. 如何避免超卖?

答案:

方案 说明
数据库乐观锁 update stock set count=count-1 where id=? and count>0
Redis Lua脚本 原子操作
Redis Decr 单线程原子
分布式锁 保证只有一个能下单

  1. 三高设计?

答案:

说明
高性能 响应快、QPS高(缓存、异步、优化)
高可用 不宕机(集群、降级、熔断)
高并发 扛得住(水平扩展、无状态、异步解耦)

🔗 相关笔记 #


最后更新: 2026-04-29