Spring Cloud 面试知识点
本页只放 Spring Cloud 面试标准回答、项目话术和知识点跳转。完整调用链路、注册中心、Feign、Gateway、Sentinel、配置中心的原理统一放到对应知识点文档中。
使用方式
mermaid
flowchart TD
A["面试页:组件怎么回答"] --> B["知识点页:组件原理"]
B --> C["项目页:医疗采集平台怎么落地"]总体问题
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 怎么判断 Spring Cloud 是否真正学懂 | 不能只背组件名。真正学懂要能从微服务为什么需要治理、服务注册发现、OpenFeign 动态代理、LoadBalancer 实例选择、Gateway 路由转发、超时重试熔断限流降级、配置中心加载刷新、链路追踪和生产排查一路讲下来,并能说明每个组件解决什么、不解决什么。 | Spring Cloud从零到精通验收清单 |
| Spring Boot 和 Spring Cloud 区别 | Spring Boot 解决单个服务快速开发和启动;Spring Cloud 解决多个服务之间的注册发现、远程调用、网关路由、熔断降级、配置中心等协作治理问题。 | SpringCloud总览 |
| Spring Cloud 核心主线是什么 | Spring Cloud 的核心主线是:服务注册到注册中心,调用方通过服务名发现实例,Feign 或 WebClient 把接口调用变成 HTTP 请求,LoadBalancer 选择实例,Gateway 统一入口,Sentinel/Resilience4j 做限流熔断降级,配置中心统一参数,链路追踪串起跨服务请求。 | SpringCloud从零到生产级掌握 |
| 微服务一次请求怎么走 | 请求通常先进 Gateway,网关按 Route 和 Predicate 匹配路由,执行鉴权、限流、灰度、日志和 Trace 等 Filter;lb://服务名 会触发 Gateway 侧 LoadBalancer 选择目标服务实例并转发。服务内部调用常用 OpenFeign,启动时扫描 @FeignClient 并创建代理,运行时代理把方法调用转换成 HTTP 请求,RequestInterceptor 透传 Trace 和认证上下文;没有固定 URL 时,请求交给 LoadBalancer,LoadBalancer 通过 DiscoveryClient 读取 Nacos/Eureka 等实例快照,经过健康、版本、区域、权重等过滤后选择 ServiceInstance,再由底层 HTTP Client 真正发请求。调用链路还会叠加超时、重试、限流、熔断、降级和指标统计:限流可能让请求根本不发出,熔断打开会快速失败,读取超时不代表下游没执行,写操作必须靠幂等号查询状态或补偿。 | 完整调用流程、商业场景训练营、Gateway、Feign、LoadBalancer、Sentinel |
| 微服务的控制面和数据面有什么区别 | 控制面通过注册中心、配置中心、规则中心分发实例、配置和治理规则;数据面由 Gateway、Feign/Dubbo、HTTP Client、服务实例或 Service Mesh Proxy 传输真实业务请求。注册中心通常不转发每次业务请求,消费者拿到实例列表后直接访问提供者。 | 控制面与数据面、组件全景 |
| 注册中心是否经过每一次业务调用 | 通常不经过。调用方订阅或拉取实例列表并维护本地缓存,LoadBalancer 从缓存快照选择实例,HTTP/RPC 客户端直接访问目标 IP 和端口。注册中心故障时已有缓存可能暂时可用,但新实例发现、故障摘除和规则更新会受影响。 | 注册发现原理、服务调用链路 |
| 微服务组件怎么分类 | 地址治理用 Nacos/Eureka/Consul/Kubernetes;HTTP 调用用 OpenFeign、HTTP Interface、RestClient/WebClient;RPC 用 Dubbo/gRPC;实例选择用 LoadBalancer;入口用 Gateway/Ingress;容错用 Sentinel/Resilience4j;配置用 Nacos/Apollo/Config;追踪用 Micrometer/OpenTelemetry/SkyWalking;异步事件用 Kafka/RabbitMQ/RocketMQ。 | 微服务组件全景、技术演进与选型 |
| 为什么不能每一层都重试 | 多层重试会乘法放大请求,例如 A 调 B、B 调 C 都最多尝试 3 次,C 最坏可能收到 9 次;下游越慢,上游重试越多,形成重试风暴。应只在合适层对幂等、瞬时故障有限重试,并采用指数退避、随机抖动、总时间预算和熔断。 | 重试放大、调用链重试与熔断 |
| Spring Cloud 新旧技术怎么对应 | 经典 Netflix 体系常见 Eureka、Ribbon、Hystrix、Zuul、Sleuth;当前常见 Nacos/Consul、Spring Cloud LoadBalancer、Sentinel/Resilience4j、Spring Cloud Gateway、Micrometer Tracing/OpenTelemetry。组件变化了,但注册发现、负载均衡、网关、熔断、配置、链路追踪这些治理问题没有变。 | 技术演进与选型 |
| 微服务边界怎样划分 | 不能按数据库表一表一服务,而要按业务能力、限界上下文、状态机、数据事实源和团队Owner划分。再用调用频率、事务范围、容量差异、发布价值和故障隔离收益验证。边界没稳定时先做模块化单体,不要过早拆进程。 | 架构演进与服务拆分、服务粒度判断 |
| 为什么微服务不建议共享数据库 | 共享库允许服务绕过对方API和状态机直接写表,导致Schema发布、锁竞争、数据规则和故障责任耦合。原则是一份事实数据只有一个写入Owner,其他服务通过API、事件、CDC、查询模型或快照获取信息。 | 数据所有权、共享数据库迁移 |
| Spring Cloud Alibaba 是什么 | Spring Cloud Alibaba 是 Alibaba 生态与 Spring Cloud 编程模型的集成体系,常见能力包括 Nacos 注册发现与配置、Sentinel 流量治理、RocketMQ Binder 和 Seata、Dubbo 集成。它不是单个中间件,也不会让微服务天然获得强一致或恰好一次。 | 生态位置、组件职责地图 |
| Spring Cloud Alibaba 为什么要看版本矩阵 | Spring Boot、Spring Cloud 和 Spring Cloud Alibaba 属于不同发布体系,底层 API 与自动配置存在兼容边界。项目应先按 JDK 选择 Boot,再选择兼容的 Cloud 发布列车和 Alibaba 版本,并核对 Nacos、Seata、RocketMQ 客户端与服务端,而不是给单个 Starter 强行升级版本。 | 版本与 BOM |
| Spring Cloud Alibaba 应用启动时发生什么 | 应用先建立配置环境并通过 Config Data 等机制拉取远程配置,使配置在 Bean 创建前进入 Environment;随后创建 Feign、LoadBalancer、Sentinel 等适配器,启动 Web 容器,再向 Nacos 注册实例并订阅依赖服务,最后通过 Readiness 后接收流量。 | 应用启动全过程 |
| Spring Cloud Alibaba 请求调用链怎么走 | 外部请求先经 Gateway 路由、鉴权和限流,lb:// 触发 LoadBalancer 从 Nacos 本地实例快照选择目标;服务内部 Feign 动态代理构造 HTTP 请求,Sentinel 对资源统计和规则判断,再由 LoadBalancer 与 HTTP Client 直连提供者,Trace 上下文贯穿全链路。 | 请求端到端全过程、Feign 与 LoadBalancer |
| Spring Cloud 中到底是谁负责发请求 | 真正发出网络请求的是底层 HTTP Client,例如 Apache HttpClient、OkHttp、JDK Client 或 Reactor Netty。Feign 负责把接口方法解析成 HTTP 请求;Nacos 负责注册发现并提供实例列表;Spring Cloud LoadBalancer 负责从候选实例里选一个并把服务名替换成真实 IP 和端口。Nacos 不转发业务请求,调用方最终直连被选中的服务实例。 | 到底是谁负责发请求、Feign分工 |
| Feign 是不是从 Nacos 获取地址后自己发请求 | 不能这么粗略理解。Feign 本身不直接依赖 Nacos,它通过 Spring Cloud 的 LoadBalancer 和 DiscoveryClient 抽象间接使用 Nacos 实例数据;LoadBalancer 选出 ServiceInstance 后,Feign 的 LoadBalancer Client 会重建真实 URL,最后委托底层 HTTP Client 发送。这样可以屏蔽 Nacos、Eureka、Consul 等注册中心差异。 | 服务调用链路、LoadBalancer桥接 |
注册中心和服务发现
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 注册中心做什么 | 注册中心保存服务名和实例地址的映射。服务启动后注册自己的 IP、端口和健康状态;调用方通过服务名获取实例列表,再配合负载均衡发起调用。 | Eureka、Nacos |
| 注册中心、服务发现和LoadBalancer完整关系是什么 | 注册中心保存服务名、实例地址、健康状态和metadata;消费者订阅或拉取实例列表并维护本地快照;LoadBalancer在本地快照上按健康、版本、区域和权重过滤后选择实例;底层HTTP Client才真正发请求。注册中心属于控制面,通常不转发业务流量。 | 服务发现完整原理、调用链路 |
| 注册中心挂了服务还能调用吗 | 运行中的调用方如果已有本地快照,且目标实例数据面可达,短时间可能继续调用;但新实例注册、坏实例剔除、规则变更、新消费者启动会受影响。缓存为空或全是坏实例时仍会失败,所以还要有超时、熔断和降级。 | 控制面和数据面、本地快照 |
| Eureka 注册发现流程怎么走 | 服务实例启动后把服务名、IP、端口、状态和元数据注册到 Eureka Server,并定期发送心跳续约;消费者从 Eureka 拉取注册表并缓存到本地,调用时按服务名获取实例列表,再交给 Ribbon 或 Spring Cloud LoadBalancer 选择实例发起 HTTP 调用。 | Eureka 注册发现全过程 |
| Eureka 为什么偏 AP | Eureka 更关注可用性,允许注册表在 Server 节点和客户端缓存中短时间不一致。大量心跳丢失时会进入自我保护,不立刻剔除实例,避免网络分区导致健康实例被误删。代价是调用方可能短时间拿到过期实例,所以还要配合超时、重试、熔断和优雅下线。 | Eureka 和 CAP、自我保护机制 |
| Eureka 自我保护机制是什么 | 当短时间内大量实例心跳丢失时,Eureka 会怀疑是网络分区或自身网络异常,而不是服务全部宕机,于是倾向于保留注册表,避免误删大量健康实例。它提高可用性,但可能保留过期实例,调用方必须有超时和容错。 | 自我保护机制 |
| Eureka 控制台有实例但 Feign 仍然无实例怎么排查 | 先确认 Feign 的服务名和 spring.application.name 是否一致,再查调用方连接的是不是同一个 Eureka、环境和网络是否一致;然后看调用方本地缓存是否刷新、实例状态是否 UP、是否被灰度、zone、metadata 或健康过滤过滤掉。不能只看 Eureka 控制台。 | 注册中心有实例但调用失败 |
| 服务下线后为什么还会被调用到 | 服务下线存在传播窗口。实例停止、注册中心剔除、调用方刷新本地注册表、HTTP 连接池释放旧连接不是同一瞬间完成的。生产要先摘流或 Readiness 置为不可用,等待缓存刷新和存量请求结束,再关闭进程。 | 服务下线后还被调用 |
| Eureka 和 Nacos 怎么选 | Eureka 是 Spring Cloud Netflix 老体系注册中心,老项目维护仍然常见;Nacos 属于 Spring Cloud Alibaba,提供注册发现和配置中心,生态更活跃。新项目如果使用 Alibaba 体系通常优先 Nacos,老项目则要理解 Eureka 的注册、续约、剔除、自我保护和客户端缓存。 | Eureka 和 Nacos 对比、技术演进与选型 |
| Nacos 是什么 | Nacos 是 Spring Cloud Alibaba 体系常用的注册中心和配置中心。注册发现负责维护服务名到实例列表的映射,配置中心负责集中管理多环境配置。它通过 Namespace、Group 做隔离,通过 Service、Instance、DataId 等模型管理服务和配置。 | Nacos 注册发现与配置中心 |
| Nacos 服务发现流程怎么走 | 服务提供者启动后把服务名、IP、端口、cluster、metadata 等注册到 Nacos,临时实例会定期心跳;消费者订阅目标服务并把实例列表缓存在本地,调用时 Feign 或 Gateway 通过 LoadBalancer 从本地实例列表中选择一个实例发起 HTTP 调用。 | Nacos 服务注册全过程、服务发现和订阅推送 |
| 怎么保证本地服务列表是最新的 | 不能保证任意瞬间绝对最新,只能通过订阅推送、定期刷新、本地缓存过期、Readiness摘流、优雅下线和连接池回收缩短旧列表窗口。注册中心更新、客户端快照替换、LoadBalancer选址和HTTP连接释放都是异步过程,所以生产必须允许短暂不一致并用超时、有限重试、幂等和观测兜底。 | 服务发现新鲜度、调用链补充 |
| 怎么保证每次请求都是最新可用的 | 严格不能保证每次请求拿到全局最新且绝对可用实例。Spring Cloud通常让Nacos Client后台维护本地快照,请求到来时Feign或Gateway触发LoadBalancer读取当前快照,按健康、权重、版本、机房和灰度过滤后选址,再由HTTP Client发送。工程上靠Readiness摘流、订阅推送、LB缓存TTL、连接池回收、短超时、有限重试、熔断隔离、幂等号和事实查询保证“当前视角下尽量可用”。 | 请求级可用闭环、服务发现每次请求尽量可用 |
| 如果调到了旧服务怎么办 | 先用Trace确认目标ip、版本和routeId,再查注册中心服务表、调用方本地实例快照、LoadBalancer过滤结果、HTTP连接池是否复用旧连接,以及灰度Header是否丢失。只读请求可按兼容策略容忍短窗口;写请求不能简单重放到新版本,要按幂等号查询事实后补偿。 | 旧实例Runbook、发布策略 |
| Nacos 临时实例和永久实例区别 | 临时实例由客户端主动心跳,心跳超时后会从实例列表删除,适合普通微服务;永久实例更偏固定地址服务,由服务端探测健康状态,异常时通常标记不健康但不会轻易删除。 | 临时实例和永久实例 |
| Nacos 为什么要本地缓存实例列表 | 如果每次调用都实时查询 Nacos,注册中心会成为业务链路瓶颈。本地缓存可以提高调用性能、降低注册中心压力,并在 Nacos 短暂不可用时继续使用已有实例列表。实例变化再通过订阅推送或刷新机制更新缓存。 | 服务发现和订阅推送 |
| Nacos为什么可能返回不健康实例 | 可能触发了保护阈值、空列表保护、本地缓存或连接池窗口。保护阈值是在大面积健康误判时避免所有实例被摘空,空列表保护是在异常推空时保留最后快照。它们保护的是可用性,不保证实例绝对健康,调用方仍要短超时、熔断、慢实例降权、连接池回收和幂等补偿。 | 保护阈值与空列表保护、Nacos面试题 |
| Nacos 服务发现不到怎么排查 | 先看服务名是否一致,再查 Namespace、Group、Cluster 是否一致;然后看 Nacos 控制台是否有健康实例、权重是否为 0、注册 IP 是否可达、调用方本地缓存是否刷新、是否被灰度 metadata 过滤。 | 生产排查:服务发现不到 |
OpenFeign
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| Feign 是什么 | Feign 是声明式 HTTP 客户端,开发者定义接口和注解,Feign 生成代理对象,把接口调用转换成 HTTP 请求。 | Feign完整心智模型 |
| Feign 是本地调用吗 | 不是。Feign 只是写法像本地调用,本质仍然是 HTTP 远程调用,所以必须考虑超时、重试、熔断、日志和序列化。 | 代理到HTTP全过程 |
| Feign 启动时做了什么 | Spring Boot 启动时,OpenFeign 会扫描 @FeignClient 接口,为每个接口创建 FeignClientFactoryBean,解析服务名、路径和配置,组装 Contract、Encoder、Decoder、Client 等组件,最后创建 JDK 动态代理并放入 Spring 容器。业务注入的 Client 不是普通实现类,而是代理对象。 | Registrar与FactoryBean |
| Feign 是怎么把方法调用变成 HTTP 请求的 | Feign 通过动态代理拦截接口方法调用,Contract 解析注解得到 HTTP 方法、路径和参数位置,调用时把 PathVariable、RequestParam、RequestBody 填入 RequestTemplate,再由 Encoder 序列化请求体,RequestInterceptor 添加请求头,最后交给 HTTP Client 发送。 | Contract与RequestTemplate |
| Encoder 和 Decoder 负责什么 | Encoder 把 Java 请求对象序列化成 JSON、表单或文件请求体;Decoder 把 HTTP 响应体反序列化成 Java 返回值。两边协议必须一致,比如下游返回 Result<T>,Feign 方法也应按统一响应包装接收,否则会出现字段为空、反序列化失败或业务语义错乱。 | 请求编码与响应链 |
| Feign 调用要注意什么 | 必须设置连接超时和读取超时;写操作谨慎重试;循环调用下游要改成批量接口;统一处理错误码和 traceId。 | 超时与三层重试 |
| Feign 为什么要关注 HTTP Client 连接池 | Feign 本身不是 TCP 客户端,真正发请求的是 Apache HttpClient、OkHttp 或 JDK Client。连接池太小会导致调用线程排队等连接,读取超时太长会让线程长期阻塞,旧连接还可能在服务下线窗口继续打到旧实例,所以生产要同时关注超时、连接池容量、每路由连接数和连接释放。 | HTTP Client与连接池 |
| Spring里HTTP客户端怎么选 | JDK 8和Boot 2存量系统常见OpenFeign、RestTemplate和WebClient;Java 17 + Boot 3新项目还会遇到HTTP Interface和RestClient。OpenFeign适合微服务声明式调用,RestClient适合同步阻塞HTTP,WebClient适合响应式和流式场景。无论选哪个,都要处理连接池、超时、负载均衡、错误语义、幂等和观测。 | Spring HTTP客户端专题、独立面试题 |
| HTTP Interface和OpenFeign有什么区别 | 二者都能用接口描述HTTP调用并生成代理。OpenFeign属于Spring Cloud OpenFeign生态,服务发现、LoadBalancer、配置和Fallback集成成熟;HTTP Interface是Spring Framework原生声明式HTTP能力,通过RestClient或WebClient执行,更轻量,但生产治理能力要按项目组合清楚。 | HTTP Interface原理、OpenFeign原理 |
| Feign 重试为什么危险 | 重试会放大下游流量。比如入口 1000 QPS,最多重试 2 次,库存服务最大可能承受 3000 QPS。查询接口可以少量重试,创建订单、扣库存、支付扣款等写操作必须有幂等键、状态查询或补偿机制,不能盲目重试。 | 三层重试放大 |
| Feign 的 fallback 和 fallbackFactory 怎么选 | fallback 只能返回固定降级逻辑,通常拿不到原始异常;fallbackFactory 可以拿到失败原因,能区分无实例、超时、下游 500、熔断等情况,更适合线上排查。降级不能把失败伪装成成功,尤其扣库存、支付这类写操作不能默认成功。 | CircuitBreaker与Fallback |
项目话术:
text
我们服务间调用主要用 OpenFeign,比如采集服务调用字典服务或资产服务。Feign 让调用写法像接口方法,但底层仍然是 HTTP,所以会配置超时、日志、错误处理和熔断降级,避免下游慢时拖垮采集线程池。Gateway
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| Gateway 做什么 | Gateway 是微服务统一入口,负责路由转发、鉴权、限流、跨域、日志、灰度和链路追踪等入口治理。 | Gateway |
| Gateway 启动时和请求进入时分别做什么 | 启动时 Gateway 会把 YAML、代码 DSL 或注册中心路由加载成 RouteDefinition,再转换成运行期 Route 放入 RouteLocator。请求进入时,RoutePredicateHandlerMapping 按 Predicate 匹配 Route,FilteringWebHandler 组装过滤器链,前置过滤器处理鉴权、日志、限流等逻辑,最后由路由过滤器转发到下游并写回响应。 | Gateway 启动阶段做了什么、一次请求在 Gateway 内部怎么走 |
| Gateway 的 Route、Predicate、Filter 怎么理解 | Route 决定请求转发到哪里;Predicate 决定什么请求能命中这条 Route,例如 Path、Method、Header;Filter 决定请求转发前后做什么,例如鉴权、限流、路径重写、日志、响应处理。三者组合起来才是一条完整网关规则。 | Route、Predicate、Filter 怎么协作 |
| Gateway Filter 为什么有前置和后置 | Gateway Filter 基于 Reactor 链式调用,请求进入时可以在 chain.filter(exchange) 前做前置逻辑,响应回来后可以通过 then、doFinally 等回调做后置逻辑。多个 Filter 的执行像洋葱模型,顺序不对会导致 traceId 缺失、鉴权误放行、路径重写错乱等问题。 | Filter 链为什么有前置和后置、Filter 顺序为什么重要 |
lb://服务名 在 Gateway 中怎么转发 | Gateway 命中 uri=lb://asset-service 后,会由负载均衡过滤器识别 lb scheme,根据 serviceId 从注册中心和本地缓存拿实例列表,通过 LoadBalancer 选择 ServiceInstance,再把目标地址改成真实 http://IP:Port,最后由 NettyRoutingFilter 发起 HTTP 转发。 | lb:// 转发的完整原理 |
| Gateway动态路由为什么不能每次请求查数据库 | 动态路由是控制面能力,路由中心负责保存、审批、发布、通知和回滚;Gateway数据面应读取本地路由快照快速匹配。每次请求查数据库会让控制面承受业务QPS,增加RT,并在配置中心或数据库抖动时拖垮入口流量。 | 动态路由控制面、Gateway面试题 |
| Gateway灰度为什么推荐稳定Hash | 随机权重会让同一用户多次请求在v1/v2之间跳变,遇到Session、缓存、Feature Flag或响应结构差异时很难排查。稳定Hash基于用户、租户、设备或医院编码固定版本,网关生成可信灰度标签,再由LoadBalancer按metadata选择实例。 | 稳定Hash灰度、Gateway灰度面试 |
| Gateway 404 和 503 怎么排查 | 404 优先查是否命中 Route、Path/Method/Header Predicate 是否满足、StripPrefix 或 RewritePath 是否把路径改错;503 优先查 lb:// 服务名、注册中心实例、namespace/group、实例健康状态、灰度过滤和本地缓存。不要一上来只看下游 Controller。 | Predicate 常见坑、lb:// 转发的完整原理 |
| Gateway 限流 key 怎么设计 | 限流 key 要按业务风险选择,IP 适合防匿名刷接口但可能误伤 NAT 用户,用户 ID 适合登录态接口,租户 ID 适合 SaaS,医疗采集可按医院编码或租户 + 接口组合限流。限流是保护系统,不是权限控制;无权限应返回 401/403,超过频率才返回 429。 | 限流 key 怎么设计 |
| Gateway 鉴权后为什么下游还要校验权限 | 网关适合做统一登录态校验和用户上下文透传,但下游不能无条件信任外部请求头。生产上要禁止绕过网关直接访问服务,网关转发前覆盖用户头,下游对关键资源权限仍做校验,并记录审计日志,防止网关配置错误或请求头伪造导致越权。 | 商业系统鉴权 Demo |
| Gateway怎么做统一认证 | Gateway作为统一入口可以校验Access Token、处理OAuth2登录回调、清洗外部Header、写入Trace和受控用户上下文,并做路由级粗授权。认证失败返回401,权限不足返回403。但Gateway不能替代业务服务授权,下游服务仍要校验Token并做方法权限和数据权限。 | Gateway统一认证与OAuth2 |
| OAuth2/OIDC在微服务里怎么落地 | 认证授权中心负责登录、授权码、Token签发和JWK公钥;Gateway可以作为Resource Server校验Bearer Token,也可以作为OAuth2 Client完成授权码登录并用TokenRelay转发Access Token。业务服务作为Resource Server再次校验Token,接口权限看scope/权限码,数据权限在Service层按租户、医院、科室和资源归属校验。 | OAuth2/OIDC登录流程、业务服务认证授权 |
| 服务间调用怎么授权 | 代表用户的同步调用透传用户Access Token,让下游按用户身份和权限判断;定时任务、MQ消费者、批处理这类系统调用使用client_credentials获取服务账号Token,并按最小权限授权。不要伪造管理员用户,也不要只靠X-User-Id这类可伪造Header。 | 服务间调用授权 |
| JWT验签每次都要请求认证中心吗 | 通常不会。Gateway和资源服务会根据issuer-uri发现jwks_uri,下载JWK公钥集合并本地缓存;每次请求根据JWT Header里的kid找公钥验签。密钥轮换要先发布新公钥,再用新私钥签Token,并保留旧公钥到旧Token过期,否则会出现大面积401。 | JWK缓存和密钥轮换、Gateway面试题 |
| JWT权限变更后为什么旧权限还可能生效 | JWT是自包含Token,旧Token未过期时里面的scope或权限快照仍可能被资源服务接受。生产上要用短Access Token、受控Refresh Token、token_version、黑名单、Opaque Token introspection或关键权限实时查缩短撤销窗口,高风险接口不能只相信长期JWT权限快照。 | Token撤销和权限变更、Gateway面试题 |
| Gateway 和 Nginx 区别 | Nginx 更偏通用反向代理、静态资源和入口负载;Gateway 更贴近微服务生态,能结合注册中心、路由规则、过滤器、鉴权和限流。 | Gateway |
| 什么逻辑不适合放网关 | 复杂业务规则、数据库事务、领域逻辑不适合放网关。网关应该薄,业务逻辑应在下游服务。 | Gateway |
熔断、降级、限流
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 限流、熔断、降级区别 | 限流解决流量太大;熔断解决下游慢或异常时快速失败;降级是在异常或熔断时返回兜底结果,保护核心链路。 | Sentinel |
| Resilience4j有哪些核心模块 | CircuitBreaker按失败率和慢调用率决定是否放行;Retry做有限再次尝试;Bulkhead限制并发或线程资源;RateLimiter按时间发许可;TimeLimiter限制Future等待。它们职责独立,CircuitBreaker不会自动提供超时、线程池和重试。 | 模块职责 · 源码与生产治理 |
| Resilience4j熔断器内部怎样开路 | 调用前向当前State申请许可,执行后按结果分类并写入次数或时间滑动窗口;样本达到minimumNumberOfCalls后,失败率或慢调用率达到阈值,CLOSED通过CAS只转换一次到OPEN;等待后有限进入HALF_OPEN探测。 | 状态机与滑动窗口 |
| Spring Cloud CircuitBreaker调用Resilience4j怎样走 | CircuitBreakerFactory按id和group查配置并取得CircuitBreaker和TimeLimiter;样本默认可把Supplier提交Executor,再组合TimeLimiter、可选Bulkhead和CircuitBreaker,Throwable进入Fallback。Retry和RateLimiter不会仅因依赖存在就自动加入。 | Cloud Factory执行链 |
| TimeLimiter超时后下游一定停止吗 | 不一定。Future取消通常只是线程中断信号,Socket、JDBC、远端事务和异步任务可能继续。写操作超时后应视为UNKNOWN,通过幂等键、状态查询、对账或补偿收敛,不能直接认定失败并盲目重试。 | TimeLimiter取消边界 |
| Resilience4j 1.x和2.x怎样区分 | JDK 8存量线可使用1.7.1,字节码major 52;2.2.0是Java 17字节码major 61。Boot 3项目还要按Cloud BOM选择适配版本,不能把独立最新版强行覆盖到任意Cloud发布列车。 | 版本基线 · 独立面试题 |
| Sentinel 底层原理是什么 | Sentinel 把接口、方法、外部调用抽象成资源,请求进入资源时经过 SlotChain。SlotChain 会建立调用上下文和统计节点,用滑动窗口统计 QPS、RT、异常、线程数,再由 FlowSlot、DegradeSlot、SystemSlot 等根据规则判断是否放行。不通过时抛出 BlockException,由 blockHandler 或统一异常处理返回限流降级结果。 | Sentinel 的核心原理:资源、规则、统计、拦截、SlotChain 每一段到底在干什么 |
| Sentinel 为什么能统计实时 QPS | Sentinel 使用滑动窗口,把一段时间切成多个小窗口,每个窗口统计通过、拒绝、异常和耗时。时间推进时旧窗口淘汰、新窗口加入,所以它能基于最近一段时间平滑计算 QPS、慢调用比例和异常比例,避免整秒清零造成边界抖动。 | 滑动窗口为什么能统计实时 QPS |
| QPS 限流和并发线程数限流怎么选 | 接口很快但流量突增时适合 QPS 限流;接口很慢、占线程、占连接或做导出时更适合并发线程数限流。因为并发数约等于 QPS * 平均耗时秒数,一个每秒 5 次、每次 60 秒的接口会占约 300 个并发位置,只看 QPS 会误判。 | 流控规则讲细:QPS、并发、关联、链路 |
| Sentinel 熔断按什么判断 | 熔断面向不健康依赖,常见依据是慢调用比例、异常比例和异常数。慢调用比例可以在错误率大面积上升前发现下游变慢;异常比例适合持续 500 或业务异常激增;异常数适合低 QPS 但异常明显的接口。规则还要配置最小请求数,避免样本太少导致误熔断。 | 熔断规则讲细:慢调用、异常比例、异常数 |
| 热点参数限流解决什么 | 热点参数限流解决“接口总流量不高,但某个参数值特别热”的问题,例如爆款 skuId、异常重试的 hospitalCode、大租户 tenantId。它可以只限制热点 key,不影响其他正常参数请求。 | 热点参数限流:为什么只保护某个参数 |
| Sentinel系统规则解决什么 | 系统规则保护整台应用实例,会根据CPU、Load、入口QPS、总线程数、平均RT等整体指标拒绝新请求。它适合作为最后兜底,但粒度较粗,不能替代接口级限流、热点参数、线程池隔离和下游熔断,否则低价值导出接口打满CPU时可能误伤核心下单接口。 | 系统规则、Sentinel系统规则面试 |
| Sentinel集群流控解决什么 | 本地流控每个实例各算各的,扩容后总通过量会变大;集群流控通过Token Server按全局配额发令牌,适合第三方总额度、租户合同额度、共享数据库保护。它会引入Token Server故障域,必须设计超时、高可用、Fail-open或Fail-closed策略。 | 集群流控、本地与集群流控 |
| Sentinel 的 blockHandler 和 fallback 区别 | blockHandler 处理 Sentinel 规则拦截,例如限流、热点参数、系统保护,方法参数通常要额外带 BlockException;fallback 处理业务异常或降级兜底。限流是系统主动拒绝,业务异常是方法执行过程中失败,两者语义不同,返回文案和错误码也应区分。 | Spring Cloud 接入示例 |
| Sentinel 规则为什么要持久化 | Dashboard 或内存里的临时规则在应用重启后可能丢失,生产环境应把规则持久化到 Nacos、Apollo、ZooKeeper 或文件,并做到环境隔离、变更记录、可回滚和监控验证。否则服务重启后限流熔断保护可能消失。 | 规则持久化、为什么控制台规则不能只存在内存 |
| Feign 接入 Sentinel 后怎么工作 | 开启 Feign Sentinel 后,Feign 方法或目标服务会作为 Sentinel 资源统计和保护。调用前判断是否限流或熔断,通过后才进入 LoadBalancer 和 HTTP Client;调用失败或慢调用会记录指标。写操作的 fallback 不能返回成功,应该返回失败、待确认或进入补偿。 | OpenFeign 接入 Sentinel 怎么理解 |
| Sentinel 拦截请求怎么排查 | 先看异常类型:FlowException 查 QPS、线程数和热点参数;DegradeException 查慢调用、异常比例和异常数;ParamFlowException 查热点 key;SystemBlockException 查 CPU、Load、入口 QPS;AuthorityException 查来源黑白名单。不要一上来只把阈值调大。 | 生产排查:Sentinel 拦截了请求怎么办 |
| 为什么只重试不够 | 下游慢时不断重试会放大流量,导致下游更慢、调用线程堆积,甚至雪崩。重试必须配合超时、限流、熔断和退避。 | Sentinel |
项目话术:
text
医疗数据采集依赖外部医院接口和内部字典服务,如果下游变慢,不能让采集线程一直阻塞。我们会设置超时,并用 Sentinel 做限流、熔断和降级;失败批次会记录下来后续补偿,而不是无限重试。配置中心
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 配置中心做什么 | 配置中心统一管理多服务、多环境、多实例配置,解决配置分散、环境混乱、修改要重启、缺少审计回滚、敏感信息泄露等问题。它的核心不是“把 yml 放网页上”,而是配置加载、隔离、刷新、权限、审计、灰度、回滚、加密、缓存和排查。 | 配置中心解决什么 |
| 哪些配置适合放配置中心 | 医院接口地址、采集开关、限流阈值、线程池参数、字典版本、灰度开关、批处理大小、第三方接口超时等低频变更且影响程序行为的参数适合放配置中心。订单状态、库存数量、任务进度这类高频业务状态不适合放配置中心,应放数据库、Redis 或专门状态存储。 | 配置中心解决什么 |
| 配置中心加载流程是什么 | 应用启动早期先读取本地最小引导配置,例如应用名、环境、配置中心地址和认证信息;再按 Namespace、Group、DataId 或 application/profile/label 定位远程配置;拉取后作为 PropertySource 合并到 Spring Environment,后续自动配置、@Value、@ConfigurationProperties 和业务 Bean 都从 Environment 读取最终配置。 | 配置加载全过程 |
| 为什么配置中心必须启动早期加载 | 很多 Bean 和自动配置在创建时就要读取配置,例如数据源、Redis、线程池、Feign 超时、Sentinel 规则。如果远程配置加载太晚,这些 Bean 可能已经按本地默认值创建完成,后面再改 Environment 也不一定能安全重建,所以配置中心要尽量进入启动早期的配置准备阶段。 | 配置加载全过程、Spring 中配置为什么能被 Bean 读取 |
| 配置分层怎么设计 | 通常按公共配置、应用配置、环境配置、租户或灰度配置分层。公共配置放日志、监控、通用中间件地址;应用配置放服务自己的参数;环境配置区分 dev/test/prod;灰度配置只影响部分实例或租户。分层要有优先级和命名规范,否则容易出现“看起来改了 A,实际被 B 覆盖”。 | 配置分层模型、配置命名规范 |
| 动态刷新为什么不是万能的 | 动态刷新通常是客户端收到变更事件后重新拉取配置,更新 Environment,再刷新支持动态更新的 Bean。功能开关、限流阈值、灰度比例适合刷新;数据源、MQ 消费组、复杂线程池、证书密钥等涉及连接、线程、事务和状态的配置不适合随意刷新。配置中心支持变更,不代表所有对象都会安全重建。 | 动态刷新原理 |
| 配置改了为什么代码还是旧值 | 要分三层排查:新值是否进入 Environment,Bean 是否重新绑定或重建,业务是否缓存旧引用。@RefreshScope 通常是清理旧目标对象,新访问通过代理创建新目标;已拿到旧引用的异步任务、长任务、静态字段、final 常量和构造器派生对象不会自动变新。 | RefreshScope边界、配置刷新面试 |
| 配置中心不可用怎么办 | 要分启动期和运行期看。启动期如果没有本地快照或必需配置,应用应快速失败,避免带错误配置启动;运行期配置中心短暂不可用时,应用通常继续使用内存里的旧配置或本地快照,但无法获取新配置。生产要做配置中心高可用、本地快照、启动失败策略、监控告警和应急回滚。 | 配置中心不可用会怎样 |
| 配置变更生产流程怎么做 | 生产配置变更不能直接手改上线,应该经过申请、评审、影响面判断、灰度发布、监控观察、全量发布、审计记录和回滚预案。线程池、批量大小、超时、限流阈值这类配置改错会直接引发数据库打满、接口超时、MQ 堆积或雪崩。 | 配置发布流程 |
| 配置不生效怎么排查 | 先确认配置中心地址、权限、Namespace、Group、DataId、profile、文件后缀是否正确;再看远程配置是否成功加入 Environment;然后检查 @ConfigurationProperties 前缀、类型转换、Bean 注册和刷新范围;最后查命令行参数、环境变量、本地配置是否以更高优先级覆盖了远程配置。 | 生产排查:配置不生效 |
| 配置改了但不刷新怎么排查 | 先看客户端是否收到配置变更事件;再看 Environment 是否已经更新;然后确认对应 Bean 是否支持刷新,比如是否使用 @RefreshScope、动态配置对象或框架自身刷新机制;最后检查业务代码是否把配置复制到 final 字段、本地缓存或静态变量里。 | 生产排查:配置改了但不刷新 |
| Nacos 配置中心怎么定位一份配置 | Nacos Config 通常通过 Namespace、Group、DataId 三个字段定位配置。Namespace 常用于环境隔离,Group 用于业务或分组隔离,DataId 是具体配置标识,例如 asset-service-prod.yml。三者任何一个不一致,应用都可能拉不到配置。 | 配置中心定位模型 |
| Nacos 配置启动时怎么加载 | 应用启动早期先读取本地 Nacos 地址、namespace、group、文件后缀等信息,再按 DataId 拉取远程配置,合并到 Spring Environment。后续自动配置和业务 Bean 都从 Environment 读取配置,所以配置中心必须在较早阶段加载。 | 配置启动拉取流程 |
| Nacos 动态刷新是不是所有配置都能刷新 | 不是。功能开关、限流阈值适合动态刷新;数据源、MQ、复杂线程池、消费组这类配置涉及连接、事务、线程和状态,不建议随便动态刷新。即使 Nacos 发现配置变化,也只有支持刷新机制的 Bean 才会真正使用新值。 | 配置动态刷新原理 |
| Nacos 配置不生效怎么排查 | 先核对 DataId、Group、Namespace、profile、文件后缀,再看配置是否在启动早期加载;然后检查 @ConfigurationProperties 的 prefix、类型转换、配置类注册情况,最后确认是否被环境变量、命令行参数或本地配置覆盖。 | 生产排查:配置不生效 |
| Apollo配置中心的核心原理是什么 | Apollo用AppId + Env + Cluster + Namespace定位配置。Portal负责管理和发布,Admin Service写配置和发布记录,客户端通过Meta Server找到Config Service,启动时拉取配置并合并到本地缓存和Spring Environment;运行时通过长轮询感知变化,收到通知后再拉取完整配置事实。业务请求读取本地快照,不每次请求访问Apollo。 | Apollo原理、Apollo面试题 |
| Apollo发布成功是否代表所有实例都生效 | 不代表。发布成功只说明配置中心保存了新Release;客户端通知、重新拉取、本地缓存、Environment更新、Bean刷新和资源切换都有传播窗口。生产要按实例观察releaseKey、checksum、刷新结果、错误率、P99和业务指标,资源型配置失败应继续使用旧资源并告警。 | Apollo灰度和版本收敛、Apollo面试题 |
| 生产配置为什么不能随便改 | 配置中心降低了改配置成本,也放大了误改风险。比如批处理大小、超时、限流阈值改错可能打满数据库、线程池或下游接口。生产配置变更要有权限、审批、审计、灰度、回滚和监控验证。 | 配置发布为什么要有流程 |
可观测性和消息事件
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| 链路追踪解决什么问题 | 链路追踪通过traceId和Span把一次请求经过的多个服务串起来,记录每段耗时、状态和异常。日志中打印traceId只是关联手段,不等于完整Tracing。JDK 8、Boot 2存量项目常见Sleuth;Java 17+、Boot 3现代项目常见Micrometer Observation/Tracing桥接OpenTelemetry或Brave。 | 入门 · Boot 3内部原理 |
| RT、P95、P99分别是什么 | RT是Response Time,表示一次请求从开始到结束的响应耗时,但要说明是在客户端、Gateway、应用、Feign还是数据库层观测。P95/P99是百分位延迟,把一段时间内请求耗时从小到大排序,P95表示95%的请求不超过该耗时,P99表示99%的请求不超过该耗时。它们不是平均值,也不是最大值;平均RT正常但P99高,通常说明存在慢实例、锁等待、GC、连接池等待、热点请求或下游长尾。 | RT、P95和P99 |
| Observation和Span是什么关系 | Observation表达一个被观测操作的完整生命周期,本身不等于Span;Tracing Handler可根据Observation创建Span,Meter Handler可根据同一次Observation生成Metric。因此一个Observation可能同时驱动指标和追踪,也可能被Predicate关闭或没有Tracing Handler而不导出Span。 | Observation生命周期 · 独立面试题 |
| Boot 3怎样把Trace导出到后端 | 框架创建Observation后,Tracing Handler创建Span,Micrometer Bridge进入OpenTelemetry SDK,Sampler决定是否记录,BatchSpanProcessor有界排队,OTLP Exporter发送Collector,Collector再批处理、采样和路由到后端。任一层失败都可能出现业务成功但Trace不可查。 | OTel与OTLP数据链 |
| Sleuth迁移到Boot 3只换依赖可以吗 | 不可以。除了把Sleuth迁移到Micrometer Tracing,还要核对Java 17基线、传播格式B3/W3C、采样、MDC字段、Span命名、自定义Sampler、Exporter、异步上下文和跨版本服务兼容,并通过灰度比较Trace连续性与数据量。 | Sleuth迁移 |
| Spring Cloud Stream 和 Bus 区别 | Stream 是通用业务消息抽象,通过Binding和Binder连接Kafka、RabbitMQ;Bus 是构建在Stream之上的Spring Cloud系统事件总线,常用于配置刷新广播。Stream减少常规收发样板代码,但不会抹平分区、offset、ACK和死信差异;Bus广播也不能替代权威配置中心。 | 标准面试题 · 内部原理 |
| Spring Cloud Stream消费成功和ACK是什么关系 | 不能只看Consumer方法是否执行完。生产上应先让业务数据和消费日志在同一本地事务提交,再由Binder提交Kafka offset或Rabbit ACK;业务成功后ACK失败会重复投递,靠consumer_group + event_id幂等吸收;先ACK再写库会造成消息丢失。 | 标准面试题 · 确认顺序原理 |
服务调用排查
| 面试题 | 标准回答 | 原理知识点 |
|---|---|---|
| Spring Cloud 服务调用失败怎么排查 | 先判断请求是否经过 Gateway,再看状态码和错误类型。Gateway 404 优先查路由匹配,503 查注册中心和可用实例,504 查下游超时;Feign No instances available 查服务名、namespace、group 和本地实例缓存;connect timeout 查网络和端口;read timeout 查下游线程池、慢 SQL、锁、GC 和第三方接口。不要只看调用方日志,要用 traceId 串起调用方和提供方。 | 服务调用故障排查决策树 |
| 注册中心有实例,为什么 Feign 仍然报无实例或调不到 | 注册中心看到实例,只说明服务端注册信息存在,不等于调用方当前可用。常见原因是调用方 namespace/group 不一致、本地缓存未刷新、服务名大小写或配置错误、实例健康状态不满足、灰度/版本/机房规则过滤后为空,或者实例已下线但缓存和连接池还没完全清理。 | 负载均衡选择实例的输入从哪里来 |
| Spring Cloud LoadBalancer 内部怎么选实例 | 先根据服务名通过 ServiceInstanceListSupplier 拿候选实例,候选实例可能来自注册中心、本地缓存和过滤链;再按健康、namespace/group、机房、版本、权重等规则过滤;最后由 ReactorServiceInstanceLoadBalancer 按轮询、随机、权重等算法返回一个 ServiceInstance,HTTP Client 再把服务名替换成真实 IP:Port。 | LoadBalancer运行时主链 |
| Ribbon 和 LoadBalancer 有什么本质区别 | 二者解决的问题相同,都是客户端负载均衡。Ribbon 是 Netflix OSS 老组件,常见扩展点是 IRule、IPing、ServerList;Spring Cloud LoadBalancer 是 Spring Cloud 官方新方案,核心扩展点是 ServiceInstanceListSupplier 和 ReactorServiceInstanceLoadBalancer,更适合当前 Spring Cloud、Gateway、WebClient、OpenFeign 体系。 | Ribbon迁移对比 |
| P2C、EWMA和Outlier解决什么 | P2C随机抽两个候选并选择综合负载更低者;EWMA用新样本权重更高的移动平均表示近期延迟;Outlier根据连续错误、成功率或延迟临时摘除坏实例。它们能降低慢实例影响,但统计多是客户端局部视图,不能替代Readiness、熔断、幂等和真实根因修复。 | P2C与EWMA Demo、Outlier状态机 |
| 负载均衡、超时、重试、熔断分别负责什么 | 负载均衡负责选实例;连接超时负责连不上时快速失败;读取超时负责下游迟迟不返回时释放线程;重试负责偶发失败恢复;熔断负责下游持续异常时快速失败。它们不能互相替代,尤其写操作超时不代表下游失败,必须用幂等键、状态查询或补偿机制,不能盲目重试。 | 超时、重试、熔断与负载均衡的边界 |
| 微服务超时和Deadline怎么设计 | 从入口SLO建立端到端Deadline,再逐层扣减Gateway、服务本地、下游逻辑调用、单次Attempt、连接池等待、数据库查询和响应返回预算。不能每层都重新给完整5秒,否则上游超时后下游仍排队执行。Read Timeout、TimeLimiter或Gateway 504都不证明下游未执行,写操作必须按幂等键查询事实或补偿。 | 分层超时与Deadline、超时与取消边界 |
| 过载时为什么要丢弃过期请求 | 请求在队列里等到Deadline耗尽后,继续执行只会形成幽灵流量,占用线程、连接、数据库锁和下游配额,却无法给用户返回结果。生产上要在入队前、出队执行前和下游调用前检查剩余Deadline,并按接口、租户和优先级做Load Shedding。 | 基于Deadline的丢弃、接纳控制Demo |
| 微服务重试应该放在哪一层 | 必须明确一个主要重试Owner。Gateway、Mesh、Feign、HTTP Client和业务代码都重试会乘法放大请求。查询类请求可在最了解错误语义的一层有限重试;写操作应由业务层结合幂等键、状态查询和补偿控制,所有重试都要受总Deadline、最大Attempt、退避抖动和Retry Budget约束。 | 重试所有权、重试与幂等 |
| 微服务依赖治理怎么做 | 先画接口依赖图,区分强依赖、弱依赖、可选依赖、异步依赖和外部依赖;强依赖失败不能伪装成功,弱依赖要短超时、低并发、快速降级。资源上按故障域拆线程池、信号量、HTTP连接池、数据库连接池和队列,并按依赖维度观测P99、错误率、降级、重试和连接池等待。 | 依赖治理完整原理、依赖治理面试题 |
| 推荐服务慢为什么会拖垮订单接口 | 如果推荐和订单核心链路共享Tomcat线程、Feign线程池、HTTP连接池或下游数据库连接,推荐慢会占住共享资源,让订单主数据、库存等强依赖也拿不到资源。推荐这种弱依赖应独立Bulkhead、短超时、失败返回空列表,不能阻塞核心下单。 | 弱依赖与故障域、降级语义 |
| 微服务错误语义怎么设计 | HTTP状态表达协议大类,业务code表达领域结果,异常类用于服务内部控制流。调用方要区分参数错误、权限拒绝、库存不足、限流、熔断、连接失败、读取超时、下游500和解码失败;写请求超时是UNKNOWN,要用幂等号查询事实,不能直接当失败重试。 | 错误语义完整原理、错误语义面试题 |
| Spring Cloud 服务容量怎么评估 | 先从入口SLO和峰值流量出发,拆Gateway、OpenFeign、LoadBalancer、HTTP连接池、应用线程池、Redis、MySQL、MQ和第三方依赖的容量预算。压测时找P99恶化前的单实例安全吞吐,按实例数、安全系数、N-1冗余和最小下游容量计算生产容量。 | 容量规划完整原理、容量规划面试题 |
| 为什么加服务实例后总容量不线性增加 | Spring Cloud 应用只是链路中的一层。注册发现传播、LoadBalancer分流、HTTP连接池、冷启动、JIT、缓存预热都会影响新实例生效;如果瓶颈在MySQL、Redis热Key、MQ分区或第三方配额,扩应用不会线性提升容量,甚至会加重共享下游压力。 | 扩容不一定有效、HPA扩缩容 |
| Feign的ErrorDecoder能不能处理所有业务错误 | 不能。ErrorDecoder通常处理非2xx HTTP响应;如果系统用HTTP 200承载业务失败码,ErrorDecoder不会自然触发,必须在Decoder或统一响应检查里处理业务code。团队要统一HTTP状态和业务code的映射,不能让调用方猜。 | 错误框架映射、Feign错误解码 |
| 为什么会负载不均 | 负载均衡不是保证每台机器请求数绝对相同,而是按实例列表和算法选择。负载不均可能来自实例规格不同、轮询遇到长耗时请求、灰度元数据偏流、长连接或连接池复用、热租户集中、某台实例自身慢。排查时要看每个实例的 QPS、P95/P99、错误率、CPU、线程池、GC 和下游依赖,而不是只看请求数量。 | 如何验证负载均衡是否按预期工作 |
| 为什么服务下线后还会被调用到 | 服务下线有传播窗口。提供者停止、注册中心剔除、调用方刷新本地实例缓存、HTTP 连接池关闭旧连接不是同一瞬间完成的。生产上要做优雅下线:先摘注册或标记不可读,再等待调用方刷新和存量请求结束,最后关闭进程;Kubernetes 场景还要配置 readinessProbe、preStop 和 terminationGracePeriod。 | 为什么会选到旧实例 |
| 为什么慢实例还会继续收到请求 | 普通轮询和随机只知道实例是否可用,不一定知道实例实时耗时。某台实例 Full GC、线程池满、慢 SQL、跨机房部署或版本 bug 时,注册中心可能仍认为它健康。需要结合慢调用熔断、实例摘流、权重降级、健康检查、链路追踪和实例级指标治理。 | 为什么会选到慢实例 |
| 连接池为什么会影响负载均衡 | LoadBalancer 只负责选实例,真正发请求的是 HTTP Client。即使选中了健康实例,如果 HTTP Client 连接池太小或旧连接没释放,请求也会卡在等连接,看起来像 Feign 慢或负载不均。排查要同时看目标实例、连接池最大连接数、每路由连接数、等连接耗时和下游响应耗时。 | 连接池为什么会影响负载均衡 |
| 重试风暴是什么 | 下游整体变慢时,上游超时后继续重试,会把原始流量放大。例如 1000 QPS 最多重试 2 次,下游可能承受 3000 QPS,导致线程池和连接池更拥塞、更多请求超时。重试必须配合总超时、退避、熔断、限流、幂等和补偿。 | 重试风暴 |
| 灰度和权重路由怎么做 | 通过服务实例 metadata 携带 version、zone、weight 等信息,调用方或网关在负载均衡前过滤候选实例,再按轮询、随机或权重选择。灰度实例为空时要明确是失败、回退稳定版本还是按业务开关决定,并配合监控和回滚。 | 权重、灰度和同机房优先 |
| 优雅下线怎么做 | 推荐先把 Readiness 置为不可用,再从注册中心摘除或标记下线,等待调用方刷新本地缓存和存量请求处理完成,再关闭消费者、定时任务、连接池和进程。K8s 中要配合 readinessProbe、preStop、terminationGracePeriodSeconds 和 Spring Boot graceful shutdown。 | 优雅下线全过程 |
常见追问
| 追问 | 回答方向 | 跳转 |
|---|---|---|
| Spring Cloud 服务调用底层原理是什么 | 本质是接口代理、服务发现、客户端负载均衡、HTTP 调用、响应解码和容错治理组合,不是真正的本地方法调用。 | 服务调用链路 |
| Ribbon 和 LoadBalancer 有什么区别 | Ribbon 是 Netflix 老体系的客户端负载均衡组件;Spring Cloud LoadBalancer 是当前 Spring Cloud 推荐方案。二者核心职责都是从服务实例列表中选一个实例,只是所属生态、扩展方式和维护状态不同。 | 负载均衡 |
| Hystrix、Sentinel、Resilience4j 怎么选 | Hystrix 是老项目常见熔断隔离方案;Sentinel 更偏流量治理,限流、热点参数、系统保护能力强;Resilience4j 更轻量模块化,适合 Spring 官方生态。 | Hystrix与Resilience4j、Sentinel |
| 注册中心挂了为什么短时间还能调 | 客户端通常缓存服务实例列表,但新实例发现和故障感知会受影响。 | Eureka、Nacos |
| Feign 为什么必须设超时 | 远程调用本质是 HTTP,不设超时会长期占用上游线程。 | Feign |
| 网关为什么不能写复杂业务 | 网关是入口横切层,复杂业务会让入口变厚、事务和领域规则混乱。 | Gateway |
| 重试为什么可能造成雪崩 | 下游慢时重试会放大流量,要配合超时、退避、熔断和限流。 | Sentinel |
面试回答模板
text
我们平台按职责拆成采集服务、资产服务、权限服务、字典服务等。请求统一先进 Gateway 做鉴权、日志、限流和路由;服务启动后注册到注册中心;服务间调用用 OpenFeign,Feign 通过服务名获取实例并负载均衡调用;下游慢或异常时通过 Sentinel 做限流、熔断和降级;采集开关、线程池参数和接口地址放在配置中心统一管理。深度验收跳转
如果面试官继续追问“这条链路到底怎么走”,回到 Spring Cloud 从零到精通验收清单 按阶段复盘:
- 注册发现:服务名、实例列表、心跳、健康、元数据、本地缓存。
- Feign:动态代理、注解解析、RequestTemplate、Encoder、Decoder、HTTP Client。
- 负载均衡:Ribbon、Spring Cloud LoadBalancer、实例过滤、权重、灰度、连接池影响。
- Gateway:Route、Predicate、Filter、
lb://、前置后置过滤器。 - 容错治理:超时、重试、熔断、限流、降级、重试风暴。
- 配置中心:启动早期加载、Environment、动态刷新边界、配置不生效排查。
- 可观测性:traceId、span、上下文传播、日志关联。
- 生产排查:无实例、404、503、504、Read timeout、配置不刷新、traceId 丢失。
本章小结
Spring Cloud 面试页只负责“怎么答”。每个组件为什么这样工作、流程图和配置 Demo,应进入对应知识点页学习。
