本轮 SpringCloud微服务架构面试题库(带答案)
生成时间:2026-05-21 22:37
【面试题】1. Eureka自我保护机制是什么?什么情况下会触发?生产环境要不要开启?
【标准答案】 Eureka自我保护机制是一种容错设计,当Eureka Server短时间内丢失大量客户端心跳时(超过85%的节点没有续约),会认为网络出问题了,不再剔除任何服务实例,保证服务注册表的可用性。
触发条件:15分钟内心跳续约比例低于85%。
生产环境建议开启。因为网络抖动很常见,如果关闭自我保护,一旦网络波动,大量健康服务会被错误剔除,造成服务雪崩。开启后最多会有一些已下线的"僵尸服务"留在注册表,但客户端有重试机制,比服务全部不可用好太多。可以通过eureka.server.enable-self-preservation=true配置。
【面试题】2. Nacos作为注册中心,AP和CP模式怎么选择?底层原理是什么?
【标准答案】 Nacos默认AP模式,保证高可用,适合注册中心场景;CP模式保证强一致性,适合配置中心场景。
选择逻辑:
- AP模式:服务注册优先可用性,即使集群节点间数据不一致也能对外服务,适合注册中心,因为服务发现容忍短暂不一致,但不可用会直接导致调用失败。
- CP模式:配置变更要强一致,否则不同实例读到不同配置会出问题,所以配置中心用CP。
底层原理:Nacos用Raft协议实现CP模式,通过Leader选举和日志复制保证一致性;AP模式用Distro协议,每个节点独立处理写请求并异步同步,不保证强一致但保证最终一致和分区容错。
【面试题】3. Ribbon和Spring Cloud LoadBalancer有什么区别?如何自定义负载均衡策略?
【标准答案】 Ribbon是Netflix的负载均衡组件,Spring Cloud LoadBalancer是Spring官方替代品。主要区别:
- Ribbon进入维护状态,不再更新;LoadBalancer是Spring Cloud官方维护
- Ribbon支持更多内置策略,LoadBalancer更轻量
- LoadBalancer与Spring生态整合更好,支持Reactive
自定义负载均衡策略(以LoadBalancer为例):
@Configuration
public class CustomLoadBalancerConfig {
@Bean
ReactorServiceInstanceLoadBalancer customLoadBalancer(Environment env, LoadBalancerClientFactory factory) {
String serviceId = env.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new CustomLoadBalancer(factory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class), serviceId);
}
}核心是实现ReactorServiceInstanceLoadBalancer接口,在choose()方法里写自己的选择逻辑,比如根据实例权重、响应时间、区域等维度选择。
【面试题】4. OpenFeign的超时重试机制怎么配置?有哪些坑需要注意?
【标准答案】 配置方式:
feign:
client:
config:
default:
connectTimeout: 5000 # 连接超时5秒
readTimeout: 10000 # 读取超时10秒重试机制默认关闭,需要自定义Retryer:
@Bean
public Retryer retryer() {
return new Retryer.Default(100, 1000, 3); // 初始间隔100ms,最大间隔1s,最多重试3次
}常见坑:
- 超时层级叠加:Feign超时 < Ribbon超时 < Hystrix/Sentinel超时,否则熔断先触发,Feign重试不生效。
- 重试风暴:GET请求重试没问题,POST/PUT重试可能造成重复操作,建议只读请求开重试。
- 超时太短:网关、注册中心、服务本身都有超时,要全链路规划,一般从外到内递减。
- 默认配置被覆盖:配置优先级是代码配置 > 配置文件 > 默认值,注意排查。
【面试题】5. Sentinel和Hystrix的熔断状态机原理是什么?有什么区别?
【标准答案】 两者都基于熔断状态机,核心三个状态:关闭→打开→半开。
状态转换逻辑:
- 关闭状态:正常请求,统计错误率/慢调用比例
- 打开状态:熔断生效,直接拒绝请求,走降级逻辑
- 半开状态:放行少量请求探测,成功则关闭,失败则重新打开
Sentinel vs Hystrix区别:
- 隔离策略:Hystrix线程池/信号量隔离,Sentinel信号量隔离(支持并发线程数限制)
- 熔断策略:Hystrix主要错误率,Sentinel支持慢调用比例、异常比例、异常数三种
- 限流能力:Sentinel原生支持QPS限流,Hystrix需要配合其他组件
- 控制台:Sentinel有实时监控和动态规则配置,Hystrix只有监控
- 性能:Sentinel基于滑动窗口,Hystrix基于RxJava,Sentinel性能更优
生产推荐Sentinel,生态更活跃,功能更全面。
【面试题】6. 令牌桶和漏桶限流算法有什么区别?Sentinel用的哪种?
【标准答案】 令牌桶:
- 固定速率往桶里放令牌,请求获取令牌才能通过
- 允许突发流量:桶里有令牌就能处理,不限制瞬间流量上限
- 适合应对流量抖动场景
漏桶:
- 请求先进队列,以固定速率从队列取出处理
- 严格限制流出速率,强制平滑流量
- 适合保护下游系统不被打垮
Sentinel方案: Sentinel的QPS限流用的是令牌桶算法的变体(滑动窗口+漏桶结合),核心是FlowSlot用滑动窗口统计QPS,超过阈值直接拒绝。也支持匀速排队模式(漏桶效果),请求进入队列匀速通过。
生产选型:需要应对突发用令牌桶,需要严格限速保护下游用漏桶,Sentinel两种模式都支持。
【面试题】7. Spring Cloud Gateway的核心架构是什么?过滤器链怎么工作的?
【标准答案】 核心架构三大组件:
- Route(路由):路由ID + 目标URI + 断言集合 + 过滤器集合
- Predicate(断言):匹配HTTP请求条件(路径、方法、Header、时间等)
- Filter(过滤器):请求/响应处理逻辑,分GatewayFilter(单路由)和GlobalFilter(全局)
工作流程: 请求 → DispatcherHandler → RoutePredicateHandlerMapping(匹配路由) → FilteringWebHandler(构建过滤器链) → 依次执行过滤器 → 调用下游服务 → 响应返回逆向执行过滤器后置逻辑
过滤器链顺序:
- pre阶段:按order从小到大执行
- post阶段:按order从大到小执行
自定义过滤器实现GlobalFilter + Ordered接口,order值决定执行顺序。比如鉴权过滤器order要小(先执行),日志过滤器order要大(后执行)。
【面试题】8. Nacos配置中心如何实现配置热更新?原理是什么?
【标准答案】 实现方式:
@RefreshScope
@RestController
public class ConfigController {
@Value("${app.name}")
private String appName;
}加上@RefreshScope注解,配置变更后自动刷新。
底层原理:
- 长轮询机制:客户端定时向Nacos Server发起30秒长轮询,服务端有变更立即返回,无变更等待到超时
- 配置缓存:客户端本地缓存配置文件,服务端推送变更后更新缓存
- 事件发布:配置变更后,Nacos Client发布RefreshEvent事件,Spring Cloud监听事件触发
@RefreshScopeBean重建
与Spring Cloud Config对比:
- Config依赖Git Webhook或手动refresh,实时性差
- Nacos内置长轮询,秒级生效,无需额外组件
注意事项:
@RefreshScope的Bean会被代理,不要频繁创建- 配置项较多时,用
@ConfigurationProperties批量注入,比多个@Value更高效
【面试题】9. Seata的AT模式和TCC模式有什么区别?各适合什么场景?
【标准答案】 AT模式(Automatic Transaction):
- 无侵入,基于数据库undo_log实现
- 一阶段:执行业务SQL,记录前后镜像到undo_log
- 二阶段提交:删除undo_log
- 二阶段回滚:根据undo_log反向生成SQL恢复数据
- 全局锁保证隔离性,避免脏写
- 适合场景:常规业务,对性能要求高,可接受短暂不一致
TCC模式(Try-Confirm-Cancel):
- 侵入性强,需要业务方实现三个接口
- Try:预留资源(冻结金额)
- Confirm:确认提交(扣减冻结金额)
- Cancel:回滚(释放冻结金额)
- 不依赖数据库,可以跨DB、跨存储
- 适合场景:高并发金融场景,要求强一致,可以接受复杂编码
选型建议: 90%场景用AT模式,开发成本低。涉及资金、库存核心扣减用TCC,保证数据绝对准确。
【面试题】10. Redis分布式锁如何实现?Redisson的看门狗机制是什么?
【标准答案】 基础实现(SET NX EX):
SET lock:resource value NX EX 30NX保证互斥,EX设置过期时间防止死锁。
Redisson方案(推荐):
RLock lock = redissonClient.getLock("lock:resource");
lock.lock();
try {
// 业务逻辑
} finally {
lock.unlock();
}看门狗机制(Watchdog): Redisson的lock()方法不传过期时间时,默认30秒过期,同时启动后台线程(看门狗),每10秒(1/3过期时间)自动续期,直到业务执行完调用unlock。防止业务未执行完锁就过期。
关键点:
- 锁续期:看门狗解决业务耗时超过锁过期时间的问题
- 锁释放:用Lua脚本保证原子性,只有锁持有者能释放
- RedLock:多Redis节点实现高可用,防止单点故障
避坑:
- 不要用
setnx+expire两条命令,非原子性,可能死锁 - 锁过期时间要大于业务执行时间,或用看门狗
- 释放锁要校验value,防止误删其他线程的锁