Skip to content

分布式组件

分布式系统离不开这些基础组件:分布式锁、分布式 ID、分布式会话。面试考的是实现细节和坑。

Q1: 分布式锁有哪些实现方式? 「🟡 中级」

考察点:分布式锁的选型与正确性。

参考答案

  • 数据库:唯一索引或 FOR UPDATE 行锁。简单但性能差,依赖 DB。
  • RedisSET key value NX EX + Lua 脚本删除。高性能,注意锁过期、主从切换问题(Redisson 看门狗续期)。
  • ZooKeeper:临时有序节点 + Watch 机制。强一致,但性能不如 Redis。
  • 选型:追求性能用 Redis(配合业务幂等);追求强一致用 ZK/Etcd。

追问延伸

  • Redis 主从切换丢锁怎么解决?(RedLock,但有争议)
  • ZooKeeper 分布式锁的羊群效应是什么?

Q2: 分布式 ID 生成方案有哪些? 「🟡 中级」

考察点:全局唯一 ID 的设计能力。

参考答案

  • UUID:简单但无序、长(36 字符),不适合做数据库主键。
  • 数据库自增:单点瓶颈;号段模式(每次取一段到内存)可缓解。
  • 雪花算法(Snowflake):64 位 = 时间戳 + 机器 ID + 序列号,趋势递增,性能高。需解决时钟回拨问题。
  • Redis INCR:原子自增,依赖 Redis 可用性。
  • Leaf(美团):号段模式 + Snowflake 双实现,高可用。

追问延伸

  • 雪花算法的时钟回拨怎么处理?
  • 为什么数据库主键推荐趋势递增?

Q3: 分布式会话怎么实现? 「🟡 中级」

考察点:微服务架构下的会话管理。

参考答案

  • Session 复制:每台机器都存所有会话,浪费内存,扩展性差。
  • Session 粘滞:负载均衡把同一用户路由到同一节点,节点挂了会话丢失。
  • Session 集中存储:用 Redis 集中存储会话,各节点从 Redis 读取。主流方案。
  • Token 方案(JWT):无状态,服务端不存会话;缺点是无法主动失效、Token 较大。

追问延伸

  • JWT 的续签怎么做?
  • Redis 集中存储会话的过期策略怎么设计?

Q4: 什么是限流?有哪些算法? 「🟡 中级」

考察点:高可用设计的基础。

参考答案

  • 固定窗口:单位时间内允许 N 个请求。缺点:窗口边界突发流量。
  • 滑动窗口:把窗口细分成多个小格,更平滑。
  • 漏桶算法:固定速率处理请求,平滑流量但无法应对突发。
  • 令牌桶算法:固定速率生成令牌,有令牌才能处理请求;允许一定程度的突发(桶满时)。Guava RateLimiter 用此算法。

追问延伸

  • 限流在网关层做还是在服务层做?
  • 分布式限流怎么实现?(Redis + Lua)

Q5: 什么是熔断和降级? 「🟡 中级」

考察点:服务容错的核心机制。

参考答案

  • 熔断:下游服务故障时,快速失败不再调用,避免雪崩。状态:关闭 → 打开(熔断)→ 半开(探测恢复)。代表:Hystrix、Sentinel、Resilience4j。
  • 降级:服务不可用时返回兜底数据(缓存、默认值、友好提示),保证核心流程可用。
  • 关系:熔断是手段,降级是目的;熔断触发后通常伴随降级。

追问延伸

  • 熔断和超时重试的关系?
  • 什么场景需要熔断?

Q6: 什么是服务注册与发现? 「🟡 中级」

考察点:微服务架构的基础组件。

参考答案

  • 服务提供者启动时向注册中心注册自己的地址;服务消费者从注册中心拉取可用实例列表并负载均衡调用。
  • 注册中心:ZooKeeper、Eureka(已停更)、Consul、Nacos、Etcd。
  • 健康检查:心跳机制,注册中心剔除不健康实例。
  • 客户端发现 vs 服务端发现:客户端直连(如 Dubbo)vs 经过负载均衡器(如 Kubernetes Service)。

追问延伸

  • Nacos 的 AP 和 CP 模式怎么切换?
  • 服务下线后消费者怎么感知?