SpringCloud微服务架构面试题库
生成时间: 2026-05-24 21:50 题目数量: 10题
本轮 SpringCloud微服务架构面试题库(带答案)
【面试题】1. Nacos作为注册中心,它的AP和CP模式怎么选?实际项目中怎么用的?
【标准答案】Nacos默认是AP模式,保证可用性优先。AP模式下,注册中心挂了,服务还能用本地缓存继续通信;CP模式保证一致性,但可能影响可用性。
实际选型看业务:如果服务对可用性要求高,比如电商核心链路,选AP,宁可脏数据也不能停服务;如果对数据一致性要求严格,比如金融账户服务,可以切CP。我们项目用的是默认AP,通过服务健康检查和心跳机制,配合负载均衡的重试策略,保证整体可用性。真正的一致性场景,比如分布式事务,我们是用Seata单独保证,不依赖注册中心。
【面试题】2. Sentinel的熔断降级有哪几种状态?状态之间怎么流转的?
【标准答案】Sentinel熔断有三种状态:关闭(Closed)、开启(Open)、半开(Half-Open)。默认关闭,请求正常通过。
当错误比例、异常数或慢调用比例超过阈值,熔断器从Closed切换到Open,直接拒绝所有请求,走降级逻辑。熔断时长后,进入Half-Open状态,放行一个请求探测:成功就切回Closed,失败就重新Open。这个状态机设计跟保险丝一样,先断电保护系统,再试探恢复。
实际配置上,比如我们订单服务配置慢调用比例超过50%且超过5个请求就熔断,熔断时长10秒,这样既能快速止损,又不会一直卡死。
【面试题】3. Spring Cloud Gateway怎么实现统一鉴权?Token怎么传递给下游服务?
【标准答案】Gateway做统一鉴权是标准做法。我们在网关层配置全局过滤器,拦截所有请求,从Header里取Token,校验JWT的签名和过期时间,通过后把用户信息放入Header传给下游。
具体实现:自定义一个GlobalFilter,用@Component注入,在filter方法里校验Token。JWT的好处是无状态,网关解析后把userId、role等放到请求头,下游服务直接从Header取,不用再查库。如果是OAuth2,网关负责调用认证服务校验,下游只管业务逻辑。
我们项目还做了白名单配置,登录、验证码接口不走鉴权,其他接口统一拦截,这样既安全又灵活。
【面试题】4. OpenFeign调用超时了怎么办?有哪些配置策略?
【标准答案】OpenFeign超时要分两层看:连接超时和读取超时。连接超时是建立TCP连接的时间,读取超时是等待响应的时间。
配置上,我们用feign.client.config.default.connectTimeout和readTimeout设置,默认连接超时10秒,读取超时60秒,但实际会按服务调优。比如调用支付服务,设置短一点,5秒超时快速失败;调用报表导出,可以放宽到30秒。
超时后走重试策略,Feign默认有重试器,可以配置重试次数和间隔。但我们一般配置成不重试或只重试1次,因为重试可能放大流量,导致雪崩。真正的容错交给Sentinel熔断降级,超时直接走fallback,返回兜底数据。
【面试题】5. 分布式锁用Redis还是Zookeeper?各有什么优缺点?
【标准答案】Redis分布式锁优点是性能高,实现简单,用SET key value NX EX seconds 一条命令搞定加锁,Redisson还封装了看门狗机制自动续期。缺点是Redis是AP系统,主从切换时可能锁丢失,RedLock方案又太复杂。
Zookeeper锁优点是强一致性,CP模型,临时节点加监听,锁释放自动通知,不会丢锁。缺点是性能不如Redis,每次加锁要写磁盘,而且ZK集群维护成本高。
我们项目用Redisson,因为业务对性能要求高,一致性要求没那么严格。真正的强一致性场景比如分布式事务协调者,我们才用Zookeeper。选型关键是:业务能容忍Redis极端情况下的锁丢失吗?能忍就用Redis,不能忍就ZK。
【面试题】6. Nacos Config配置热更新怎么实现的?配置改了服务要重启吗?
【标准答案】Nacos配置热更新不用重启服务,核心是动态刷新机制。我们在配置类上加@RefreshScope注解,Nacos推配置变更时,Spring Cloud会销毁旧的Bean,用新配置重建。
底层原理是Nacos Client通过长轮询监听配置变化,服务端配置更新后,Client收到推送,触发RefreshEvent事件,Spring重新绑定配置值。我们项目把数据库连接池、限流阈值这些参数放Nacos,改动后秒级生效。
注意点是:@RefreshScope只支持@ConfigurationProperties和@Value,而且Bean是代理对象,每次刷新会重建,不要在里面存状态。如果是第三方Bean不支持刷新,可以用Environment手动读取或监听配置变更事件自己处理。
【面试题】7. Seata的AT模式原理是什么?为什么能保证分布式事务一致性?
【标准答案】AT模式是Seata最常用的模式,核心是"自动补偿"。业务执行SQL时,Seata会自动记录前镜像和后镜像到undo_log表,如果事务提交失败,根据前镜像自动生成反向SQL回滚。
整个流程:TM发起全局事务 -> RM注册分支事务 -> 执行业务SQL -> TC协调者决定提交或回滚。AT模式的一阶段本地事务直接提交,释放锁,二阶段异步删undo_log,性能高。如果回滚,根据undo_log反向生成delete或update语句。
AT模式保证最终一致性,缺点是写隔离级别只有读已提交,可能出现脏读。我们用AT模式做订单+库存扣减,一阶段各自提交,二阶段TC统一协调,失败就自动回滚,比TCC代码侵入小得多。
【面试题】8. 微服务链路追踪,TraceId怎么在服务间传递的?对性能有影响吗?
【标准答案】TraceId传递核心是HTTP Header透传。Sleuth在发请求时,把TraceId、SpanId放到请求头X-B3-TraceId、X-B3-SpanId,下游服务从Header取出来,继续往下传,整个链路就能串联起来。
异步场景比如线程池、MQ,Sleuth提供装饰器手动传递。我们用RocketMQ,在消息头里放TraceId,消费者取出后设置到当前上下文。跨线程用TraceContext手动传递。
性能影响是有的,每个请求要生成TraceId、写日志、上报Zipkin,采样率设成100%确实有开销。我们线上设置10%采样,异常请求强制全采样,用SpanNamer过滤关键路径,这样既能追踪问题,性能损耗可控在3%以内。
【面试题】9. Spring Cloud Gateway的过滤器链怎么执行?怎么自定义全局过滤器?
【标准答案】Gateway过滤器分两类:GatewayFilter(局部)和GlobalFilter(全局)。请求进来先走Pre阶段的过滤器,比如鉴权、限流,然后转发到后端服务,响应返回走Post阶段的过滤器,比如响应头处理、日志记录。
执行顺序由@Order注解或getOrder方法决定,数字越小越先执行。全局过滤器所有路由生效,我们用它做统一鉴权:自定义类实现GlobalFilter和Ordered接口,在filter方法里校验Token,通过就chain.filter继续,不通过就返回401。
具体代码:@Component注解,注入SecurityService,在filter方法里从exchange.getRequest拿Header,校验通过后把用户信息放exchange里,return chain.filter(exchange)继续。如果要改响应,可以用ServerHttpResponseDecorator包装,在Post阶段处理返回值。
【面试题】10. 服务注册到Nacos后,怎么保证下线时不丢流量?
【标准答案】服务下线最怕的是注册中心删了,但调用方缓存没更新,请求打过来直接报错。Nacos提供了优雅下线机制。
我们用Spring Cloud的@PreDestroy钩子,服务关闭时先调用Nacos API取消注册,但不是直接删,而是标记为不健康状态,等一段缓冲时间。调用方收到服务变更推送,从本地缓存移除这个实例。同时我们配置了Ribbon的重试策略,失败会自动切到其他实例。
更稳妥的做法是:先在网关层摘流量,把服务从负载均衡器里剔除,等处理完存量请求再关服务。Nacos还支持延迟注册,启动后等应用就绪再注册,避免启动瞬间流量打进来。
实际我们用k8s的PreStop钩子,sleep 30秒,让Nacos推送变更、负载均衡刷新缓存,保证流量不丢。
题目覆盖范围:
- 服务注册与发现(Nacos AP/CP模式)
- 熔断限流降级(Sentinel状态机)
- API网关(统一鉴权、Token传递)
- 服务调用(OpenFeign超时配置)
- 分布式锁(Redis vs Zookeeper)
- 配置中心(Nacos热更新)
- 分布式事务(Seata AT模式)
- 链路追踪(TraceId传递)
- API网关(过滤器链、自定义过滤器)
- 服务治理(优雅下线)