Spring Cloud 高频面试题
一、组件基础类
Q1:Spring Cloud 有哪些核心组件?各自作用是什么?
| 组件 | 作用 | 一句话 |
|---|---|---|
| Nacos | 注册中心 + 配置中心 | 服务在哪里?配置在哪里? |
| Gateway | API 网关 | 统一入口,路由转发 |
| OpenFeign | 声明式服务调用 | 远程调用像本地方法,内置负载均衡 |
| LoadBalancer | 负载均衡 | 选哪个实例调用(Ribbon → LoadBalancer) |
| Sentinel | 流量治理 | 熔断、降级、限流 |
| Sleuth | 链路追踪 | 请求经过了哪些服务 |
| Stream | 消息驱动 | 统一消息编程模型 |
面试回答思路: 不要像背八股一样罗列名称,而是按"一个请求从进入系统到返回"的流程来串联组件——先经过 Gateway 鉴权路由,然后 Nacos 发现服务,Feign 声明式调用,LoadBalancer 选实例,Sentinel 保驾护航,Sleuth 记录全链路,异步场景用 Stream。
Q2:Nacos 和 Eureka 的区别?
| 维度 | Nacos | Eureka |
|---|---|---|
| CAP 模型 | AP/CP 可切换 | 仅 AP |
| 配置中心 | 内置 | 无(需配合 Config) |
| 健康检查 | 心跳 + 主动探测(TCP/HTTP/MySQL) | 仅心跳 |
| 一致性协议 | Distro(AP)/ Raft(CP) | 无 |
| 服务下线感知 | 推送 + 长轮询,秒级 | 定时拉取,分钟级 |
| 维护状态 | 活跃 | 停止维护 |
关键点: Nacos 的 CP 模式基于 Raft 协议,临时实例走 AP,持久化实例走 CP。Eureka 的自我保护机制是经典面试点——当大量心跳丢失时,Eureka 不会剔除实例,防止网络分区导致大面积误删。
Q3:Spring Cloud Gateway 的工作原理?与 Zuul 的区别?
三大核心组件:
- Route(路由):定义转发规则,包含 ID、URI、Predicate、Filter
- Predicate(断言):匹配请求条件(Path、Header、Method 等)
- Filter(过滤器):前置/后置处理(鉴权、限流、日志、修改请求头)
与 Zuul 对比:
- Gateway 基于 WebFlux + Netty(非阻塞异步),Zuul 1.x 基于 Servlet(阻塞同步)
- 性能:Gateway 远高于 Zuul 1.x
- Gateway 是 Spring 官方推荐,Zuul 已停维
Q4:OpenFeign 的原理?
Feign 本质是动态代理 + HTTP 客户端:
- Spring 扫描
@FeignClient注解的接口 - 通过 JDK 动态代理生成代理对象
- 调用接口方法时,代理对象拦截请求
- 解析方法上的注解,构造 HTTP 请求(URL、Headers、Body)
- 从注册中心获取服务实例列表,经内置的负载均衡选择实例
- 发送 HTTP 请求,接收响应,反序列化为返回类型
二、架构设计类
Q5:如何设计一个电商微服务架构?
面试回答框架:
- 服务拆分:用户服务、商品服务、订单服务、支付服务、库存服务、购物车服务、通知服务、营销服务(8 个核心服务)
- 基础设施:Nacos(注册+配置)、Gateway(网关)、Sentinel(熔断限流)、SkyWalking(链路追踪)、RocketMQ(消息队列)
- 数据存储:MySQL(业务数据,每个服务独立数据库)、Redis(缓存、购物车、分布式锁)、Elasticsearch(商品搜索)
- 核心链路:下单流程——Gateway → 鉴权 → 查询商品 → 预扣库存(Sentinel 熔断保护)→ 创建订单 → 创建支付单 → MQ 异步通知
- 高并发:秒杀场景——Redis Lua 预扣库存 → MQ 削峰 → Sentinel 消费端限流 → 订单异步处理
- 分布式事务:Seata AT 模式,RocketMQ 事务消息兜底
- 部署:Kubernetes + HPA 弹性伸缩,Jenkins CI/CD
Q6:服务拆分的原则是什么?
- 单一职责:一个服务只做一件事,高内聚低耦合
- 数据库 per 服务:每个服务有自己的数据库,不能直接访问别人的数据库
- 先边缘后核心:先拆非核心服务(通知、文件),再拆核心服务(订单、支付)
- 基于业务能力,而非技术分层:按订单、用户、商品拆分,不是按 Controller/Service/DAO 拆分
- DDD 限界上下文:用事件风暴识别领域边界,上下文映射确定服务边界
Q7:分布式事务怎么处理?
| 方案 | 原理 | 适用场景 |
|---|---|---|
| Seata AT | 一阶段提交 + 二阶段回滚(自动生成 undo log) | 通用场景,业务无侵入 |
| TCC | Try-Confirm-Cancel 三阶段 | 资金交易,需业务改造 |
| Saga | 长事务拆分 + 补偿 | 流程长、不能锁资源 |
| RocketMQ 事务消息 | 半消息 + 本地事务 + 提交/回滚 | 异步解耦,最终一致性 |
| 本地消息表 | 本地事务 + 消息表 + 定时重试 | 简单可靠 |
推荐组合: Seata AT 做主力,RocketMQ 事务消息做兜底。
三、实战场景类
Q8:如何保证服务间调用的幂等性?
场景: 用户点击"下单"按钮,因为网络抖动发了两次请求,如何保证不重复扣款?
| 方案 | 实现 | 适用场景 |
|---|---|---|
| 数据库唯一索引 | INSERT ... ON DUPLICATE KEY UPDATE | 插入操作 |
| Token 机制 | 请求前获取 Token,提交时校验并删除 Token | 表单提交 |
| 状态机 | 订单状态:待支付→已支付→已发货,不能跳状态 | 流程管控 |
| 分布式锁 | Redis SETNX + Lua 脚本 | 并发控制 |
| 乐观锁 | 版本号校验 WHERE version = ? | 更新操作 |
组合使用: 前端防抖 + Token 机制 + 数据库唯一索引 + 状态机校验,四道防线。
Q9:服务雪崩是什么?怎么解决?
雪崩效应: 一个服务故障 → 调用方线程阻塞等待 → 线程池耗尽 → 调用方也故障 → 级联蔓延 → 整个系统崩溃。
解决方案:
- 熔断(Circuit Breaker):当失败率达到阈值,自动熔断,快速失败
- 降级(Fallback):熔断后返回兜底数据(缓存、默认值、提示信息)
- 限流(Rate Limiting):控制请求量,超过阈值直接拒绝
- 隔离(Bulkhead):线程池隔离,一个服务故障不影响其他服务
- 超时(Timeout):设置合理的超时时间,避免线程无限等待
Sentinel 实现: 熔断规则(慢调用比例/异常比例)+ 降级方法(blockHandler/fallback)+ 限流规则(QPS/线程数)。
Q10:如何实现全链路灰度发布?
场景: 新版本只给内部测试用户使用,普通用户仍使用旧版本。
请求 → Gateway (Weight 路由)
│
├── 90% → order-service-v1 (稳定版)
│
└── 10% → order-service-v2 (灰度版)
│
├── Feign → inventory-service-v2 (灰度版)
│
└── Feign → payment-service-v2 (灰度版)实现要点:
- Gateway 通过 Header(
X-Version: v2)或 Weight 路由分流 - 透传版本标记到下游服务(Feign RequestInterceptor)
- 下游服务根据版本标记选择对应版本的服务实例
- Nacos 元数据区分版本:
spring.cloud.nacos.discovery.metadata.version=v2
Q11:如何排查"下单慢"问题?
排查思路(按层级):
- 看监控:Prometheus 查看各服务 QPS、RT、错误率,定位是哪个服务慢
- 看链路:SkyWalking 输入慢请求的 TraceId,查看哪个 Span 耗时最长
- 看日志:ELK 搜索 TraceId,查看慢服务是否有异常日志
- 看数据库:慢查询日志,是否有全表扫描、缺失索引
- 看连接池:数据库连接池是否耗尽,HTTP 连接池是否耗尽
- 看 GC:JVM GC 日志,是否频繁 Full GC 导致 STW
常用工具: Arthas(在线诊断)、JProfiler(性能分析)、JMeter(压测)。
Q12:Spring Cloud 和 Spring Cloud Alibaba 怎么选?
| 维度 | Spring Cloud Netflix | Spring Cloud Alibaba |
|---|---|---|
| 注册中心 | Eureka(停维) | Nacos(活跃) |
| 配置中心 | Config + Bus | Nacos(内置) |
| 熔断降级 | Hystrix(停维) | Sentinel(活跃) |
| 网关 | Zuul(已不推荐) | 仍用 Gateway |
| 分布式事务 | 无 | Seata |
| 社区活跃度 | 低 | 高 |
| 生产验证 | Netflix 内部 | 阿里双十一 |
| 推荐度 | ★★(存量) | ★★★★★(新项目) |
结论: 新项目无脑选 Spring Cloud Alibaba,存量项目逐步迁移。