Skip to content

本轮 SpringCloud微服务架构面试题库(带答案)

【面试题】1. Eureka和Nacos在服务注册发现上的核心架构差异是什么?生产环境怎么选? ​

【标准答案】核心差异在于一致性模型:Eureka是AP模型,优先保证可用性和分区容错,节点间数据异步复制,可能出现短暂不一致但服务不会因注册中心故障而不可用;Nacos同时支持AP和CP,临时实例走AP(Distro协议),持久化实例走CP(Raft协议),可以按业务灵活切换。选型建议:如果是纯Spring Cloud Netflix体系、对一致性要求不高、服务实例都是临时的,Eureka够用且运维简单;如果需要同时管理临时和持久化实例、需要配置中心一体化、或者用Spring Cloud Alibaba全家桶,Nacos是更优选择。另外Nacos自带配置中心,省去单独部署Config Server,运维成本更低。

【面试题】2. Sentinel的熔断状态机是怎么工作的?半开状态下为什么不能让所有请求通过? ​

【标准答案】Sentinel熔断有三个状态:关闭→开启→半开。关闭状态下正常放行请求,同时统计慢调用比例或异常比例;当指标超过阈值(比如慢调用比例>50%),切换到开启状态,所有请求直接走降级逻辑,不调用下游。经过熔断时长后进入半开状态,此时只放行少量探测请求(不是全部),如果探测请求成功说明下游恢复,关闭熔断;如果探测失败说明还没好,继续熔断。半开状态不能全量放行,核心原因是如果下游还没恢复就打全量流量过去,会再次压垮下游,导致"雪崩→恢复→再雪崩"的振荡。少量探测既验证了下游状态,又控制了风险,这是熔断器的设计精髓。

【面试题】3. Spring Cloud Gateway的过滤器链执行顺序是怎样的?如何实现统一鉴权? ​

【标准答案】Gateway过滤器分三类:GatewayFilter(路由级别)、GlobalFilter(全局级别)和GatewayFilterChain(过滤器链)。执行顺序按order值排序,值越小越先执行,pre阶段按order升序,post阶段按order降序——也就是"洋葱模型"。统一鉴权实现:自定义一个GlobalFilter,实现Ordered接口设order=-1(优先级高于路由过滤器),在filter方法中从ServerWebExchange获取请求头中的Token,校验JWT签名和过期时间,合法则chain.filter继续,不合法则设置response状态码401并return。关键点:鉴权Filter要放在最前面,防止未认证请求穿透到后置过滤器;同时排除登录/公开接口的路径,用path匹配跳过鉴权。

【面试题】4. Seata的AT模式是如何保证分布式事务一致性的?全局锁的作用是什么? ​

【标准答案】AT模式是自动化的两阶段提交。一阶段:拦截业务SQL,查询修改前数据生成before-image,执行业务SQL,查询修改后数据生成after-image,一起组成undo-log写入本地数据库,然后提交本地事务——业务SQL和undo-log在同一个本地事务里,保证了原子性。二阶段:如果全局提交,异步删除undo-log即可,非常轻量;如果全局回滚,根据undo-log的before-image反向补偿,生成回滚SQL执行。全局锁的作用:在二阶段提交前,防止脏写——即防止其他事务修改了正在参与分布式事务的数据。具体是TC(事务协调器)在分支事务一阶段提交后,对涉及的数据加全局锁,其他全局事务要等锁释放才能修改,保证回滚时数据没被别人改过。本地事务不受全局锁影响,所以AT模式对性能的影响可控。

【面试题】5. Redis分布式锁用SET NX EX就够了?Redisson做了哪些增强? ​

【标准答案】SET NX EX是最基础的Redis分布式锁,但有三个致命问题:①锁过期释放但业务没执行完——其他线程拿到锁导致并发问题;②客户端宕机,锁到期自动释放是正常的,但如果网络分区导致误判就更麻烦;③主从切换时锁数据丢失——主节点加锁后还没同步到从节点就挂了,从升主后其他线程可以再加锁。Redisson的增强:①看门狗(Watchdog)自动续期——默认锁30秒,每10秒检查锁还被持有就续期到30秒,业务没执行完锁不会过期;②可重入锁——用Hash结构记录锁持有者和重入次数,同一线程可多次加锁;③RedLock算法——向多个独立Redis实例加锁,多数成功才算获取锁,解决主从切换锁丢失问题。生产环境推荐用Redisson,SET NX EX只在简单场景够用。

【面试题】6. OpenFeign的超时和重试配置有哪些坑?如何避免请求被重复执行? ​

