Skip to content

SpringCloud微服务架构面试题库 ​

生成时间:2026-05-21 21:47 | 题目数:10


【面试题】1. Nacos既支持AP又支持CP模型,它是怎么切换的?什么场景下该用哪种? ​

【标准答案】Nacos通过临时实例和持久化实例来区分AP与CP。临时实例(默认)走AP模式,用的是Distro协议——客户端发心跳,服务端不持久化,侧重可用性;持久化实例走CP模式,用的是Raft协议——服务端主动探活,数据强一致。切换方式很简单:注册实例时设置ephemeral=false就是CP,ephemeral=true(默认)就是AP。选型建议:业务服务上下线频繁、对实时性要求高用AP;配置信息、核心基础服务如数据库地址这种不能丢的用CP。面试时强调一点:大多数微服务场景用AP就够了,CP更适合存储类需求。

【面试题】2. Sentinel的滑动窗口统计和漏桶限流有什么区别?生产环境怎么选? ​

【标准答案】滑动窗口是统计维度的——它把时间窗口切成多个格子,比如1秒窗口分5个格子,每个格子独立计数,滑动时丢弃最老格子、加入新格子,解决固定窗口的临界突发问题。漏桶是限流策略——请求进来先排队,以固定速率流出,不管你进来多猛,出去都是匀速的。两者不是互斥的:Sentinel用滑动窗口做指标统计,在此基础上可以配漏桶、令牌桶或直接QPS拒绝。生产选型:对普通接口防护用QPS直接拒绝+滑动窗口统计就够了,简单高效;对需要平滑流量的下游服务(如调用第三方API有频率限制),用漏桶或匀速排队;对允许短暂突发的场景用令牌桶。关键点:Sentinel默认的FlowRule是滑动窗口+直接拒绝,已经能满足80%的限流需求。

【面试题】3. OpenFeign的超时和重试怎么配?怎么避免重试风暴? ​

【标准答案】超时分两层:连接超时connectTimeout和读取超时readTimeout,在yaml里配feign.client.config.default.connectTimeout和readTimeout。重试通过retryer控制,默认不重试,自定义需实现Retryer接口。避免重试风暴三个要点:第一,非幂等操作(POST等)绝对不重试,只对GET重试;第二,重试次数限制在1-2次,别贪多;第三,加上熔断器做兜底,重试失败直接走降级,别无限等。实际配置建议:connectTimeout设2-3秒,readTimeout根据接口RT的P99设(一般3-5秒),重试最多1次,配合Sentinel的熔断规则,超时比例超50%就熔断。还有个坑:Ribbon也有自己的重试配置MaxAutoRetries,两层重试会叠加,必须显式关掉Ribbon的重试或统一只保留一层。

【面试题】4. Spring Cloud Gateway的过滤器链执行顺序是怎样的?怎么实现鉴权+限流+日志的统一管控? ​

【标准答案】Gateway过滤器分三种:Global Filter(全局生效)、GatewayFilter(路由级别)、Default Filter(所有路由默认)。执行顺序按getOrder()返回值排序,值越小越先执行,pre阶段按顺序执行,post阶段逆序执行。鉴权+限流+日志的统一方案:用GlobalFilter链式处理——鉴权Filter设最高优先级(order=-100),验证JWT失败直接setComplete拦截;限流Filter其次(order=-50),用Redis+Lua脚本做令牌桶,超出返回429;日志Filter最低优先级(order=0),记录请求耗时和状态码。关键设计:Filter之间通过exchange.getAttributes()传数据,比如鉴权Filter把userId放进attributes,后续Filter直接取。生产建议:鉴权必须放最前面,限流在鉴权之后(未认证的请求直接拦,不浪费限流资源),日志放最后保证能记录所有请求包括被拦截的。

【面试题】5. Seata的AT模式原理是什么?它和TCC模式各自的优缺点和使用场景? ​

【标准答案】AT模式是二阶段提交的自动版。一阶段:拦截业务SQL,解析语义找前后镜像,生成undo_log存到业务库,然后提交本地事务;二阶段成功就异步删undo_log,失败就根据undo_log反向补偿。AT优点:对业务零侵入,只需要加个@GlobalTransactional注解;缺点:只能代理关系型数据库SQL操作,对Redis、MQ等非DB操作无能为力,而且全局锁会降低并发度。TCC模式:Try-Confirm-Cancel三个阶段由业务代码实现。优点:不依赖数据库,能处理任何资源(MQ、缓存、第三方API),锁粒度可以做到业务级别;缺点:侵入性强,每个接口要写三个方法,开发量大,还要自己处理空回滚和幂等。选型建议:纯数据库操作用AT,涉及MQ/缓存/第三方调用用TCC。混合场景可以AT+TCC混用,但要注意事务协调器的性能调优。

【面试题】6. Redis分布式锁用Redisson实现,锁续期和锁释放怎么保证可靠性?RedLock真的必要吗? ​

