前言

Spring Cloud 面试题通常不会只问“它是不是微服务框架”。更常见的问题是:服务注册发现怎么做,配置中心如何刷新,网关承担什么职责,服务间调用为什么要负载均衡,OpenFeign 底层怎么发请求,熔断和降级有什么区别,链路追踪如何定位问题,线上某个服务调用突然变慢怎么排查。

如果只把 Spring Cloud 理解成“一组微服务组件”,回答很容易停留在名词层。更好的方式是把它理解成一条完整链路:

1
服务启动 -> 注册到注册中心 -> 拉取配置 -> 网关接入请求 -> 负载均衡选择实例 -> Feign/HTTP 调用服务 -> 熔断限流保护 -> 链路追踪和监控定位问题

本文按面试中最常见的模块梳理 Spring Cloud 要点,适合作为面试前的复习清单。

Spring Cloud 整体定位

Spring Cloud 是一套基于 Spring Boot 的微服务治理工具集,提供服务注册发现、配置管理、网关路由、负载均衡、服务调用、熔断降级、链路追踪等能力。

它不是单个框架,而是一组面向分布式系统常见问题的解决方案。

面试中可以这样概括:

Spring Boot 解决单个应用如何快速开发和运行;Spring Cloud 解决多个 Spring Boot 服务组成分布式系统后,如何发现、调用、配置、保护、观测和治理。

核心组件

Spring Cloud 生态中常见组件包括:

  • 注册中心:Eureka、Nacos、Consul、Zookeeper。
  • 配置中心:Spring Cloud Config、Nacos Config、Apollo。
  • 网关:Spring Cloud Gateway。
  • 负载均衡:Spring Cloud LoadBalancer。
  • 服务调用:OpenFeign、RestTemplate、WebClient。
  • 熔断限流:Resilience4j、Sentinel。
  • 链路追踪:Sleuth、Micrometer Tracing、Zipkin、SkyWalking。
  • 消息驱动:Spring Cloud Stream。
flowchart TD
    A[Client] --> B[Gateway]
    B --> C[Service A]
    C --> D[Service B]
    C --> E[Service C]
    C --> F[Registry]
    D --> F
    E --> F
    C --> G[Config Center]
    D --> G
    E --> G
    C --> H[Tracing / Metrics]
    D --> H
    E --> H

服务注册与发现

服务注册发现解决的问题是:服务实例 IP 和端口会变化,调用方不应该写死地址。

基本流程:

1
服务启动 -> 向注册中心注册实例 -> 定期心跳续约 -> 调用方拉取服务列表 -> 负载均衡选择实例 -> 发起调用

注册中心保存服务名、实例地址、健康状态、元数据等信息。

常见追问:服务下线后调用方为什么还会请求到旧实例?

可能原因包括:

  • 注册中心剔除有延迟。
  • 客户端本地服务列表缓存未刷新。
  • 服务没有优雅下线。
  • 网关或调用方连接池仍持有旧连接。

生产环境要配合健康检查、优雅停机、预下线、流量摘除和合理缓存刷新时间。

配置中心

配置中心解决多服务、多环境配置统一管理的问题。

常见能力:

  • 按环境管理配置。
  • 配置版本管理。
  • 动态刷新。
  • 配置权限控制。
  • 配置变更审计。

配置加载链路可以概括为:

1
应用启动 -> 连接配置中心 -> 拉取当前环境配置 -> 注入 Environment -> Bean 读取配置 -> 配置变更后通知刷新

常见问题:配置改了为什么没有生效?

可能原因包括:

  • 应用没有接入动态刷新。
  • Bean 没有使用可刷新作用域。
  • 配置 key 写错或环境 namespace/group 错误。
  • 本地配置优先级覆盖了远端配置。
  • 配置中心推送失败或客户端连接异常。

面试回答时要明确:不是所有配置都适合动态刷新,例如线程池核心参数、数据库连接池、日志级别等需要结合实现和风险判断。

Spring Cloud Gateway

Gateway 是微服务入口层,常见职责包括:

  • 统一路由。
  • 权限认证。
  • 限流。
  • 跨域处理。
  • 灰度发布。
  • 请求和响应改写。
  • 统一日志和 traceId 注入。

Gateway 核心概念:

  • Route:路由规则。
  • Predicate:匹配条件。
  • Filter:过滤器。

