Skip to content

SpringCloud微服务架构面试题库 ​

生成时间: 2026-05-21 21:14


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

【面试题】1. Nacos作为注册中心,如何实现服务的优雅上下线? ​

【标准答案】 优雅上线:服务启动后先完成预热(缓存加载、连接池初始化),再向Nacos注册,注册成功后等待一小段时间让网关和其他服务同步到实例信息,最后才开始接收流量。可以通过spring.cloud.nacos.discovery.enabled=true配合@PostConstruct做初始化。

优雅下线:先从Nacos注销(调用注销API或设置enabled=false),让Nacos通知其他服务剔除该实例,等待正在处理的请求完成(设置缓冲期比如30秒),再真正停止服务。Spring Cloud提供了preStop钩子,在K8s中可以用lifecycle.preStop配合sleep实现。

核心是保证流量不丢失、请求不中断,生产环境建议配合健康检查和就绪探针一起使用。

【面试题】2. Sentinel的熔断降级策略有哪些?分别适用于什么场景? ​

【标准答案】 三种核心策略:

  1. 慢调用比例:统计一段时间内响应时间超过阈值的请求比例,超过设定值触发熔断。适合对响应时间敏感的业务,比如支付、下单场景。
  2. 异常比例:统计异常数占请求总数的比例,超过阈值熔断。适合外部依赖不稳定的情况,比如第三方API调用。
  3. 异常数:统计指定时间内的异常数量,达到阈值直接熔断。适合绝对不允许失败的敏感操作。

熔断后进入半开状态会放一个请求探测,成功恢复、失败继续熔断。实际项目中通常配合限流规则使用,熔断是兜底策略,限流是主动防护。

【面试题】3. OpenFeign如何实现动态修改超时时间?生产环境如何配置? ​

【标准答案】 动态超时可以通过两种方式:

  1. 配置中心动态刷新:在Nacos配置中设置feign.client.config.default.connectTimeout和readTimeout,配合@RefreshScope实现热更新。
  2. 自定义Feign.Builder:通过拦截器或自定义Request.Options,在每次请求时从配置中心拉取最新超时配置。

生产配置建议:

  • 全局默认超时:连接3秒,读超时5秒
  • 核心服务单独配置:支付类接口可以短一些,报表导出类可以长一些
  • 必须配置重试策略,避免网络抖动导致的失败
  • 开启Feign日志级别FULL便于排查问题
  • 配合Sentinel实现超时后的降级处理

关键是不同服务不同接口要差异化配置,不能一刀切。

【面试题】4. Spring Cloud Gateway如何实现统一的JWT认证鉴权? ​

【标准答案】 实现方案:

  1. 网关统一认证:在Gateway中配置AuthGlobalFilter,解析请求头中的JWT Token,验证签名和有效期,提取用户信息放入请求头传递给下游服务。
  2. 服务间信任:下游服务信任网关传递的用户信息,无需再次验证JWT,通过AddRequestHeader传递X-User-Id等关键信息。

关键代码:

java
@Component
public class AuthGlobalFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        // JWT验证逻辑
        Claims claims = JwtUtil.parseToken(token);
        ServerHttpRequest request = exchange.getRequest().mutate()
            .header("X-User-Id", claims.getSubject())
            .build();
        return chain.filter(exchange.mutate().request(request).build());
    }
}

安全要点:

  • 网关只做Token解析验证,不做权限校验
  • 权限校验在具体服务中通过AOP或拦截器实现
  • 敏感接口额外验证请求签名

【面试题】5. Seata的AT模式和TCC模式有什么区别?分别适合什么业务场景? ​

【标准答案】 AT模式:

  • 原理:一阶段提交直接成功,二阶段根据Undo Log回滚或删除日志
  • 特点:无侵入,基于数据库本地事务,支持MySQL/Oracle/PostgreSQL
  • 适用:并发不高、对一致性要求不严格的业务,如积分、优惠券

TCC模式:

  • 原理:Try-Confirm-Cancel三个阶段,业务代码需实现三个接口
  • 特点:侵入性强,但性能好、一致性强
  • 适用:高并发、对一致性要求高的核心业务,如支付、库存扣减

选择建议:

  • 优先选AT,开发成本低
  • 涉及资金、库存等核心数据用TCC
  • TCC要注意幂等设计、空回滚、悬挂问题
  • 跨公司服务调用考虑Saga模式

AT模式本质是补偿事务,TCC是预留资源事务,生产环境需要根据业务复杂度和一致性要求做取舍。

【面试题】6. Redis分布式锁使用Redisson实现,如何保证锁的可靠性? ​

【标准答案】 Redisson锁的核心机制:

  1. 锁续期(Watch Dog):默认30秒过期,后台线程每10秒自动续期,防止业务没执行完锁就释放
  2. 可重入锁:基于Hash结构存储,同一线程可多次获取锁
  3. 等待队列:请求获取锁失败会进入等待队列,支持公平锁和非公平锁

