Skip to content

微服务面试题

1. 微服务和单体架构的区别?

特性单体架构微服务架构
部署整体打包部署独立部署
扩展整体扩展按需扩展
技术栈统一可异构
数据库共享数据库每个服务独有数据库
复杂度代码耦合分布式系统复杂性
通信本地调用网络通信

2. Spring Cloud 微服务有哪些核心模块?各自的作用是什么?

Spring Cloud 是微服务架构的一站式解决方案,提供了服务治理、配置管理、负载均衡、熔断降级、链路追踪等一系列组件。以下是核心模块及其作用:

2.1 服务注册与发现 —— Spring Cloud Netflix Eureka / Nacos Discovery

作用: 解决微服务架构中"服务在哪里"的问题。在微服务架构中,服务实例的数量和位置是动态变化的,服务注册与发现让服务之间能够自动找到彼此,而不需要硬编码 IP 地址。

Eureka 核心机制:

  • 服务注册:服务启动时向 Eureka Server 注册自己的元数据(服务名、IP、端口、健康状态等)
  • 心跳续约:服务每 30 秒发送一次心跳,证明自己还活着。Eureka Server 90 秒未收到心跳则剔除该实例
  • 服务发现:服务调用方从 Eureka Server 拉取服务注册表,并缓存在本地,定时更新
  • 自我保护模式:当 Eureka Server 短时间内丢失大量心跳时,自动进入自我保护模式,不再剔除任何实例,防止因网络抖动导致大面积误删

Nacos 相比 Eureka 的优势:

  • 支持 AP/CP 模式切换,灵活应对不同场景
  • 不仅做注册发现,还做配置中心,功能合一
  • 心跳 + 主动健康检查,更可靠
  • 阿里持续维护,生态活跃

面试要点: 区分 Eureka 的 AP 模型(优先保证可用性,可能返回过期实例)和 Zookeeper 的 CP 模型(优先保证一致性,Leader 故障时不可用)。


2.2 配置中心 —— Spring Cloud Config / Nacos Config

作用: 解决微服务架构中"配置在哪里"的问题。几十个微服务的配置如果散落在各自的配置文件中,修改一个配置需要重新部署大量服务,配置管理成为噩梦。配置中心实现配置的集中管理、动态刷新、环境隔离。

核心功能:

  • 集中管理:所有服务的配置统一存储在配置中心,一处修改,全局生效
  • 动态刷新:配置变更后无需重启服务,通过 @RefreshScope 注解或 Nacos 的监听机制实现热更新
  • 环境隔离:通过 namespace 或 profile 实现 dev / test / prod 环境配置隔离
  • 版本管理:配置变更历史可追溯,支持回滚
  • 灰度发布:部分实例先使用新配置,验证无问题后全量推送

面试要点: 配置刷新的实现原理(长轮询 vs WebSocket 推送 vs Spring Cloud Bus 广播),以及为什么需要配置中心(想象一下 100 个服务每个都要改 Redis 地址的场景)。


2.3 API 网关 —— Spring Cloud Gateway

作用: 解决微服务架构中"请求从哪里进"的问题。网关是整个系统的唯一入口,所有外部请求都经过网关,由网关路由到对应的微服务。

为什么需要网关?

  • 如果让前端直接调用各个微服务,前端需要知道所有服务的地址,且每个服务都要自己处理鉴权、限流、日志、跨域,代码重复严重
  • 网关将这些通用能力统一收敛,实现了"关注点分离"

Spring Cloud Gateway 三大核心组件:

