Spring Cloud 最佳实践与面试考点
导学
飞翔科技的微服务化改造历经 18 个月终于完成。CTO 大翔在年终总结时说:"现在系统稳定了,但我想知道——如果重新来一次,有哪些坑可以避免?面试时问哪些问题能筛出真正理解微服务的人?"
白歌整理了这份最佳实践与面试考点手册。
一、最佳实践
1.1 版本选择
| 场景 | 推荐版本 | 原因 |
|---|---|---|
| 新项目 2024+ | Spring Cloud 2023.0.x + Boot 3.2.x | Jakarta EE 9+,Java 17+ |
| 维护旧项目 | Spring Cloud 2021.0.x + Boot 2.7.x | 稳定,javax 命名空间 |
| 国内生态 | Spring Cloud Alibaba 2023.x | Nacos + Sentinel + Seata 一体化 |
1.2 组件选型决策树
1.3 超时与重试配置黄金法则
熔断器 timeout > (连接超时 + 读取超时) × (同一实例重试 + 1) × (其他实例重试 + 1)
即:Hystrix/Sentinel timeout > Ribbon/LoadBalancer (ConnectTimeout + ReadTimeout) × (MaxAutoRetries + 1) × (MaxAutoRetriesNextServer + 1)
反例导致的问题:Hystrix 先于 Ribbon 触发超时,Ribbon 重试机制完全失效。
1.4 配置文件结构最佳实践
Git 仓库中的配置文件组织:
config-repo/
├── application.yml # 公共配置
├── application-dev.yml # 开发环境公共配置
├── application-prod.yml # 生产环境公共配置
├── feixiang-order-service.yml # 订单服务公共
├── feixiang-order-service-dev.yml # 订单服务 dev
├── feixiang-order-service-prod.yml # 订单服务 prod
└── feixiang-inventory-service.yml # 库存服务公共
规则:{application}-{profile}.yml
1.5 生产环境 Checklist
- [ ] Eureka 集群至少 2 节点,生产关闭自我保护或严格配置阈值
- [ ] 所有 Feign Client 配置 fallback 或 fallbackFactory
- [ ] 所有关键接口配置 Sentinel 限流规则
- [ ] 配置中心敏感信息加密(
{cipher}前缀) - [ ] 网关层统一 CORS、认证、限流
- [ ] 链路追踪采样率生产环境 ≤ 10%
- [ ] 所有服务配置健康检查端点(不被网关拦截)
- [ ] 消费者组(group)配置正确,防止消息丢失
- [ ] 日志配置中加入 Trace ID 占位符
1.6 服务雪崩的三层防护
1.7 零停机部署策略
关键配置:
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
eureka:
client:
healthcheck:
enabled: true
二、面试高频考点(20 题)
1. Spring Cloud 和 Spring Boot 的关系?
Spring Boot 是 Spring Cloud 的基石,提供自动配置和 Starter 机制;Spring Cloud 在 Spring Boot 之上构建微服务治理能力。两者的版本必须严格对应(如 Spring Cloud 2023.0.x 对应 Spring Boot 3.2.x / 3.3.x)。
2. Eureka 的自我保护机制?触发条件?
当 Eureka Server 在 15 分钟内收到的心跳低于阈值的 85%,进入自我保护模式,不再剔除任何实例。设计意图:宁可保留可能已宕机的实例,决不能因网络抖动误杀健康实例。体现 AP 原则(牺牲一致性换取可用性)。生产环境不要关闭,开发环境可关闭。
3. Eureka 与 Consul 的核心区别?
Eureka 是 AP 系统,基于客户端心跳;Consul 是 CP 系统,基于 Raft 协议,支持 HTTP/TCP/Script 等多维度健康检查,提供多数据中心支持和 KV 存储。纯 Java 生态选 Eureka,多语言/多集群选 Consul。
4. Spring Cloud LoadBalancer 与 Ribbon 的区别?
Ribbon 已进入维护模式,基于阻塞线程模型;LoadBalancer 基于 Reactor 响应式架构,原生支持 WebClient。Spring Cloud 2020.0.x 起默认使用 LoadBalancer。
5. OpenFeign 的工作原理?
通过 @FeignClient 定义接口,Spring 在运行时生成 JDK 动态代理。调用接口方法时,代理通过 Contract 解析注解生成请求模板,Encoder 编码参数,HTTP Client 发起请求,Decoder 将响应解码为返回类型。同时集成 LoadBalancer 实现服务名解析和熔断器实现降级。
6. 熔断器 Resilience4j 的三种状态及转换?
CLOSED(正常放行)→ 失败率超阈值 → OPEN(快速失败)→ 等待超时 → HALF_OPEN(探测恢复)→ 探测成功 → CLOSED;探测失败 → OPEN。
7. Spring Cloud Gateway 与 Zuul 1.x 的区别?
Gateway 基于 WebFlux/Reactor 非阻塞架构,Zuul 1.x 基于 Servlet 阻塞模型。Gateway 支持 WebSocket,提供更丰富的 Predicate 和 Filter 机制。Zuul 1.x 已进入维护模式。
8. @RefreshScope 的原理?
标注该注解的 Bean 放入 Refresh Scope,当调用 /actuator/refresh 时,Scope 缓存被清空,Bean 被销毁重建,从而重新读取最新配置。配合 Bus 可实现集群级刷新。
9. Spring Cloud Stream 的 Binder 是什么?
Binder 是 Stream 与消息中间件的适配层,屏蔽 Kafka/RabbitMQ 差异。开发者面向 Supplier/Function/Consumer 函数式编程,切换中间件只需更换 Binder 依赖。
10. Config Server 的加密机制?
支持对称加密({cipher}xxx)和非对称加密(RSA)。密文存储在 Git,Config Server 启动时加载密钥,响应客户端时自动解密。生产环境建议结合 Vault。
11. 什么是服务雪崩?如何防止?
下游故障引发上游级联失败。三层防护:① 熔断器快速失败 ② 限流防止压垮 ③ 降级提供兜底。此外网关层统一限流和鉴权也能提前拦截异常流量。
12. Spring Cloud Bus 除了配置刷新还能做什么?
Bus 本质是基于消息中间件的分布式事件总线,可用于缓存失效广播、服务状态同步、全局开关切换、灰度发布通知等。自定义 RemoteApplicationEvent 即可扩展。
13. Nacos 与 Eureka 的核心区别?
Nacos 是 AP/CP 可选,支持推模式(长轮询)和拉模式,内置配置中心;Eureka 是纯 AP,仅支持心跳和拉模式,无配置中心。Nacos 集群使用 Raft + Distro 协议,支持命名空间和分组隔离。
14. Nacos 配置中心的长轮询机制?
Nacos Config 客户端通过 HTTP Long Polling 连接 Server,Server hold 请求 30 秒,期间配置变更立即返回;无变更则超时后客户端重新发起。相比 Config + Bus + Webhook,更实时且无需额外中间件。
15. Sentinel 的滑动窗口 vs 令牌桶 vs 漏桶?
- 滑动窗口:统计时间窗口内请求数,精确统计,适合实时判断
- 令牌桶:固定速率生成令牌,允许突发流量(Warm Up)
- 漏桶:请求入队,匀速流出,平滑整形
Sentinel 支持三种效果:直接拒绝、Warm Up、匀速排队。
16. Sentinel 的 blockHandler 和 fallback 的区别?
blockHandler 仅处理 Sentinel 规则触发的 BlockException,方法需额外该参数;fallback 处理业务方法抛出的所有异常,参数与原方法一致。两者可同时使用。
17. Spring Boot 3.x 为何不再使用 Sleuth?
Sleuth 已进入维护模式。Spring Boot 3.x 采用 Micrometer Tracing 作为统一可观测性门面,通过 Brave 或 OpenTelemetry 实现 Trace 传播。Micrometer Tracing 与 Metrics 共享 Observation API,实现 Metrics + Traces 统一。
18. Prometheus Pull vs Push 模式?
Pull 模式:Prometheus 主动抓取目标端点(/actuator/prometheus),适合长期运行服务,可自动发现目标。Push 模式:应用主动推送指标到 Pushgateway,适合批处理/短生命周期任务。微服务通常使用 Pull + Service Discovery。
19. Seata AT 模式的 Undo Log 机制?
RM 在一阶段执行业务 SQL 前解析生成反向 SQL(Undo Log)并记录到本地 undo_log 表,同时提交本地事务。二阶段全局提交则删除 Undo Log,全局回滚则执行 Undo Log 回滚数据。前提:数据库支持本地事务,SQL 可被解析器识别。
20. Seata TCC 模式的空回滚和幂等性?
空回滚:Try 未执行时 Cancel 被调用,通过事务控制表记录状态,Cancel 检查到 Try 未执行则直接返回成功。幂等性:Confirm/Cancel 可能因重试多次调用,通过事务控制表记录已执行状态,重复调用直接返回成功。
三、核心注解速查
| 注解 | 所属组件 | 作用 |
|---|---|---|
@EnableEurekaServer | Eureka | 启用 Eureka 服务端 |
@EnableDiscoveryClient | 通用 | 启用服务发现客户端 |
@EnableFeignClients | OpenFeign | 启用 Feign 客户端扫描 |
@FeignClient | OpenFeign | 声明 Feign 客户端接口 |
@LoadBalanced | LoadBalancer | 标记 RestTemplate 启用负载均衡 |
@EnableConfigServer | Config | 启用 Config Server |
@RefreshScope | Config | 标记 Bean 支持配置刷新 |
@EnableZuulProxy | Zuul | 启用 Zuul 网关 |
@SentinelResource | Sentinel | 标记 Sentinel 资源 |
@GlobalTransactional | Seata | 标记全局事务入口 |
@CircuitBreaker | Resilience4j | 标记熔断保护方法 |
四、版本对照速查
| Release Train | Spring Boot | Java | 命名空间 | 状态 |
|---|---|---|---|---|
| 2023.0.x (Leyton) | 3.2.x / 3.3.x | 17+ | jakarta | 推荐 |
| 2022.0.x (Kilburn) | 3.0.x / 3.1.x | 17+ | jakarta | 维护 |
| 2021.0.x (Jubilee) | 2.6.x / 2.7.x | 8+ | javax | 维护 |
| Hoxton | 2.2.x / 2.3.x | 8+ | javax | 终止 |
结语
从 Eureka 的"服务在哪里",到 Gateway 的"如何进入",再到 Zipkin 的"问题出在哪"——Spring Cloud 为微服务架构的每一个挑战都提供了成熟的解决方案。
记住三个原则:
- 用对版本:Spring Cloud 和 Spring Boot 的版本必须严格对应
- 不要重复造轮子:Spring Cloud 的每个组件背后都有 Netflix、Alibaba、HashiCorp 等公司的生产级实践
- 容错是第一优先级:服务总会出问题,关键是在出问题时优雅降级而非全站崩溃
祝你在微服务的世界中,既能俯瞰全局,又能深入细节。