spring cloud是分布式系统工具集,核心在于理解组件适用场景与替换成本:eureka(ap,下线延迟)、nacos(ap/cp可切,内置配置中心)、consul(强cp,脑裂风险);openfeign需显式配超时重试及连接池;gateway基于异步非阻塞,禁用阻塞代码;config依赖手动刷新或bus,nacos支持原生推送但需注意@refreshscope和dataid命名规范。

Spring Cloud 并不是一个单一框架,而是一套用于构建分布式系统的工具集,各组件职责明确、可插拔。面试中常被问及“用过哪些”“怎么选型”“出问题怎么排查”,关键不在背名字,而在理解每个组件在什么场景下不可替代、替换成本有多高。
服务注册与发现:Eureka vs Nacos vs Consul
三者都能做服务注册中心,但行为差异直接影响故障恢复和运维方式:
-
Eureka采用 AP 设计,自我保护模式开启后会容忍心跳丢失,适合网络不稳定但要求高可用的场景;缺点是服务下线延迟可能达 90 秒(默认leaseExpirationDurationInSeconds=90) -
Nacos支持 AP 和 CP 模式切换(通过curl -X PUT '$NACOS_SERVER/nacos/v1/ns/operator/switches?entry=serverMode&value=CP'),且默认健康检查是 TCP + HTTP 双探活,下线更及时;同时内置配置中心,避免多系统耦合 -
Consul是强 CP 系统,依赖 Raft 协议,服务异常时会立即剔除,但集群脑裂风险更高;需额外部署consul-template或配合Spring Cloud Consul Config做配置推送
面试若被问“为什么不用 Eureka”,不能只答“停更了”,要指出:Eureka 2.x 已停止维护,且其客户端缓存机制在灰度发布时容易导致流量打到已下线实例(需配合 ribbon.ServerListRefreshInterval 调小 + 自定义 IPing)。
服务调用:OpenFeign 的超时与重试必须显式配置
OpenFeign 默认不启用重试,且底层用的是 URLConnection(无连接池),直接跑在生产环境极易出现 SocketTimeoutException 或连接耗尽。
立即学习“Java免费学习笔记(深入)”;
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000
loggerLevel: BASIC
httpclient:
enabled: true # 启用 Apache HttpClient,支持连接池
ribbon:
ReadTimeout: 10000
ConnectTimeout: 5000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 1注意:ribbon.* 配置在 Spring Cloud 2020+ 中已被标记为废弃,应迁移到 spring-cloud-openfeign 的原生配置或改用 Resilience4j 做熔断重试。
网关:为什么 Spring Cloud Gateway 替代了 Zuul
Zuul 1.x 基于 Servlet 2.5,阻塞 I/O,每个请求独占线程;Spring Cloud Gateway 基于 Project Reactor 和 Netty,全异步非阻塞,吞吐量提升明显。但这也带来两个易忽略点:
- 自定义
GlobalFilter里不能写阻塞代码(如Thread.sleep()、JDBC 查询),否则会拖垮整个事件循环线程 - 文件上传需显式配置
spring.servlet.context-path和spring.cloud.gateway.httpclient.response-timeout,否则大文件上传会触发ReadTimeoutException - 路由谓词(
Predicate)顺序很重要:多个Path谓词匹配时,靠前的规则优先生效;调试时可通过logging.level.org.springframework.cloud.gateway=DEBUG查看匹配过程
配置中心:Spring Cloud Config 的刷新局限与 Nacos 的优势
Spring Cloud Config 本身不推配置,靠 /actuator/refresh 手动触发,或集成 Bus(需 RabbitMQ/Kafka)实现广播。但 Bus 引入消息中间件后链路变长,失败不易定位。
Nacos 原生支持配置变更推送,客户端监听 DataId+Group,收到变更后自动刷新 @ConfigurationProperties 或 @Value 注解字段。但要注意:
-
@Value刷新需配合@RefreshScope,否则值不会更新(且该注解不支持@Bean在Configuration类中) -
Nacos的dataId命名需严格匹配${spring.application.name}-${profile}.${file-extension},否则bootstrap.yml里配置的namespace和group无效 - 敏感配置(如数据库密码)不应明文存在 Nacos,应结合
Spring Cloud Config Server的encrypt.*加密,或用 Vault
真正难的不是记住组件名,而是清楚哪个组件在哪种拓扑结构下会成为瓶颈——比如 Eureka 集群跨机房部署时,Zone 感知失效;又比如 Gateway 上启用了全局限流但没配 redis 密码,导致所有请求 fallback 到本地计数器,限流完全失效。