组件作用示例
Route(路由)定义请求的转发规则/order/**order-service
Predicate(断言)匹配请求的条件Path、Header、Method、Query 参数等
Filter(过滤器)对请求/响应进行拦截处理鉴权、限流、日志、修改请求头

与 Zuul 的对比:

  • Gateway 基于 WebFlux + Netty,非阻塞异步,性能远高于 Zuul 1.x(基于 Servlet 阻塞模型)
  • Gateway 使用函数式编程定义路由规则,比 Zuul 的 Filter 链更灵活
  • Zuul 2.x 虽然也改为非阻塞,但 Spring 官方已明确推荐 Gateway

面试要点: 网关不是银弹,它会成为单点瓶颈和单点故障,需要集群部署保证高可用。另外,网关层不应该承载过重的业务逻辑,否则网关本身就成了新的"单体"。


2.4 声明式服务调用 —— Spring Cloud OpenFeign

作用: 解决微服务架构中"服务怎么调用"的问题。让服务间的 HTTP 调用像调用本地方法一样简单,通过接口 + 注解的方式声明远程调用。

核心特性:

  • 声明式调用:只需定义接口 + @FeignClient 注解,无需写 HTTP 调用代码
  • 负载均衡集成:内置集成 Ribbon 或 Spring Cloud LoadBalancer
  • 熔断降级集成:配合 Sentinel 或 Hystrix 实现容错
  • 请求拦截器:统一添加请求头(如 Token 传递、TraceId 透传)
  • 编解码器:支持 JSON、XML、表单等多种格式

工作流程:

  1. 定义 @FeignClient(name = "order-service") 接口
  2. Feign 根据接口生成动态代理对象
  3. 调用接口方法时,代理对象根据服务名去注册中心查询实例列表
  4. 通过负载均衡选择一个实例
  5. 构造 HTTP 请求发送到目标服务
  6. 解析响应,返回结果

面试要点: Feign 的本质是动态代理 + HTTP 客户端。需要理解 @FeignClient 的配置项(超时、重试、日志级别),以及如何通过 RequestInterceptor 实现链路追踪的 TraceId 透传。


2.5 负载均衡 —— Spring Cloud LoadBalancer

作用: 解决"选哪个实例调用"的问题。当一个服务有多个实例时,负载均衡器决定将请求发给哪个实例。

与 Ribbon 的关系:

  • Ribbon 是 Netflix 开源的客户端负载均衡器,已进入维护模式
  • Spring Cloud LoadBalancer 是 Spring 官方替代品,更轻量,与 Spring 生态集成更好

常见负载均衡策略:

  • 轮询(Round Robin):依次分配,最简单的策略
  • 加权轮询(Weighted):根据服务器性能分配不同权重
  • 随机(Random):随机选择
  • 最小活跃数(Least Active):选择当前处理请求最少的实例
  • 一致性哈希(Consistent Hash):相同参数的请求总是路由到同一实例,适合有状态场景

面试要点: 区分客户端负载均衡(Ribbon / LoadBalancer,调用方自己选实例)和服务端负载均衡(Nginx,请求先到 LB 再转发)。微服务架构中通常使用客户端负载均衡,因为它更灵活,去掉了中心化 LB 的瓶颈。


2.6 熔断降级 —— Sentinel / Resilience4j

作用: 解决微服务架构中"一个服务挂了怎么办"的问题。在分布式系统中,一个服务的故障可能像雪崩一样蔓延到整个系统,熔断降级就是为了阻断这种级联故障。

Sentinel 核心能力:

能力说明场景举例
流量控制QPS / 并发线程数限制秒杀场景限制下单接口 QPS
熔断降级慢调用比例 / 异常比例超过阈值,自动熔断数据库挂了,快速返回降级结果
系统保护根据系统 Load、CPU 使用率自动限流防止系统被突发流量打垮
热点参数限流针对特定参数值限流限制单个商品 ID 的查询频率
规则持久化规则存储在 Nacos / Apollo 等配置中心重启后规则不丢失

熔断器状态机:

  1. 关闭(Closed):正常状态,请求正常通过
  2. 打开(Open):失败次数达到阈值,熔断器打开,所有请求直接失败
  3. 半开(Half-Open):经过一段时间后,尝试放行一个请求,如果成功则关闭熔断器,如果失败则继续保持打开状态

Sentinel vs Hystrix:

  • Hystrix 已停止维护,官方推荐迁移到 Resilience4j 或 Sentinel
  • Sentinel 控制台可视化更好,支持实时监控和规则动态调整
  • Sentinel 支持更细粒度的流量控制(QPS、线程数、关联资源、链路)

面试要点: 熔断和降级是两个概念:熔断是自动的(根据失败率自动触发),降级是主动的(提前定义好失败时的兜底逻辑)。实际开发中,熔断和降级通常配合使用:熔断触发后,走降级逻辑返回兜底结果。


2.7 链路追踪 —— Micrometer Tracing(原 Spring Cloud Sleuth)

作用: 解决微服务架构中"请求经过了哪些服务"的问题。一个用户请求可能经过网关 → 订单服务 → 库存服务 → 支付服务 → 物流服务,没有链路追踪,排查问题如大海捞针。

核心概念:

概念说明
TraceId一次完整请求链路的唯一标识,贯穿所有服务
SpanId链路中每个操作单元的唯一标识
ParentSpanId父 Span 的 ID,用于构建调用树

工作原理:

  1. 请求进入第一个服务时,生成全局唯一的 TraceId 和 SpanId
  2. 调用下游服务时,将 TraceId 和 SpanId 放入请求头透传
  3. 下游服务解析请求头,创建新的 Span,ParentSpanId 指向上游的 SpanId
  4. 所有 Span 上报到追踪系统(如 Zipkin / SkyWalking / Jaeger)
  5. 通过 TraceId 查询完整调用链

面试要点: 日志中打印 TraceId 是排查问题的关键手段。通过 %X{traceId} 在 Logback 配置中输出 TraceId,出问题时只需要用户提供一个 TraceId,就能串联出整个调用链的所有日志。


2.8 消息驱动 —— Spring Cloud Stream

作用: 解耦微服务之间的异步通信,屏蔽底层消息中间件的差异。开发者只需面向统一的编程模型编程,无需关心底层是 Kafka、RocketMQ 还是 RabbitMQ。

核心概念:

  • Binder:适配层,屏蔽不同消息中间件的差异
  • Channel:消息通道,分为 Input(消费)和 Output(生产)
  • Message:消息体,包含 payload 和 header

适用场景:

  • 异步解耦:下单后异步发送短信、推送通知
  • 流量削峰:秒杀请求先写入 MQ,后端慢慢消费
  • 数据同步:数据变更后通过 MQ 通知其他服务同步

2.9 消息总线 —— Spring Cloud Bus

作用: 实现微服务之间的广播通信,通常配合 Spring Cloud Config 实现配置的批量刷新。

工作原理:

  • 基于消息中间件(RabbitMQ / Kafka)实现
  • 当配置中心的配置变更时,通过 Bus 广播 Refresh 事件
  • 所有订阅了该事件的服务自动刷新配置

与 Nacos 的对比:

  • Nacos 自带配置推送能力,不需要额外引入 Bus
  • 如果使用 Spring Cloud Config + Git 作为配置中心,则需要 Bus 来实现配置的批量刷新

2.10 模块体系总结

┌─────────────────────────────────────────────────────┐
│                   外部请求                            │
└─────────────────────┬───────────────────────────────┘

          ┌───────────▼───────────┐
          │  Gateway (API 网关)    │  ← 统一入口、鉴权、限流
          └───────────┬───────────┘

          ┌───────────▼───────────┐
          │  Nacos (注册+配置)     │  ← 服务发现、配置管理
          └───────────┬───────────┘

    ┌─────────┬───────┼───────┬─────────┐
    │         │       │       │         │
┌───▼───┐ ┌───▼───┐ ┌─▼──┐ ┌──▼───┐ ┌──▼───┐
│ 订单  │ │ 用户  │ │商品│ │ 支付 │ │ 物流  │
│ 服务  │ │ 服务  │ │服务│ │ 服务 │ │ 服务  │
└───┬───┘ └───┬───┘ └─┬──┘ └──┬───┘ └──┬───┘
    │         │       │       │         │
    │  Feign (声明式调用) + LoadBalancer (负载均衡)  │
    │         │       │       │         │
    │     Sentinel (熔断降级限流)     │         │
    │         │       │       │         │
    │  Sleuth/Micrometer Tracing (链路追踪)  │         │
    │         │       │       │         │
    └─────────┴───────┼───────┴─────────┘

          ┌───────────▼───────────┐
          │  Stream (消息驱动)     │  ← 异步解耦
          └───────────┬───────────┘

          ┌───────────▼───────────┐
          │  Bus (消息总线)        │  ← 配置广播
          └───────────────────────┘

面试回答模板:

"Spring Cloud 是一套微服务治理的完整解决方案。我实际项目中使用过以下核心模块:

Nacos 做服务注册发现和配置中心,解决服务之间怎么找到彼此、配置怎么集中管理的问题; Gateway 做 API 网关,作为系统统一入口,处理路由转发、鉴权、限流; OpenFeign + LoadBalancer 做服务间调用,Feign 让远程调用像本地调用一样简单,LoadBalancer 负责负载均衡; Sentinel 做熔断降级和流量控制,防止级联故障和突发流量打垮系统; Sleuth/Micrometer Tracing 做链路追踪,配合 SkyWalking 或 Zipkin 可视化调用链,方便排查问题; 异步场景下用 Stream 对接消息队列,解耦服务间的同步依赖。

这些组件各司其职,共同支撑起一个完整的微服务体系。选型上,我们现在更倾向于 Spring Cloud Alibaba 生态(Nacos + Sentinel),因为它们功能更全、社区更活跃,而且阿里有大规模生产验证。"


3. 服务注册与发现的原理?

  1. 服务注册:服务启动时向注册中心注册自己的信息(IP、端口、服务名)
  2. 心跳续约:定时发送心跳,保持注册信息有效
  3. 服务发现:调用方从注册中心获取服务实例列表
  4. 负载均衡:调用方通过负载均衡策略选择实例
  5. 服务下线:服务关闭或无心跳时,注册中心移除实例

4. Eureka 和 Nacos 的区别?

特性EurekaNacos
CAPAPAP/CP 可切换
功能仅注册发现注册发现 + 配置中心
健康检查心跳心跳 + 主动探测
一致性协议Raft(CP 模式)
维护状态停止维护持续更新

5. Spring Cloud Gateway 的原理?

Spring Cloud Gateway 基于 WebFlux 框架,使用 Netty 作为底层通信。

三大核心组件:

  • Route(路由):包含 ID、目标 URI、Predicate 集合、Filter 集合
  • Predicate(断言):匹配请求的条件(路径、Header、参数等)
  • Filter(过滤器):对请求进行修改或拦截

6. 分布式事务如何解决?

方案原理适用场景
2PC两阶段提交,协调者统一管理强一致性要求
TCCTry-Confirm-Cancel 三阶段资金交易等
可靠消息本地消息表 + 消息队列保证最终一致高并发场景
最大努力通知反复通知直到成功短信通知等
SeataAT 模式:一阶段提交 + 二阶段回滚通用场景

7. CAP 定理是什么?如何选择?

CAP:一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance),三者只能同时满足两个。

  • CP:保证一致性和分区容错,牺牲可用性(Zookeeper、Consul)
  • AP:保证可用性和分区容错,牺牲一致性(Eureka、Nacos AP 模式)
  • 分区容错性必须保证,实际是在 CP 和 AP 之间选择

8. 如何保证接口幂等性?

  • 数据库唯一索引:利用唯一约束防止重复插入
  • Token 机制:请求前获取 Token,提交时校验 Token
  • 状态机:通过状态流转保证幂等
  • 分布式锁:Redis / Zookeeper 锁防止并发重复请求
  • 乐观锁:版本号机制,更新时校验版本