可靠性保证:

java
RLock lock = redissonClient.getLock("order:123");
try {
    // 尝试获取锁,最多等待5秒,锁30秒后自动释放
    boolean acquired = lock.tryLock(5, 30, TimeUnit.SECONDS);
    if (acquired) {
        // 执行业务逻辑
    }
} finally {
    if (lock.isHeldByCurrentThread()) {
        lock.unlock();
    }
}

生产注意:

  • 开启Watch Dog防止锁提前过期
  • finally中判断是否持有锁再释放
  • 集群环境用RedLock保证高可用
  • 锁粒度尽量小,避免大key

【面试题】7. 微服务架构下,如何实现配置的热更新而不重启服务? ​

【标准答案】 核心方案:

  1. Nacos Config动态刷新:使用@RefreshScope注解配置类,Nacos配置变更后自动刷新Bean
  2. 配置变更监听:通过@NacosConfigListener监听配置变化,手动更新内存中的配置

实现方式:

java
@RefreshScope
@RestController
public class ConfigController {
    @Value("${app.config.key}")
    private String configValue;
    
    @NacosConfigListener(dataId = "app.properties")
    public void onConfigChange(String newConfig) {
        // 配置变更回调
    }
}

注意事项:

  • @RefreshScope会重建Bean,有状态的服务要注意数据丢失
  • 数据库连接、线程池等初始化类配置无法热更新,需要重启
  • 复杂配置建议用配置中心SDK的API手动刷新
  • 开发环境可以关闭自动刷新,避免意外变更

配置热更新适合开关类、阈值类配置,核心配置变更还是建议重启。

【面试题】8. SkyWalking链路追踪对性能有什么影响?如何优化? ​

【标准答案】 性能影响:

  • CPU开销:每个请求创建Span、传递Context,约占请求处理的2-5%CPU
  • 内存开销:Span对象会占用堆内存,高并发时Full GC频繁
  • 网络IO:Span数据异步上报到OAP,网络带宽消耗

优化方案:

  1. 采样策略:高并发服务设置1%-10%采样率,核心服务100%
  2. 异步上报:使用gRPC异步发送,避免阻塞业务线程
  3. Span精简:只追踪关键调用链,非核心操作跳过追踪
  4. 部署优化:OAP集群独立部署,ES分片扩容

配置示例:

yaml
agent.sample_n_per_3_secs: 3  # 每3秒采样3个请求
agent.span_limit: 200  # 单个Span最大标签数

生产经验:QPS超过1万的服务必须降采样,否则链路追踪组件本身会成为瓶颈。

【面试题】9. Spring Cloud Stream如何保证消息的可靠性投递? ​

【标准答案】 可靠性三阶段:

  1. 生产端:开启事务消息或Confirm确认机制,消息持久化后再返回成功
  2. 消费端:手动ACK机制,业务处理成功后再确认,失败则重试或进入死信队列
  3. Broker端:配置消息持久化、多副本同步复制

实现代码:

java
@StreamListener(MySink.INPUT)
public void handleMessage(Message<String> message) {
    try {
        // 业务处理
        process(message.getPayload());
        // 手动确认
        AckUtils.acknowledge(message);
    } catch (Exception e) {
        // 重试或进入死信队列
        AckUtils.nack(message);
    }
}

配置要点:

  • 消费组隔离:每个服务配置独立的group,避免消息竞争
  • 重试策略:配置重试次数和间隔,避免无限重试
  • 死信队列:重试失败的消息进入DLQ,人工处理
  • 消息去重:使用业务唯一键配合Redis去重

生产环境必须配合监控告警,对积压和失败消息及时处理。

【面试题】10. Kubernetes环境下部署微服务,如何实现服务的灰度发布? ​

【标准答案】 灰度发布方案:

  1. Deployment版本控制:通过镜像Tag区分版本,部署新版本Deployment
  2. Service流量切分:通过label selector控制流量比例
  3. Ingress/Nginx路由:基于Header、Cookie、权重进行流量分流

具体实现:

yaml
# 新版本Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      version: v2
---
# Service同时暴露两个版本
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp  # 同时匹配v1和v2
---
# Ingress基于权重分流
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"

灰度流程:

  1. 先部署新版本Pod,初始副本数为1
  2. 通过Ingress控制10%流量进入新版本
  3. 观察监控指标(错误率、延迟、资源使用)
  4. 逐步增加权重:10%→30%→50%→100%
  5. 确认稳定后下线旧版本

推荐使用Argo Rollouts或Flagger实现自动化灰度,配合Prometheus指标自动判断是否继续发布。


题目数量: 10题
知识点覆盖: 服务注册发现、熔断限流、服务调用、API网关、分布式事务、分布式锁、配置中心、链路追踪、消息队列、容器化部署