示例:

1
2
3
4
5
6
7
8
9
10
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1

lb://user-service 表示通过服务名从注册中心获取实例,并进行负载均衡。

负载均衡

负载均衡解决一个服务有多个实例时,调用方选择哪个实例的问题。

常见策略:

  • 轮询。
  • 随机。
  • 权重。
  • 最少连接。
  • 基于实例元数据的灰度路由。

Spring Cloud 早期常用 Ribbon,新版本更推荐 Spring Cloud LoadBalancer。

负载均衡通常发生在客户端侧:

1
调用 user-service -> 获取实例列表 -> 选择一个实例 -> 发起 HTTP 请求

常见问题:

  • 实例列表缓存延迟导致请求到已下线实例。
  • 所有请求打到少数实例,可能是权重或缓存问题。
  • 灰度元数据不一致导致路由异常。
  • 健康检查不准确导致异常实例仍被调用。

OpenFeign

OpenFeign 是声明式 HTTP 客户端,通过接口和注解描述远程调用。

1
2
3
4
5
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/users/{id}")
UserDTO getUser(@PathVariable Long id);
}

Feign 调用大致流程:

sequenceDiagram
    participant ServiceA
    participant Feign
    participant LB as LoadBalancer
    participant ServiceB

    ServiceA->>Feign: 调用接口方法
    Feign->>Feign: 构造 HTTP 请求
    Feign->>LB: 根据服务名选择实例
    LB-->>Feign: 返回实例地址
    Feign->>ServiceB: 发起 HTTP 请求
    ServiceB-->>Feign: 返回响应
    Feign-->>ServiceA: 反序列化结果

常见配置点:

  • 连接超时。
  • 读取超时。
  • 重试策略。
  • 编码解码器。
  • 拦截器。
  • 日志级别。
  • 熔断降级集成。

面试中要注意:远程调用一定要设置超时,不能让默认超时和无限等待拖垮线程池。

熔断、降级和限流

这三个概念容易混淆。

  • 限流:控制进入系统的请求量,防止流量超过承载能力。
  • 熔断:下游持续失败或变慢时,短时间直接失败,避免拖垮调用方。
  • 降级:返回兜底结果或关闭非核心功能,保证核心链路可用。

例如:

1
库存服务变慢 -> 订单服务调用超时增多 -> 熔断库存查询 -> 返回稍后重试或默认结果 -> 避免订单线程池被耗尽

常见指标:

  • 慢调用比例。
  • 异常比例。
  • QPS。
  • 并发线程数。
  • RT。

限流是入口保护,熔断是依赖保护,降级是业务兜底。

服务雪崩

服务雪崩是微服务面试高频问题。

典型过程:

1
下游服务变慢 -> 上游线程阻塞 -> 请求堆积 -> 线程池耗尽 -> 更多服务超时 -> 故障扩散

治理手段:

  • 超时控制。
  • 熔断降级。
  • 限流。
  • 线程池隔离。
  • 舱壁隔离。
  • 缓存兜底。
  • 快速失败。
  • 依赖分级。

面试中要强调:没有超时的远程调用是非常危险的,可能把局部故障放大成全链路故障。

链路追踪

微服务调用链变长后,单个服务日志很难定位问题,需要链路追踪。

常见概念:

  • Trace:一次完整请求链路。
  • Span:链路中的一个调用片段。
  • TraceId:整条链路的唯一标识。
  • SpanId:单个调用节点标识。

链路追踪可以回答:

  • 请求经过了哪些服务。
  • 哪个服务耗时最长。
  • 哪个调用报错。
  • 下游依赖是否变慢。

常见工具包括 Zipkin、SkyWalking、Jaeger、Micrometer Tracing 等。

日志中也应该打印 traceId,方便从监控跳到日志。

分布式事务

微服务拆分后,单机数据库事务无法覆盖多个服务。常见方案包括:

  • 本地事务 + 可靠消息最终一致性。
  • TCC。
  • Saga。
  • Seata AT。
  • 业务补偿。

面试中不要简单说“用分布式事务框架”。更重要的是根据业务一致性要求选择方案。

例如订单创建和库存扣减:

  • 强一致要求高:可以考虑 TCC 或 Seata,但复杂度高。
  • 可接受最终一致:订单本地落库后发消息扣库存,失败后补偿。
  • 读模型一致性:通过状态机和定时任务修复。