【标准答案】Redisson的看门狗(Watchdog)机制解决续期问题:默认锁30秒过期,后台每10秒(1/3超时时间)检查锁还被持有就自动续期,续期用Lua脚本保证原子性。如果持有锁的客户端宕机,看门狗也停了,锁自然过期释放。释放用unlock(),底层也是Lua脚本:先检查value是不是自己加的(防误删别人的锁),是的话删key+发释放消息。RedLock的争议:它在多个独立Redis实例上同时加锁,多数成功才算获取锁。但Martin Kleppmann指出RedLock在时钟跳变、GC停顿时仍可能不安全。实际建议:单机房用单Redis实例+Redisson就够了,可靠性靠业务层幂等兜底;跨机房多活场景可以用RedLock,但更推荐用Zookeeper或直接上etcd,CP模型天然适合分布式锁。面试要点:承认RedLock理论上的改进,但说明生产中大多数场景单实例+业务幂等已经够用,别过度设计。

【面试题】7. Spring Cloud Stream怎么保证消息的可靠投递和消费?消息积压了怎么处理? ​

【标准答案】可靠投递三步走:生产者端开启事务或confirm机制,确保消息到Broker;Broker端配多副本同步复制(RocketMQ同步刷盘、Kafka副本同步);消费者端手动ACK,处理完业务再确认。Spring Cloud Stream 3.x用的是函数式编程模型,@Bean定义消费函数,配合spring.cloud.stream.bindings.input.consumer.max-attempts控制重试次数。消息积压处理分紧急和长效:紧急方案——增加消费者实例数(水平扩容最直接)、临时提高消费线程数、跳过非核心消息(降级处理)、创建临时Topic做分流;长效方案——优化消费逻辑减少RT、批量消费减少IO、消息分片让同一Key的消息到同一队列并行消费。关键指标监控:消费者Lag(积压量),设置告警阈值,比如积压超过10万条就触发扩容。还有一招:积压严重时先快速消费丢消息外的元数据,业务数据入库后再异步补全。

【面试题】8. 微服务之间调用怎么传递Token?网关鉴权后内部服务还需要再校验吗? ​

【标准答案】Token传递分两种方案。方案一:网关验证后把用户信息放到请求头往下传,内部服务从Header取(如X-User-Id),简单但Header可能被伪造。方案二:网关验证JWT后原样透传,内部服务只验签名不查库,性能好但JWT过大增加网络开销。网关鉴权后内部服务要不要再校验?答案是:核心服务必须校验,边缘服务可以不校验。原因——零信任架构下,内部服务也可能被直接调用(如Pod内直接请求),不校验就是裸奔。实现方式:内部服务用Filter拦截,从Header取JWT验签名,通过Spring Security的SecurityContext设置认证上下文。Feign调用传递Token:用RequestInterceptor从当前上下文取Token塞到请求头。关键点:网关校验是第一道防线,内部校验是纵深防御,两者互补不冲突。Refresh Token放网关统一刷新,内部服务只管Access Token的有效期。

【面试题】9. SkyWalking和Zipkin在链路追踪上的架构差异是什么?对业务性能影响怎么评估? ​

【标准答案】核心架构差异:Zipkin是客户端埋点+服务端聚合,数据通过HTTP或Kafka传到Zipkin Server,存储用Elasticsearch/Cassandra,轻量但规模大了性能下降;SkyWalking用Java Agent无侵入埋点,数据走gRPC发到OAP集群,存储用Elasticsearch/H2,天然支持大规模分布式。性能影响评估:Zipkin的Brave客户端埋点,每条Span约增加0.5-1ms延迟,采样率1%时几乎无感;SkyWalking的Agent字节码增强,约增加1-3%的CPU开销和5-10ms的P99延迟,但不用改代码。采样策略:Zipkin用概率采样(如10%),简单但可能漏掉慢请求;SkyWalking支持基于TraceID的固定采样和自适应采样,能保证慢请求不被漏。选型建议:中小规模(<500实例)用Zipkin够用,轻量上手快;大规模(>500实例)或不想改代码的场景用SkyWalking,Agent方式运维成本低。性能优化通用做法:异步发送Trace数据、控制采样率、Agent和业务进程隔离部署。

【面试题】10. Kubernetes环境下SpringCloud微服务的注册发现怎么做?还用Eureka吗? ​

【标准答案】K8s环境下不建议再用Eureka,因为服务注册发现K8s本身就提供了——Service资源就是注册中心,CoreDNS就是发现机制。方案一:Spring Cloud Kubernetes,直接读K8s Service作为注册表,配置spring.cloud.kubernetes.discovery.enabled=true,应用自动发现同Namespace下的Service,零额外组件。方案二:Nacos依然可用,K8s里部署Nacos集群,应用连Nacos,好处是配置中心复用、多集群统一管理。方案三:Service Mesh(Istio),服务发现和负载均衡全交给Sidecar,应用无感知。对比:Eureka在K8s里是多余的,还要额外维护集群;Nacos适合需要配置中心+多集群管理的场景;Spring Cloud Kubernetes适合纯K8s环境不想引入额外中间件的场景;Istio适合全链路治理需求。面试重点:说明为什么Eureka不适合——K8s的Pod IP不固定、生命周期短,Eureka的心跳机制和自我保护跟K8s的调度机制冲突,容易出现假上线。最终建议:K8s原生用Spring Cloud Kubernetes或Istio,混合云用Nacos。