Spring Cloud 面试高频问题汇总
面试 Spring Cloud,你准备好了吗?
这一讲,我们来汇总 Spring Cloud 面试中的高频问题,让你面试无忧。
一、基础概念篇
Q1:什么是 Spring Cloud?它和 Spring Boot 是什么关系?
参考答案:
Spring Cloud 是 Spring 官方提供的微服务解决方案,它基于 Spring Boot,提供了服务注册发现、配置中心、负载均衡、熔断降级、网关路由等组件。
关系:
- Spring Boot 是基础,提供了自动配置能力
- Spring Cloud 在 Spring Boot 基础上扩展了分布式开发能力
- Spring Boot 关注单个微服务的开发,Spring Cloud 关注微服务架构的整体治理
比喻:Spring Boot 像手机的操作系统,Spring Cloud 像手机上的 App 生态。
Q2:Spring Cloud 有哪些核心组件?
参考答案:
| 组件 | 功能 | 常用实现 |
|---|---|---|
| 服务注册与发现 | 服务实例管理 | Nacos、Eureka |
| 配置中心 | 集中配置管理 | Nacos Config、Apollo |
| 负载均衡 | 流量分发 | Ribbon、LoadBalancer |
| 服务调用 | HTTP 客户端 | OpenFeign |
| 网关 | 统一入口、路由 | Gateway、Zuul |
| 熔断降级 | 故障保护 | Sentinel、Hystrix |
| 链路追踪 | 请求追踪 | Sleuth + Zipkin |
| 分布式事务 | 跨服务事务 | Seata |
Q3:Spring Cloud 和 Dubbo 有什么区别?
参考答案:
| 维度 | Spring Cloud | Dubbo |
|---|---|---|
| 通信协议 | HTTP/REST | RPC(Dubbo 协议) |
| 性能 | 较低(HTTP 序列化) | 高(RPC 二进制序列化) |
| 生态 | 完整(涵盖微服务全场景) | 专注于 RPC 调用 |
| 学习成本 | 较高(组件多) | 较低 |
| 社区活跃度 | 高(持续迭代) | 中(阿里维护) |
| 国内使用 | 广泛 | 广泛(金融领域多) |
选择建议:一般业务场景选 Spring Cloud,对性能要求高的场景选 Dubbo。
Q4:什么是 CAP 理论?Nacos 是 AP 还是 CP?
参考答案:
CAP 理论指出分布式系统无法同时满足:一致性(Consistency)、可用性(Availability)、分区容错性(Partition Tolerance)。
Nacos 的选择:
- AP 模式(默认):临时实例,通过心跳检测,适合大多数场景
- CP 模式:持久实例,使用 Raft 协议,适合对数据一致性要求高的场景
yaml
# AP 模式
spring.cloud.nacos.discovery.ephemeral: true
# CP 模式
spring.cloud.nacos.discovery.ephemeral: false二、服务注册与发现篇
Q5:Nacos 和 Eureka 有什么区别?
参考答案:
| 维度 | Nacos | Eureka |
|---|---|---|
| 架构 | 同时支持 AP 和 CP | 只支持 AP |
| 功能 | 注册中心 + 配置中心 | 只有注册中心 |
| 健康检查 | 心跳检测 + 服务端探测 | 客户端心跳 |
| 控制台 | 功能完善 | 简陋 |
| 维护状态 | 活跃 | 已停更 |
| 集群同步 | Raft 协议 | 多副本同步 |
结论:新项目推荐 Nacos。
Q6:服务注册与发现的原理是什么?
参考答案:
┌─────────────────────────────────────────────────────────┐
│ 服务注册发现流程 │
│ │
│ 服务启动时: │
│ 1. 服务实例向注册中心发送注册请求 │
│ 2. 注册中心保存服务实例信息 │
│ 3. 服务实例定期发送心跳 │
│ │
│ 服务调用时: │
│ 1. 调用方从注册中心获取被调用方列表 │
│ 2. 根据负载均衡策略选择实例 │
│ 3. 向选中实例发起调用 │
│ │
│ 服务下线时: │
│ 1. 停止发送心跳 │
│ 2. 注册中心剔除过期实例 │
│ 3. 调用方感知服务列表变化 │
│ │
└─────────────────────────────────────────────────────────┘Q7:Nacos 如何实现配置管理?
参考答案:
三层隔离机制:
- Namespace(命名空间):环境隔离(dev/test/prod)
- Group(分组):项目或业务线隔离
- Data ID(配置 ID):具体配置文件
配置加载规则:
${prefix}-${spring.profiles.active}.${file-extension}
示例:order-service-prod.yaml三、服务调用篇
Q8:OpenFeign 的工作原理是什么?
参考答案:
┌─────────────────────────────────────────────────────────┐
│ OpenFeign 工作原理 │
│ │
│ 1. 启动时: │
│ @EnableFeignClients 扫描 @FeignClient 注解 │
│ 为每个接口生成 JDK 动态代理对象 │
│ │
│ 2. 调用时: │
│ 调用代理对象的接口方法 │
│ → MethodHandler.invoke(args) │
│ → RequestTemplate 构建请求 │
│ → LoadBalancerFeignClient 选择实例 │
│ → HTTP Client 发送请求 │
│ → 解析响应 │
│ │
└─────────────────────────────────────────────────────────┘Q9:Ribbon 和 Spring LoadBalancer 有什么区别?
参考答案:
| 维度 | Ribbon | Spring LoadBalancer |
|---|---|---|
| 维护状态 | 已停更 | 活跃 |
| 线程模型 | 同步阻塞 | 异步非阻塞(WebFlux 友好) |
| 配置方式 | XML/Java | Spring Boot 标准化 |
| 负载均衡策略 | 丰富 | 基础(轮询、随机) |
选择建议:新项目使用 Spring LoadBalancer。
Q10:Feign 如何实现熔断降级?
参考答案:
- 引入 Sentinel 依赖
xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>- 配置启用
yaml
feign:
sentinel:
enabled: true- 定义降级类
java
@Component
public class UserClientFallback implements UserClient {
@Override
public User getUser(Long id) {
User fallbackUser = new User();
fallbackUser.setId(id);
fallbackUser.setName("降级用户");
return fallbackUser;
}
}- 使用降级
java
@FeignClient(name = "user-service", fallback = UserClientFallback.class)
public interface UserClient {
@GetMapping("/user/{id}")
User getUser(@PathVariable("id") Long id);
}四、网关路由篇
Q11:Spring Cloud Gateway 和 Zuul 有什么区别?
参考答案:
| 维度 | Gateway | Zuul |
|---|---|---|
| 线程模型 | 异步非阻塞(WebFlux) | 同步阻塞(Servlet) |
| 性能 | 高 | 较低 |
| 长连接 | 支持 | 不支持 |
| 维护状态 | 活跃 | 已停更 |
| Predicate | 内置丰富 | 需要自定义 |
| Filter | 两种类型(Gateway/Global) | 一种(ZuulFilter) |
结论:新项目使用 Gateway。
Q12:Gateway 的请求处理流程是什么?
参考答案:
┌─────────────────────────────────────────────────────────┐
│ Gateway 请求处理流程 │
│ │
│ 请求 ─► HttpWebHandlerAdapter │
│ │ │
│ ▼ │
│ RoutePredicateHandlerMapping │
│ │ 匹配路由 │
│ ▼ │
│ FilteringWebHandler │
│ │ │
│ ▼ │
│ Global Filter Chain │
│ │ │
│ ┌────┴────┐ │
│ │ Pre │ ← 请求处理前 │
│ │ 路由转发 │ │
│ │ Post │ ← 响应处理后 │
│ └─────────┘ │
│ │ │
│ ▼ │
│ 响应 │
│ │
└─────────────────────────────────────────────────────────┘Q13:Gateway 如何实现限流?
参考答案:
基于令牌桶算法,配合 Redis 实现分布式限流:
- 引入依赖
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>- 配置限流规则
yaml
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
key-resolver: '#{@userKeyResolver}'- 定义 Key 解析器
java
@Bean
public KeyResolver userKeyResolver() {
return exchange -> Mono.just(
exchange.getRequest().getHeaders().getFirst("X-User-Id")
);
}五、熔断降级篇
Q14:Sentinel 和 Hystrix 有什么区别?
参考答案:
| 维度 | Sentinel | Hystrix |
|---|---|---|
| 隔离方式 | 信号量隔离 | 线程池隔离 |
| 熔断策略 | RT/异常比例/异常数/系统自适应 | RT/异常比例 |
| 热点限流 | 支持 | 不支持 |
| 控制台 | 功能完善 | 无 |
| 维护状态 | 活跃 | 已停更 |
Q15:熔断器的三个状态是什么?
参考答案:
┌─────────────────────────────────────────────────────────┐
│ 熔断器状态机 │
│ │
│ 关闭(正常) │
│ │ 失败率超阈值 │
│ ▼ │
│ 打开(熔断)←────────────────────── 熔断时间结束 │
│ │ │
│ 半开(尝试恢复) │
│ │ │
│ └────── 请求成功 ──► 关闭(正常) │
│ │ │
│ └────── 请求失败 ──► 打开(熔断) │
│ │
└─────────────────────────────────────────────────────────┘Q16:什么是服务雪崩?如何避免?
参考答案:
服务雪崩:服务 A 调用服务 B,服务 B 调用服务 C,C 不可用导致 B 阻塞,阻塞的 B 导致 A 不可用,最终整个系统崩溃。
解决方案:
- 熔断器:检测到故障快速熔断
- 限流:控制进入系统的流量
- 降级:返回兜底数据
- 超时控制:设置合理的超时时间
- 隔离:线程池/信号量隔离
六、分布式事务篇
Q17:Seata AT 模式的原理是什么?
参考答案:
┌─────────────────────────────────────────────────────────┐
│ Seata AT 模式原理 │
│ │
│ Phase 1(准备阶段): │
│ ├─ 注册全局事务 │
│ ├─ 注册分支事务 │
│ ├─ 执行业务 SQL + 生成 Undo Log │
│ └─ 报告分支状态(成功) │
│ │
│ Phase 2(提交阶段): │
│ ├─ TC 确认所有分支成功 │
│ └─ 异步删除 Undo Log │
│ │
│ Phase 2(回滚阶段): │
│ ├─ TC 通知回滚 │
│ └─ 执行 Undo Log,恢复数据 │
│ │
└─────────────────────────────────────────────────────────┘Q18:分布式事务有哪些解决方案?
参考答案:
| 方案 | 一致性 | 性能 | 侵入性 | 适用场景 |
|---|---|---|---|---|
| 2PC | 强一致 | 低 | 高 | 底层数据库 |
| TCC | 最终一致 | 中 | 高 | 复杂业务 |
| AT | 最终一致 | 高 | 无 | 通用场景 |
| 本地消息表 | 最终一致 | 中 | 中 | 可接受侵入 |
| Saga | 最终一致 | 高 | 中 | 长流程 |
七、链路追踪篇
Q19:Sleuth 和 Zipkin 的关系是什么?
参考答案:
- Sleuth:客户端库,负责生成 TraceId/SpanId,收集链路数据
- Zipkin:服务端,负责存储和展示链路数据
工作流程:
Sleuth(客户端)
├─ 生成 TraceId(全局唯一)
├─ 生成 SpanId(每个节点唯一)
└─ 发送数据到 Zipkin
Zipkin(服务端)
├─ 接收链路数据
├─ 存储(MySQL/Elasticsearch)
└─ 展示(Web UI)Q20:如何选择采样率?
参考答案:
采样率设置原则:
- 生产环境:5-10%(高并发场景可能更低)
- 测试环境:100%
- 调试时:按需调整
优先采样:
- 慢请求(RT > 阈值)
- 错误请求
- 高价值请求
八、综合篇
Q21:如何设计一个微服务架构?
参考答案:
核心原则:
- 单一职责:每个服务只负责一块业务
- 服务自治:服务独立部署、独立数据库
- 轻量通信:HTTP/REST 或 RPC
- 自动化运维:CI/CD、监控、告警
分层设计:
┌─────────────────────────────────────────────────────────┐
│ 微服务分层架构 │
│ │
│ 网关层:鉴权、路由、限流 │
│ │ │
│ 业务层:核心业务逻辑 │
│ │ │
│ 数据层:数据库、缓存 │
│ │
└─────────────────────────────────────────────────────────┘Q22:微服务架构有哪些挑战?
参考答案:
- 服务治理:服务注册发现、负载均衡、熔断降级
- 分布式事务:跨服务数据一致性
- 分布式锁:并发控制
- 链路追踪:问题定位
- 配置管理:多环境配置
- 运维复杂度:服务数量多,部署、监控困难
写在最后
面试 Spring Cloud,核心考察点:
- 概念理解:理解各组件的作用和关系
- 原理掌握:理解核心组件的工作原理
- 实战经验:有实际项目经验,能解决实际问题
- 架构思维:理解微服务设计原则和最佳实践
面试不仅是回答问题,更是展示你对技术的理解深度。多动手实践,才能真正掌握。
