四、Spring Cloud 微服务组件(S21–S30)
S21 · 知识点:Eureka 与 CAP 理论
【题目】在 CAP 理论中,Eureka(服务注册中心)的设计偏向于以下哪种架构?
A. CP(强一致 + 分区容错) B. 三者都不是 C. CA(一致性 + 可用性) D. AP(可用性 + 分区容错)
答案:D
【考点】CAP 理论(一致性/可用性/分区容错)与 Eureka 的设计取舍。
【结论】选 D。Eureka 采用去中心化对等节点架构,优先保证服务可用性,属于 AP 系统。
【逐项辨析】 A. CP(强一致 + 分区容错):错误。ZooKeeper、Consul、etcd 偏向 CP,但 Eureka 不追求强一致性。 D. AP(可用性 + 分区容错):正确。Eureka 各节点平等、相互注册,采用最终一致性,网络分区时仍对外提供服务。 C. CA(一致性 + 可用性):错误。CAP 理论中 CA 意味着放弃分区容错,而分布式系统必须保证 P,因此 CA 在分布式场景下不现实。 B. 三者都不是:错误。Eureka 明确属于 AP 架构。
【知识点】CAP 理论指出分布式系统无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance),最多只能同时满足两项。由于网络分区不可避免,分布式系统通常必须在 C 和 A 之间做权衡。Eureka 的自我保护机制(Self-Preservation)进一步体现了其“保可用”的设计哲学:当心跳失败比例超过阈值时,Eureka 不会立即剔除实例,而是进入保护模式,避免误判导致服务大面积下线。这种设计使得服务消费者可能短暂拿到过期的服务列表,但保证了注册中心本身的高可用。
【记忆锚点】“Eureka 爱爬坡(AP),ZooKeeper 守城池(CP)”——爱爬坡意味着优先可用,守城池意味着优先保数据一致。
【易混对比】
| 维度 | Eureka | ZooKeeper / Consul / etcd |
|---|---|---|
| CAP 偏向 | AP | CP |
| 一致性模型 | 最终一致 | 强一致(基于 Raft/Paxos) |
| 默认端口 | 8761 | 2181(ZK)/ 8300(Consul)/ 2379(etcd) |
| 适用场景 | 服务注册发现,追求高可用 | 配置管理、分布式协调,追求数据准确 |
换问法:若题目改为“ZooKeeper 在 CAP 中偏向哪种架构?”,答案应选 A(CP)。
【自测】某微服务系统在发生网络分区后,注册中心仍然能够正常响应客户端的查询请求,但可能返回稍旧的实例列表。这体现了哪种 CAP 取舍?
答:体现了 AP 取舍,即牺牲强一致性来保证分区容错性和可用性。与第 S22 题连考。
【知识关联】
- 同库关联:与 S22/S23;Eureka AP 倾向。
- 实现层:客户端缓存注册表;最终一致;心跳。
- 面试追问:① Eureka 是 AP 还是 CP?② 与 ZooKeeper 区别?
【拓展延伸】
- 变式问法:分区时是否可用。
- 版本差异:Eureka 1.x 进入维护;生态向 Nacos 等演进。
- 工程注意点:注册中心选型看一致性需求与生态。
S22 · 知识点:Eureka 默认端口
【题目】Eureka Server 默认的服务端口是?
A. 8080 B. 8848 C. 9092 D. 8761
答案:D
【考点】微服务核心组件默认端口记忆。
【结论】选 D。Eureka Server 的默认服务端口是 8761。
【逐项辨析】 A. 8080:错误。8080 是 Spring Cloud Gateway 的默认端口,也是 Tomcat 的默认 HTTP 端口。 D. 8761:正确。Eureka Server 官方默认端口为 8761,是微服务面试和笔试中的经典记忆点。 C. 9092:错误。9092 是 Kafka Broker 的默认监听端口。 B. 8848:错误。8848 是 Nacos 的默认控制台端口。
【知识点】微服务组件的默认端口属于“基础设施常识”,在国企笔试和互联网校招中反复出现。除了 Eureka(8761),还需牢记:Nacos(8848)、Spring Cloud Config Server(8888)、Spring Cloud Gateway(8080,但若独立启动常与 Tomcat 共享)、Zipkin(9411)、Redis(6379)、MySQL(3306)等。记住这些端口不仅有助于答题,还能在排查服务连接问题时快速定位故障。
【记忆锚点】“EU 去如意”——Eureka 的 EU 谐音“意”,8761 谐音“去如意”,记成“Eureka 去如意,端口 8761”。
【易混对比】
| 组件 | 默认端口 | 记忆口诀 |
|---|---|---|
| Eureka Server | 8761 | EU-reka → 8761 |
| Nacos | 8848 | 两个 8 夹 48 |
| Spring Cloud Gateway | 8080 | 标准 Web 端口 |
| Spring Cloud Config | 8888 | 四个 8,配置发发发 |
| Kafka | 9092 | 消息就领 92 |
| Zipkin | 9411 | 链路就试一试 |
换问法:若题目改为“Nacos 默认端口是多少?”且沿用本题的四个选项(A. 8080|B. 8848|C. 9092|D. 8761),答案应选 B(8848)——本题里 8848 是 B 项,8761(D 项)才是 Eureka;换问法时不要沿用原答案的字母。
【自测】在 application.yml 中未显式指定 server.port 时,新创建的 Eureka Server 项目启动后会监听哪个端口?
答:会监听 8761 端口。若该端口被占用,启动将失败并报 BindException。与第 S23 题连考。
【知识关联】
- 同库关联:与 S21;默认 8761。
- 实现层:独立 Server 或互相注册。
- 面试追问:① 高可用怎么做?② 客户端配置?
【拓展延伸】
- 变式问法:eureka.client.serviceUrl.defaultZone。
- 版本差异:默认端口稳定。
- 工程注意点:生产多实例;监控注册表;保护模式理解。
S23 · 知识点:Nacos 与 Eureka 区别
【题目】以下哪个组件同时具备服务注册与发现和分布式配置管理两大能力?
A. Eureka B. Nacos C. Ribbon D. Zuul
答案:B
【考点】Nacos 的定位与 Spring Cloud Netflix 组件职能区分。
【结论】选 B。Nacos 同时具备服务注册与发现和分布式配置管理两大核心能力。
【逐项辨析】 A. Eureka:错误。Eureka 仅提供服务注册与发现功能,不具备配置管理能力。 B. Nacos:正确。Nacos 是 Spring Cloud Alibaba 生态的核心组件,集注册中心与配置中心于一体。 C. Ribbon:错误。Ribbon 是客户端负载均衡组件,负责从注册中心获取实例列表后按策略分发请求。 D. Zuul:错误。Zuul 是 API 网关组件,负责路由转发、过滤和安全控制,与注册发现和配置管理无关。
【知识点】在 Spring Cloud Netflix 时代,服务注册(Eureka)、配置管理(Config)、负载均衡(Ribbon)、网关(Zuul)各司其职,需要引入多个组件。而 Spring Cloud Alibaba 推出的 Nacos 实现了“注册 + 配置”一体化,降低了运维复杂度。Nacos 还支持命名空间(Namespace)、分组(Group)、Data ID 三元组模型,以及配置监听和长轮询(Long Polling)机制,能够实现毫秒级动态配置推送。此外,Nacos 提供可视化管理控制台,支持权重路由、服务分组、集群管理等功能,已成为国内微服务架构的主流选择。
【记忆锚点】“Nacos 两手抓,注册配置都拿下”——一只手续注册,一只手管配置。
【易混对比】
| 组件 | 注册发现 | 配置管理 | 负载均衡 | 网关路由 |
|---|---|---|---|---|
| Eureka | ✓ | ✗ | ✗ | ✗ |
| Nacos | ✓ | ✓ | ✗ | ✗ |
| Ribbon | ✗ | ✗ | ✓ | ✗ |
| Zuul | ✗ | ✗ | ✗ | ✓ |
| Consul | ✓ | ✓(KV 存储) | ✗ | ✗ |
换问法:若题目改为“以下哪个组件仅做客户端负载均衡?”,答案应选 C(Ribbon)。
【自测】某团队希望用一个组件同时替代 Eureka 和 Spring Cloud Config,减少中间件数量,应该选择哪个方案?
答:应选择 Nacos。Nacos 的 naming 模块替代 Eureka 做服务注册发现,config 模块替代 Config Server 做配置管理,两者共用同一集群,降低运维成本。与第 S24 题连考。
【知识关联】
- 同库关联:与 S21/S29;Nacos 注册+配置一体。
- 实现层:Nacos 支持 CP/AP 切换(临时/持久实例);配置推送。
- 面试追问:① Nacos 与 Eureka 差异?② 配置中心能力?
【拓展延伸】
- 变式问法:为什么很多团队迁 Nacos。
- 版本差异:Nacos 2.x 长连接性能。
- 工程注意点:版本兼容与鉴权;生产部署集群。
S24 · 知识点:Ribbon 负载均衡策略
【题目】Ribbon 负载均衡器默认使用的负载均衡策略是?
A. RandomRule(随机) B. RoundRobinRule(轮询) C. WeightedResponseTimeRule(加权响应时间) D. BestAvailableRule(最闲优先)
答案:B
【考点】负载均衡策略及其默认值。
【结论】选 B。就 Ribbon 自身(BaseLoadBalancer 的默认 IRule)而言是 RoundRobinRule(轮询)。(语境口径:① 接进 spring-cloud-netflix 后,其自动配置提供的默认 IRule 是 ZoneAvoidanceRule(区域感知 + 轮询),选项里没有它,所以本题按「Ribbon 内核默认」取 B;② 用 Spring Cloud LoadBalancer 替换 Ribbon 时,默认是 RoundRobinLoadBalancer,仍是轮询。面试被追问时要主动把这三层说清。)
【逐项辨析】 A. RandomRule(随机):错误。RandomRule 是 Ribbon 的内置策略之一,但并非默认策略。 B. RoundRobinRule(轮询):正确。Ribbon 的 BaseLoadBalancer 默认 IRule 为 RoundRobinRule,按顺序循环选择服务实例。 C. WeightedResponseTimeRule(加权响应时间):错误。该策略根据实例的平均响应时间动态计算权重,响应越慢权重越低,适合需要动态调优的场景。 D. BestAvailableRule(最闲优先):错误。该策略选择并发连接数最小的实例,适合实例性能差异较大的场景。
【知识点】需要特别注意的是,Spring Cloud Netflix 的 RibbonClientConfiguration 在实际环境中会将默认策略设为 ZoneAvoidanceRule(区域回避 + 轮询的组合),它会优先选择同可用区内的实例。但在笔试和面试的常规考点中,“Ribbon 默认轮询”是标准答案。Ribbon 的其他内置策略还包括:RetryRule(带重试的轮询)、AvailabilityFilteringRule(过滤掉故障实例的轮询)等。新版 Spring Cloud 已使用 Spring Cloud LoadBalancer 替代 Ribbon,其默认算法同样是轮询(RoundRobin),但实现基于 Reactive 编程模型。
【记忆锚点】“Ribbon 轮流转,默认轮询记心间”——Ribbon 像彩带一样循环轮转。
【易混对比】
| 策略名称 | 机制 | 适用场景 |
|---|---|---|
| RoundRobinRule | 顺序轮询 | 实例性能相近的均衡场景 |
| RandomRule | 随机选择 | 简单负载分散 |
| WeightedResponseTimeRule | 按响应时间加权 | 实例性能差异大,需动态调整 |
| BestAvailableRule | 选择并发最小的实例 | 部分实例性能更优 |
| ZoneAvoidanceRule | 同区域优先 + 轮询 | 多可用区部署 |
换问法:若题目改为“Spring Cloud LoadBalancer 的默认策略是什么?”,答案仍是轮询(RoundRobin)。
【自测】某系统有 3 个服务实例 A、B、C,使用 Ribbon 默认策略时,第 1、2、3、4 次请求分别会落到哪个实例?
答:第 1 次 A,第 2 次 B,第 3 次 C,第 4 次又回到 A,依次循环。与第 S25 题连考。
【知识关联】
- 同库关联:与 S25;负载均衡策略。
- 实现层:Ribbon 已进入维护,LoadBalancer 替代。
- 面试追问:① 常见策略?② 与网关 LB 关系?
【拓展延伸】
- 变式问法:轮询/随机/权重。
- 版本差异:Spring Cloud 推荐 spring-cloud-starter-loadbalance。
- 工程注意点:新项目不要用已停更组件;自定义负载策略注意元数据。
S25 · 知识点:OpenFeign
【题目】关于 OpenFeign 的声明式 HTTP 客户端,下列说法错误的是?
A. 基于动态代理自动生成调用实现 B. 集成负载均衡能力,可配合注册中心使用 C. 必须手动编写 HTTP 调用代码 D. 通过 @FeignClient 声明接口即可远程调用
答案:C
【考点】OpenFeign 的原理与使用方式。
【结论】选 C。OpenFeign 通过声明式接口和动态代理自动生成 HTTP 调用实现,无需手动编写 HTTP 请求代码。
【逐项辨析】 A. 基于动态代理自动生成调用实现:正确。OpenFeign 在运行时为 @FeignClient 标注的接口生成 JDK 动态代理,将方法调用转换为 HTTP 请求。 B. 集成负载均衡能力,可配合注册中心使用:正确。Feign 与 Spring Cloud LoadBalancer(或 Ribbon)集成,可通过服务名自动解析实例并完成负载均衡。 C. 必须手动编写 HTTP 调用代码:错误。这是 OpenFeign 要解决的核心痛点,开发者只需声明接口,无需手写 RestTemplate 或 HttpClient 代码。 D. 通过 @FeignClient 声明接口即可远程调用:正确。@FeignClient(name = “服务名”) 是 OpenFeign 的标准使用方式。
【知识点】OpenFeign 最初是 Netflix 开源的声明式 HTTP 客户端,后被 Spring Cloud 整合为 Spring Cloud OpenFeign。其核心原理是:Spring 在容器启动时扫描 @FeignClient 注解,通过 FeignClientFactoryBean 创建代理对象;方法调用时,根据接口注解(如 @GetMapping、@PostMapping)构建 RequestTemplate,经编码器(Encoder)序列化请求体,再通过客户端(如 OkHttpClient、HttpURLConnection)发送请求,最后经解码器(Decoder)反序列化响应。Feign 还支持请求/响应压缩、日志级别配置、熔断降级(fallback/fallbackFactory)等高级功能。
【记忆锚点】“Feign 飞鸽传书,接口一写就出发”——像飞鸽一样,写好接口声明,信件(请求)自动送达。
【易混对比】
| 维度 | OpenFeign | RestTemplate | WebClient |
|---|---|---|---|
| 编程模型 | 声明式(接口 + 注解) | 命令式(模板方法) | 响应式(Reactive) |
| 负载均衡 | 原生集成 | 需手动配合 @LoadBalanced | 需配合 Reactor LoadBalancer |
| 代码量 | 极少 | 较多 | 中等 |
| 阻塞/非阻塞 | 阻塞(默认) | 阻塞 | 非阻塞 |
换问法:若题目改为“OpenFeign 的核心注解是什么?”,答案应为 @FeignClient。
【自测】请写出一段 OpenFeign 客户端接口代码,声明对名为 "order-service" 的服务的 GET 请求,路径为 /orders/{id},并指定降级类 OrderFallback.class。
答:
@FeignClient(name = "order-service", fallback = OrderFallback.class)
public interface OrderClient {
@GetMapping("/orders/{id}")
Order getOrder(@PathVariable("id") Long id);
}与第 S26 题连考。
【知识关联】
- 同库关联:与 S24/S26;声明式 HTTP 客户端。
- 实现层:接口+注解生成代理;默认集成负载均衡。
- 面试追问:① 超时与重试如何配?② 与 RestTemplate?
【拓展延伸】
- 变式问法:fallback;请求拦截器加 header。
- 版本差异:OpenFeign 维护状态与替代方案关注社区公告。
- 工程注意点:统一超时;避免重试放大故障;链路追踪头透传(S30)。
S26 · 知识点:Hystrix 隔离策略
【题目】Hystrix 默认采用的资源隔离策略是?
A. 信号量隔离(SEMAPHORE) B. 线程池隔离(THREAD) C. 进程隔离 D. 无隔离
答案:B
【考点】服务容错中的舱壁隔离模式(线程池隔离 vs 信号量隔离)。
【结论】选 B。Hystrix 默认采用线程池隔离(THREAD)作为资源隔离策略。
【逐项辨析】 A. 信号量隔离(SEMAPHORE):错误。信号量隔离是 Hystrix 的可选策略,需通过 execution.isolation.strategy 显式配置,并非默认。 B. 线程池隔离(THREAD):正确。Hystrix 为每个依赖服务创建独立的线程池,故障局限在池内,不会拖垮调用方主线程。 C. 进程隔离:错误。Hystrix 不提供进程隔离机制,进程隔离通常由容器(如 Docker)实现。 D. 无隔离:错误。Hystrix 的核心设计目标就是通过隔离防止雪崩,不可能默认无隔离。
【知识点】线程池隔离与信号量隔离的深层差异:线程池隔离为每个依赖分配独立线程池,支持超时控制、异步执行和排队,但线程切换带来一定开销;信号量隔离则在调用线程上执行,通过信号量限制并发数,开销极小,但不支持超时和异步。Hystrix 官方建议:对外部服务调用(如 HTTP、RPC)默认使用线程池隔离;对内部本地调用或并发极高、耗时极短的场景,可考虑信号量隔离。Hystrix 已进入维护模式,Sentinel 和 Resilience4j 是其主流替代方案。
【记忆锚点】“Hystrix 线程隔,默认 THREAD 要记牢;信号量像红绿灯,需要手动才生效”——线程池像独立房间,信号量像路口红绿灯。
【易混对比】
| 对比维度 | 线程池隔离(THREAD) | 信号量隔离(SEMAPHORE) |
|---|---|---|
| 实现方式 | 独立线程池 | 计数信号量 |
| 超时支持 | 支持 | 不支持 |
| 异步执行 | 支持 | 不支持 |
| 系统开销 | 较高(线程切换) | 较低(无线程切换) |
| 适用场景 | 外部依赖调用 | 本地高频短调用 |
| 默认值 | 是 | 否 |
换问法:若题目改为“信号量隔离相比线程池隔离的主要优势是什么?”,答案应为“开销更低”。
【自测】某电商系统在 Hystrix 默认配置下,商品服务调用库存服务时出现大量超时,为什么不会导致商品服务自身的线程全部耗尽?
答:因为 Hystrix 默认使用线程池隔离,库存服务有独立的线程池,超时只会耗尽库存线程池,商品服务的主线程不受影响,从而防止了服务雪崩。与第 S27 题连考。
【知识关联】
- 同库关联:与 S27;Hystrix 已停更,Sentinel/Resilience4j 常见。
- 实现层:线程池隔离 vs 信号量隔离。
- 面试追问:① 两种隔离差异?② 熔断状态?
【拓展延伸】
- 变式问法:资源隔离如何防雪崩。
- 版本差异:Hystrix 维护模式;新项目用 Sentinel/Resilience4j。
- 工程注意点:限流熔断超时组合;监控指标。
S27 · 知识点:Sentinel 熔断限流
【题目】Spring Cloud Alibaba 中,用于流量控制(限流)、熔断降级与系统保护的组件是?
A. Hystrix B. Sentinel C. Seata D. Nacos
答案:B
【考点】Sentinel 的定位及与 Hystrix 的迭代关系。
【结论】选 B。Sentinel 是 Spring Cloud Alibaba 生态中负责流量控制、熔断降级与系统保护的流量防卫组件。
【逐项辨析】 A. Hystrix:错误。Hystrix 是 Netflix 的熔断降级组件,但官方已停止更新,进入维护模式。 B. Sentinel:正确。Sentinel 提供 QPS/并发线程数限流、熔断降级、系统自适应保护、热点参数限流等全方位流量控制能力。 C. Seata:错误。Seata 是分布式事务解决方案(AT、TCC、Saga、XA 模式),与流量控制无关。 D. Nacos:错误。Nacos 是注册中心和配置中心,不负责熔断限流。
【知识点】Sentinel 的设计围绕“流量”展开,核心概念包括:资源(Resource,可以是方法、接口或代码块)、规则(Rule,包括流量控制规则、熔断降级规则、系统保护规则、热点规则、授权规则)。流控规则 FlowRule 的字段(下面【自测】要用):resource 资源名、count 阈值、grade 限流模式(0=线程数、1=QPS)、limitApp 调用来源、strategy 流控策略(直接/关联/链路)、controlBehavior 控制效果(直接拒绝/Warm Up/匀速排队)、Slot 责任链(ProcessorSlotChain,包括 NodeSelectorSlot、ClusterBuilderSlot、StatisticSlot、FlowSlot、DegradeSlot、SystemSlot 等)。Sentinel 控制台提供实时监控、规则配置和推送能力,支持通过 Nacos、ZooKeeper、Apollo 等实现规则持久化。与 Hystrix 相比,Sentinel 的限流维度更丰富(支持 QPS、线程数、热点参数、系统负载),且控制台功能更强大。
【记忆锚点】“Sentinel 哨兵站岗,限流熔断我全挡”——Sentinel 是哨兵,站在门口控制人流(限流),发现危险就关门(熔断)。
【易混对比】
| 维度 | Sentinel | Hystrix | Seata |
|---|---|---|---|
| 核心功能 | 限流、熔断、系统保护 | 熔断降级、线程隔离 | 分布式事务 |
| 限流能力 | 丰富(QPS/线程/热点/系统) | 有限(依赖线程池/信号量) | 无 |
| 控制台 | 功能强大,支持实时监控 | Dashboard 功能较简单 | 有 TC 控制台 |
| 维护状态 | 活跃更新 | 停止更新(维护模式) | 活跃更新 |
| 所属生态 | Spring Cloud Alibaba | Spring Cloud Netflix | Spring Cloud Alibaba |
换问法:若题目改为“分布式事务场景应该选用哪个组件?”,答案应选 C(Seata)。
【自测】请写出 Sentinel 流量控制规则的三个核心参数(如资源名、限流阈值等)。
答:核心参数包括:resource(资源名)、count(限流阈值,如 QPS 上限)、grade(限流模式,0 表示线程数,1 表示 QPS)。此外还包括 limitApp(限流针对的调用来源)、strategy(流控策略,直接/关联/链路)和 controlBehavior(控制效果,直接拒绝/Warm Up/匀速排队)。与第 S28 题连考。
【知识关联】
- 同库关联:与 S26/S28;流控、熔断、热点、系统保护。
- 实现层:滑动窗口统计;规则可动态推送(结合 S29)。
- 面试追问:① 限流算法?② 熔断恢复?
【拓展延伸】
- 变式问法:QPS 限流 vs 并发线程数。
- 版本差异:Sentinel 持续演进;与网关/Feign 集成。
- 工程注意点:规则配置中心化;压测确定阈值;dashboard 权限。
S28 · 知识点:Spring Cloud Gateway
【题目】Spring Cloud Gateway 的底层实现是基于以下哪种技术栈?
A. Servlet + 阻塞式 IO B. Spring WebFlux + Reactor Netty(响应式非阻塞) C. RMI + 序列化 D. WebSocket + 消息队列
答案:B
【考点】Spring Cloud Gateway 与 Zuul 1.x 的技术选型差异。
【结论】选 B。Spring Cloud Gateway 基于 Spring WebFlux + Reactor Netty 构建,采用响应式非阻塞 IO 模型。
【逐项辨析】 A. Servlet + 阻塞式 IO:错误。这是传统 Spring MVC 和 Zuul 1.x 的技术栈,Gateway 明确不基于 Servlet。 B. Spring WebFlux + Reactor Netty(响应式非阻塞):正确。Gateway 利用 Project Reactor 的 Mono/Flux 和 Netty 的事件循环实现高并发非阻塞处理。 C. RMI + 序列化:错误。RMI 是 Java 远程方法调用技术,与网关实现无关。 D. WebSocket + 消息队列:错误。WebSocket 是 Gateway 支持的一种协议转发能力,但不是其底层实现技术栈。
【知识点】Spring Cloud Gateway 的核心组件包括:Route(路由,由 ID、目标 URI、Predicate 集合和 Filter 集合组成)、Predicate(断言,匹配请求条件,如 Path、Method、Header、Query 等)、Filter(过滤器,修改请求或响应,如 StripPrefix、AddRequestHeader、RateLimiter 等)。由于基于 WebFlux,Gateway 不能与传统的 Servlet Filter、Spring MVC 的 @Controller 阻塞式处理混用(同一应用中需选择 WebMvc 或 WebFlux 之一)。Gateway 的性能显著优于 Zuul 1.x,且天然支持长连接、WebSocket 和响应式编程范式。
【记忆锚点】“Gateway 走 Flux,响应式非阻塞”——Flux 像流水一样源源不断,不会阻塞。
【易混对比】
| 维度 | Spring Cloud Gateway | Zuul 1.x | Zuul 2.x |
|---|---|---|---|
| 底层框架 | Spring WebFlux + Netty | Servlet + 阻塞 IO | Netty + 异步 IO |
| 性能 | 高(非阻塞) | 中(阻塞) | 高(非阻塞) |
| 编程模型 | 响应式(Mono/Flux) | 命令式 | 异步 |
| 与 Spring Cloud 兼容性 | 官方推荐 | 已停止维护 | Netflix 内部使用 |
| 过滤器类型 | GatewayFilter / GlobalFilter | ZuulFilter | ZuulFilter |
换问法:若题目改为“Zuul 1.x 基于什么技术栈?”,答案应选 A(Servlet + 阻塞式 IO)。
【自测】在 Spring Cloud Gateway 中,配置一条路由,要求将路径 /api/user/** 转发到 lb://user-service,并去掉前缀 /api,请写出 YAML 配置片段。
答:
spring:
cloud:
gateway:
routes:
- id: user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1与第 S29 题连考。
【知识关联】
- 同库关联:与 S09/S25;WebFlux 网关。
- 实现层:Filter 链;路由谓词;与 Eureka/Nacos 集成。
- 面试追问:① 与 Zuul 区别?② 全局限流如何做?
【拓展延伸】
- 变式问法:自定义 GlobalFilter;灰度路由。
- 版本差异:Boot3 需 WebFlux 网关版本匹配。
- 工程注意点:网关无状态扩容;超时与重试策略;安全过滤。
S29 · 知识点:配置中心动态刷新
【题目】使用 Nacos Config(或 Spring Cloud Config)配置中心时,以下哪个注解可以让 Bean 在配置变更后自动刷新,而无需重启服务?
A. @RefreshScope B. @Scope("prototype") C. @EnableAutoConfiguration D. @Lazy
答案:A
【考点】配置中心动态刷新的实现注解。
【结论】选 A。@RefreshScope 注解可以使 Bean 在配置变更后自动刷新,无需重启服务。
【逐项辨析】 A. @RefreshScope:正确。该注解标注的 Bean 会在配置刷新事件触发后被销毁并重建,重新绑定最新配置值。 B. @Scope("prototype"):错误。这是 Spring 的作用域注解,表示每次注入都创建新实例,与配置热更新无关。 C. @EnableAutoConfiguration:错误。这是 Spring Boot 的自动配置注解,用于启用 starters 的自动配置,不处理配置刷新。 D. @Lazy:错误。这是懒加载注解,延迟 Bean 的初始化时机,与配置动态刷新无关。
【知识点】@RefreshScope 的实现原理:Spring Cloud 通过 ContextRefresher 监听配置变更事件(如 Nacos 配置推送、/actuator/refresh 端点手动触发),当事件发生时,会清空 RefreshScope 缓存(本质是 GenericScope),导致下一次访问该 Bean 时重新创建实例并重新绑定 @ConfigurationProperties 或 @Value 注入的配置值。实际使用中,通常将 @RefreshScope 与 @ConfigurationProperties 搭配使用:配置类加 @RefreshScope,属性类加 @ConfigurationProperties,实现“配置一改,全局生效”。注意:静态变量、@PostConstruct 中的初始化逻辑不会自动重新执行,需额外处理。
【记忆锚点】“RefreshScope 刷新域,配置一变就重建”——Refresh 就是刷新,Scope 就是作用域,配置变了整个域重新来。
【易混对比】
| 注解 | 作用 | 与配置刷新关系 |
|---|---|---|
| @RefreshScope | 创建可刷新的代理 Bean | 直接相关,核心注解 |
| @ConfigurationProperties | 批量绑定外部配置到 POJO | 配合 @RefreshScope 实现热更新 |
| @Value | 单属性注入 | 在 @RefreshScope Bean 内可随刷新更新 |
| @Scope("prototype") | 每次获取新实例 | 无关 |
| @Lazy | 延迟初始化 | 无关 |
换问法:若题目改为“通过哪个端点可以手动触发配置刷新?”,答案应为 /actuator/refresh(需引入 spring-boot-starter-actuator)。
【自测】某服务使用 Nacos Config 管理数据库连接串,修改 Nacos 中的配置后,以下哪种方式可以让应用在不重启的情况下加载新配置?
答:在需要热更新的 Bean 上添加 @RefreshScope 注解,并确保 Nacos 配置文件的 dataId、group 与应用匹配。修改 Nacos 配置后,Nacos 客户端会收到推送事件,触发 Spring Cloud 的 Environment 刷新,@RefreshScope Bean 会被重建并重新注入新配置值。与第 S30 题连考。
【知识关联】
- 同库关联:与 S04/S23;@RefreshScope。
- 实现层:配置变更事件 → 清空 RefreshScope 缓存 → 下次访问重建。
- 面试追问:① 为何有的 Bean 不刷新?② 端点触发?
【拓展延伸】
- 变式问法:Nacos 推送与 /actuator/refresh。
- 版本差异:与配置中心版本联动。
- 工程注意点:静态字段与 @PostConstruct 不会自动重做;关键路径做开关。
S30 · 知识点:服务链路追踪
【题目】Spring Cloud Sleuth 生成的链路信息(traceId、spanId),通常配合以下哪个组件完成链路数据的收集与可视化展示?
A. Zipkin B. Eureka C. Sentinel D. Gateway
答案:A
【考点】微服务链路追踪体系(Sleuth + Zipkin)的职责划分。
【结论】选 A。Spring Cloud Sleuth 生成的链路信息通常配合 Zipkin 完成数据的收集与可视化展示。
【逐项辨析】 A. Zipkin:正确。Zipkin 是分布式链路追踪系统,负责接收、存储和展示 trace 数据,提供调用拓扑和耗时分析。 B. Eureka:错误。Eureka 是服务注册中心,与链路追踪无关。 C. Sentinel:错误。Sentinel 是流量控制组件,负责熔断限流,不处理链路数据。 D. Gateway:错误。Gateway 是 API 网关,负责路由和过滤,虽然会在请求头中传递 traceId,但不负责收集和展示链路数据。
【知识点】分布式链路追踪的核心概念:Trace(一次完整请求的调用链,由全局唯一的 traceId 标识)、Span(调用链中的单个工作单元,由 spanId 标识,包含父 spanId 形成树状结构)、Annotation(事件标注,如 cs 客户端发送、sr 服务端接收、ss 服务端发送、cr 客户端接收)。Spring Cloud Sleuth 通过 Brave 库自动为 HTTP、MQ、Feign 等调用注入 traceId/spanId,并输出到 MDC(Mapped Diagnostic Context)供日志系统收集。Zipkin 通过 Collector 接收数据,存储在内存、MySQL、Elasticsearch 或 Cassandra 中,并通过 Web UI 展示依赖拓扑和耗时瀑布图。注意:Spring Cloud Sleuth 自 2022.0 起停止维护,官方推荐迁移到 Micrometer Tracing + Brave/OpenTelemetry。
【记忆锚点】“Sleuth 侦探找线索,Zipkin 画地图”——Sleuth 是侦探收集线索(traceId),Zipkin 是地图师把线索画成地图(调用拓扑)。
【易混对比】
| 组件 | 职责 | 数据内容 |
|---|---|---|
| Sleuth / Micrometer Tracing | 生成并传播链路标识 | traceId、spanId、parentId、baggage |
| Zipkin | 收集、存储、可视化 | Span 数据、依赖拓扑、耗时分布 |
| SkyWalking | APM + 链路追踪 + 监控 | 更全面的性能指标和告警 |
| Prometheus + Grafana | 指标采集与展示 | 度量指标,非链路数据 |
换问法:若题目改为“链路追踪中的 traceId 作用是什么?”,答案应为“标识一次完整请求的全局唯一 ID,贯穿所有调用节点”。
【自测】在一次微服务调用中,服务 A 通过 Feign 调用服务 B,服务 B 通过 RestTemplate 调用服务 C。Sleuth 如何保证三个服务的日志中能够关联到同一次请求?
答:Sleuth 为这次请求生成全局唯一的 traceId,并在 A→B 的 Feign 请求头和 B→C 的 RestTemplate 请求头中自动注入 traceId 和 spanId。三个服务的日志通过 MDC 输出相同的 traceId,日志收集系统(如 ELK)即可按 traceId 检索出完整调用链。与第 S21 题连考。
【知识关联】
- 同库关联:与 S25;链路追踪 Sleuth/Zipkin 与 Micrometer Tracing。
- 实现层:traceId/spanId 注入头与 MDC。
- 面试追问:① 如何跨线程池传播?② 与日志如何关联?
【拓展延伸】
- 变式问法:按 traceId 检索日志;采样率。
- 版本差异:Sleuth 停维,迁 Micrometer Tracing / OpenTelemetry。
- 工程注意点:统一日志格式带 traceId;注意异步边界丢失上下文。