【标准答案】OpenFeign超时分两层:Feign层的connectTimeout和readTimeout,以及Ribbon层的ConnectTimeout和ReadTimeout。如果两个都配了,实际生效的是Ribbon层的(老版本),新版本用Spring Cloud LoadBalancer则只有Feign层的配置生效。重试的坑:Ribbon默认重试1次(MaxAutoRetries=0, MaxAutoRetriesNextServer=1),如果接口非幂等(POST创建订单),重试会导致重复创建。避免方式:①对非幂等接口关闭重试——设MaxAutoRetries=0且MaxAutoRetriesNextServer=0;②全局关闭重试,只对个别幂等接口手动开启;③用Feign的重试器替代Ribbon重试,Feign默认不重试;④更推荐在业务层用唯一请求ID做幂等校验,重试时携带相同ID,服务端去重。配置原则:超时时间要大于下游P99响应时间但小于用户容忍度,重试只对幂等接口开启。

【面试题】7. 链路追踪中TraceId是怎么跨服务传递的?异步线程池场景下链路为什么会断? ​

【标准答案】TraceId跨服务传递依赖HTTP请求头:Sleuth在发起HTTP调用时,自动在请求头中注入traceId(X-B3-TraceId)和spanId(X-B3-SpanId),下游服务从请求头中提取并继续传递,形成完整调用链。异步线程池链路断裂的原因:Sleuth默认只在当前线程的ThreadLocal中维护Trace上下文,新线程没有继承主线程的ThreadLocal数据,所以traceId丢失。解决方案:①用Sleuth提供的LazyTraceExecutor包装线程池,它会在提交任务时捕获主线程的Trace上下文,在新线程执行时恢复;②用@Async注解时配合Sleuth自动包装;③手动传递:主线程获取当前traceId,新线程中用Tracer手动设置。核心原则就是确保Trace上下文在线程切换时正确传递,ThreadLocal不会自动继承。

【面试题】8. Nacos配置中心如何实现配置热更新?和Spring Cloud Config相比优势在哪? ​

【标准答案】Nacos配置热更新有两种方式:①@RefreshScope注解——配置变更时销毁并重建Bean,重新注入最新配置值;②@NacosValue的autoRefreshed=true或@Value配合RefreshScope——配置变更时自动更新字段值。底层机制:客户端通过长轮询(Long Polling)监听配置变化,Nacos服务端维护配置的MD5值,客户端定时对比MD5,发现变化则拉取最新配置并触发RefreshEvent。对比Spring Cloud Config的优势:①Config依赖Git/SVN存储,变更需要推送到仓库再刷新,链路长延迟高;Nacos自带存储,变更秒级生效;②Config需要配合Bus(RabbitMQ/Kafka)做批量刷新,Nacos原生支持;③Config没有管理界面,Nacos自带可视化控制台;④Nacos同时提供注册中心和配置中心,部署运维更简单。唯一Config的优势是对Git生态的天然集成和审计日志。

【面试题】9. 微服务场景下JWT Token如何安全地在服务间传递?Refresh Token机制怎么设计? ​

【标准答案】JWT在服务间传递的方案:网关鉴权通过后,将Token放入请求头(通常是Authorization: Bearer xxx),通过HTTP头在服务调用链中传递。OpenFeign通过RequestInterceptor拦截器自动将上游的Token透传给下游;如果是异步调用或消息队列场景,需要手动将Token放入消息体或线程上下文。安全要点:①服务间内网调用也必须验Token,防止内网被突破后横向移动;②Token不要放入URL参数,会出现在日志里;③敏感操作要做二次校验。Refresh Token机制:Access Token短过期(30分钟),Refresh Token长过期(7天);Access Token过期后用Refresh Token换新Token,Refresh Token过期必须重新登录;Refresh Token只在认证服务校验,不下发到业务服务;注销时要把Refresh Token加入黑名单(Redis存储),防止已泄露的Refresh Token继续换新Access Token。关键:Refresh Token只使用一次,每次刷新后旧Refresh Token作废,返回新的Refresh Token,形成Token轮转。

【面试题】10. 灰度发布在Spring Cloud Gateway中怎么实现?有哪些常见策略? ​

【标准答案】灰度发布在Gateway层实现的核心思路:根据路由规则将不同比例或特征的流量导向不同版本的服务实例。实现方式:①基于权重路由——自定义GlobalFilter或Predicate,按配置的权重比例(如v1:80%, v2:20%)将请求随机分配到不同版本;②基于请求特征路由——根据请求头(如User-Agent、Region)、Cookie、参数等特征匹配,比如带gray=true请求头的流量全部走v2版本;③基于用户标签路由——在用户中心给特定用户打灰度标签,请求到达网关时查标签决定路由。技术实现细节:Nacos元数据中给服务实例打version标签(v1/v2),Gateway的自定义Predicate根据权重或特征选择对应版本的实例列表。常见策略:金丝雀发布(先1%流量到新版本,观察没问题再逐步扩大)、蓝绿部署(两套完整环境,流量一次性切换)、A/B测试(按用户特征分流对比效果)。关键点:灰度期间要能快速回滚,Gateway路由规则要支持动态刷新,监控指标要区分版本统计。