核心取舍是:一致性、性能、复杂度、可用性。

灰度发布

灰度发布是让部分流量进入新版本,验证稳定后逐步扩大。

常见维度:

  • 用户 ID。
  • 租户 ID。
  • Header。
  • Cookie。
  • 地域。
  • 服务实例元数据。

常见实现位置:

  • 网关层。
  • 负载均衡层。
  • 服务调用拦截器。
  • 注册中心实例元数据。

灰度发布要配合监控、日志、快速回滚和配置开关,否则只做路由没有治理闭环。

常见性能优化

服务治理:

  • 合理设置超时。
  • 避免无边界重试。
  • 对核心依赖配置熔断和降级。
  • 网关限流保护入口。
  • 服务优雅下线。

调用链路:

  • 减少串行远程调用。
  • 合并批量接口。
  • 避免循环调用。
  • 缓存低频变更数据。
  • 对慢接口异步化。

配置和发布:

  • 配置变更要有审计和回滚。
  • 灰度发布先小流量验证。
  • 版本兼容避免上下游同时强依赖升级。

观测:

  • 接入指标、日志和链路追踪。
  • 监控 QPS、RT、错误率、线程池、连接池。
  • 关键业务指标和技术指标一起看。

常见排查思路

如果面试官问“某个微服务接口突然变慢怎么排查”,可以按以下路径回答:

  1. 看是单接口慢、单服务慢,还是全链路慢。
  2. 通过 traceId 查看调用链路,定位耗时最长的 Span。
  3. 看网关、调用方、被调方的 RT 和错误率。
  4. 看是否发生注册中心异常或调用到异常实例。
  5. 看 Feign 超时、重试和连接池状态。
  6. 看下游数据库、缓存、消息队列是否变慢。
  7. 看线程池、CPU、GC、内存和容器资源。
  8. 看最近是否有发布、配置变更、流量突增或灰度规则变化。

如果是服务调用失败,可以重点看服务是否注册、实例健康、路由规则、网络连通性、鉴权、超时配置、熔断状态和日志异常。

高频面试题

Spring Cloud 和 Spring Boot 有什么区别?

Spring Boot 解决单体应用或单个服务快速开发、运行和部署的问题;Spring Cloud 基于 Spring Boot,解决多个服务之间的注册发现、配置、调用、网关、熔断、链路追踪等分布式治理问题。

注册中心有什么用?

注册中心保存服务实例地址和健康状态。服务启动后注册,调用方通过服务名获取实例列表,再进行负载均衡调用,避免写死 IP 和端口。

配置中心改了配置为什么没生效?

可能是动态刷新未开启、Bean 不支持刷新、namespace/group/profile 错误、本地配置优先级更高、配置中心推送失败或客户端连接异常。

Gateway 的核心概念是什么?

Gateway 核心是 Route、Predicate 和 Filter。Route 定义路由规则,Predicate 判断请求是否匹配,Filter 在请求前后做鉴权、限流、改写、日志、灰度等处理。

Feign 是怎么调用远程服务的?

Feign 根据接口注解生成代理,方法调用时构造 HTTP 请求,通过服务名获取实例列表并负载均衡选择实例,然后发起 HTTP 调用并反序列化响应。

熔断和降级有什么区别?

熔断是当下游异常或变慢时,临时切断调用以保护系统;降级是返回兜底结果或关闭非核心能力,保证核心链路可用。熔断偏保护机制,降级偏业务策略。

如何防止服务雪崩?

设置超时、限流、熔断、降级、线程池隔离、快速失败、缓存兜底和依赖分级,避免一个下游故障拖垮上游和整条链路。

总结

Spring Cloud 面试的主线可以围绕四个问题展开:

  1. 服务怎么发现:注册中心、健康检查、实例缓存、优雅下线。
  2. 服务怎么调用:Gateway、LoadBalancer、Feign、超时和重试。
  3. 系统怎么保护:限流、熔断、降级、隔离、防雪崩。
  4. 线上怎么治理:配置中心、链路追踪、灰度发布、监控和排查。

把这条链路讲清楚,再结合微服务调用失败、接口变慢、配置不生效和服务雪崩治理,Spring Cloud 相关问题就能从“知道组件名”升级成“理解微服务治理体系”。