面试追问地图

主问题必讲关键点下一层追问
注册发现注册、心跳、订阅、本地缓存注册中心不可用还能否调用
配置中心推送/拉取、版本、灰度多实例短时不一致、错误配置回滚
Feign/RPC服务发现、序列化、超时重试风暴、幂等、连接池
负载均衡节点选择、权重、健康状态一致性哈希扩缩容、客户端缓存
Gateway路由、认证、限流、灰度网关高可用、是否做业务编排
Sentinel限流、熔断、系统保护流控模式、热点参数、规则持久化
服务雪崩超时、隔离、重试、熔断、降级线程池隔离 vs 信号量隔离
分布式一致性消息、补偿、幂等重复、乱序、死信、人工对账
链路追踪traceId/spanId、跨进程传播线程池上下文丢失、MDC 串联、头部 vs 尾部采样

微服务题不能只列组件名,要沿一次请求讲清注册、选址、调用、超时和失败处理。


一、Spring Cloud 基础

微服务的服务间通信方式?

难度 🟡

快答

方式协议同步/异步场景
FeignHTTP/REST同步简单调用
gRPCHTTP/2同步高性能
消息队列MQ异步解耦

二、微服务核心组件

SpringCloud vs SpringBoot 区别?

  • SpringBoot:构建单个 Spring 应用的框架
  • SpringCloud:构建分布式微服务架构的工具集(注册中心、负载均衡、熔断器等)

核心微服务组件

组件解决问题SpringCloud 实现Alibaba 实现
注册中心服务发现与状态维护EurekaNacos
负载均衡服务发现 + 请求分发RibbonNacos 服务端均衡
服务通信服务间消息通信Feign/RestTemplateFeign/Dubbo
配置中心集中管理配置ConfigNacos 内置
服务网关API 路由GatewayGateway
服务保护防止雪崩HystrixSentinel
链路追踪调用链路可视化Sleuth/ZipkinSleuth/Zipkin

负载均衡算法

  • 轮询:按顺序分发(简单/加权)
  • 随机:随机选择(简单/加权)
  • 一致性哈希:同 IP/同参数路由到同一服务器,扩缩容只影响相邻区段;哈希环与虚拟节点原理见分布式系统
  • 最小活跃数:分发到当前请求最少的服务器

服务熔断 vs 服务降级

熔断降级
目的保护链路,防止雪崩保护核心服务
触发条件下游服务超时/不可用系统负载过高
行为停止调用,快速返回错误非核心功能不处理或简化处理
比喻保险丝丢卒保车

Hystrix 熔断默认配置:10 秒内请求 >= 20 次且错误率 > 50% 时触发。Hystrix 自 2018 年起已进入维护模式、不再新增特性,新项目应选 Sentinel 或 resilience4j;这里列出是因为存量系统和面试历史考点仍常涉及。

熔断三状态(Closed/Open/Half-Open)流转与限流算法原理见系统设计


三、注册中心与配置中心

服务注册与发现的基本流程?

难度 🟡

服务启动 → 注册实例和元数据 → 定期心跳
调用方 → 拉取/订阅实例列表 → 本地负载均衡 → 发起调用

注册中心需要处理:

  • 实例上下线。
  • 健康检查和心跳超时。
  • 客户端缓存。
  • 网络分区时的可用性与一致性取舍。

Nacos 临时实例和持久实例有什么区别?

  • 临时实例:依赖客户端心跳,心跳超时后可被删除,适合可弹性扩缩的服务实例。
  • 持久实例:服务端主动探测,实例异常后保留注册信息,适合需要保留元数据的场景。

回答时应结合实际使用版本和部署模式,不要只背 AP/CP 标签。

配置中心如何保证变更安全?

  • 配置按环境和命名空间隔离。
  • 变更需要权限、审计和版本记录。
  • 客户端监听变更并刷新允许动态更新的 Bean。
  • 高风险配置先灰度,再逐步扩大范围。
  • 配置解析失败时保留旧值或快速回滚。

四、网关与服务调用

API 网关的职责有哪些?

  • 路由和协议适配。
  • 统一认证、鉴权和签名校验。
  • 限流、黑白名单和防刷。
  • 请求日志、Trace ID 和指标。
  • 灰度路由和流量切分。

网关不适合承载复杂业务编排,否则会形成新的单体和性能瓶颈。

OpenFeign 调用需要注意什么?

  • 明确连接超时和读取超时。
  • 只对适合的错误进行有限重试。
  • 写请求要保证幂等。
  • 配置熔断和降级,避免故障扩散。
  • 记录调用方、目标服务、耗时和错误码。

客户端负载均衡和服务端负载均衡的区别?

  • 客户端负载均衡:调用方获取实例列表并选择节点,少一次代理转发,但客户端逻辑更复杂。
  • 服务端负载均衡:由网关或代理选择后端,治理集中,但增加一跳和中心组件压力。

五、Sentinel 与流量治理

限流、熔断和系统保护有什么区别?

能力判断依据目的
限流QPS、并发线程数控制进入系统的流量
熔断慢调用、异常比例或异常数隔离不稳定依赖
系统保护系统负载、CPU、入口 QPS保护整体系统容量

Sentinel 常见流控模式?

  • 直接:当前资源达到阈值后限流。
  • 关联:关联资源过载时限制当前资源。
  • 链路:只限制特定调用入口。

流控效果可选择快速失败、预热或匀速排队。方案需要结合业务是否允许等待和请求是否可重试。

如何防止服务雪崩?

难度 🔴

需要组合治理:

  • 超时:尽快释放阻塞资源。
  • 重试:限制次数并使用退避。
  • 熔断:故障依赖快速失败。
  • 降级:保留核心功能。
  • 隔离:不同依赖使用独立线程池、连接池或信号量。
  • 限流:控制入口流量。
  • 缓存和兜底:在可接受一致性范围内返回可用结果。

六、微服务一致性与可观测性

微服务如何保证数据一致性?

根据业务选择:

  • 强一致:本地事务或尽量收敛到单服务。
  • 最终一致:事务消息、本地消息表、补偿任务。
  • 长事务:Saga 或 TCC,但开发和治理成本较高。

所有异步方案都要考虑幂等、重复消息、乱序、补偿和人工兜底。

通用概念:补偿与重试都建立在幂等之上——不幂等的接口不能安全重试。

如何设计跨服务 Trace?

频次 ★★★ · 难度 🟡

是什么:一次请求跨多个服务,链路追踪用两个 ID 把散落各处的日志和耗时串成一棵树——traceId 全局唯一、入口生成后整条链路不变;spanId 标识链路中的一段工作单元,记录 parentSpanId 构成父子树。W3C Trace Context 标准头:traceparent: 00-<traceId 32hex>-<spanId 16hex>-<flags>(老系统常见 Zipkin B3 头 X-B3-TraceId 等)。

生成与跨进程传播

  • 生成:入口服务发现请求头没有 trace 上下文就生成一个 128 位随机 traceId——只要求唯一不要求有序,随机数即可,不需要像分布式 ID 那样全局协调(见分布式系统分布式 ID 一节的对比)
  • HTTP/RPC:出站拦截器(Feign/RestTemplate interceptor、RPC attachment)把上下文注入协议头;进站过滤器解出并放入线程上下文,同时派生新 spanId、当前 span 变 parent
  • MQ:没有”请求头”就塞消息属性(Kafka headers、RocketMQ userProperty),消费端取出接上——载体换了,“上下文随调用走”的模式不变
  • 异步/线程池:上下文存在 ThreadLocal 里,跨线程会丢,要装饰 Runnable 在提交时捕获、执行时回放(与 TransmittableThreadLocal 是同一问题,见并发编程ThreadLocal 一节)

与 MDC 日志串联:MDC(Mapped Diagnostic Context)是 logback/log4j2 提供的 ThreadLocal Map。进站时把 traceId 放进 MDC,日志 pattern 写 %X{traceId},所有业务日志自动携带——ELK 里按 traceId 一搜,整条链路的日志聚齐。这是”追踪系统看耗时瀑布”和”日志系统看业务细节”的连接点:

// 进站 Filter:有上下文就接续,没有就新开;写入 MDC 供日志输出
String traceId = parseOrNewTraceId(request.getHeader("traceparent"));
MDC.put("traceId", traceId);
try {
    chain.doFilter(request, response);
} finally {
    MDC.clear();   // 线程池线程复用,不清理会串到下一个请求的日志里
}

采样率取舍:全量上报时每个请求产生 N 个 span,存储成本随流量线性涨。

策略做法代价
头部采样入口按比例决定(如 1%),决定随上下文传播,整链要采都采便宜,但出错的那条可能恰好没采
尾部采样链路结束后看有无错误/慢再决定保留不漏关键链路,但收集端要先缓存全量
工程折中低基线采样 + 错误/慢请求强制采样主流做法

常见追问

  • traceId 到线程池里丢了怎么排查/解决?→ ThreadLocal 不跨线程;用 TTL 或 micrometer context-propagation 装饰执行器,提交时捕获、执行时回放
  • 采样 1% 漏掉报错链路怎么办?→ 头部采样的固有缺陷,用”错误强制采样”或尾部采样补
  • Trace、Metrics、Log 什么关系?→ 可观测性三支柱:Metrics 发现问题(告警)、Trace 定位到哪个服务哪一跳、Log 看服务内部细节;traceId 是三者的关联键

通用概念:链路追踪本质是跨进程的上下文传递——进程内靠 ThreadLocal,跨线程靠捕获/回放,跨进程靠协议头捎带。与 Spring 事务传播行为(线程内的上下文传递策略,见Spring)是同一模式在不同作用域的形态。

微服务一定比单体好吗?

不一定。微服务适合边界清晰、团队较大、需要独立扩缩容和发布的系统,但会增加:

  • 网络调用和故障模式。
  • 数据一致性难度。
  • 部署、监控和运维成本。
  • 跨团队协作成本。

拆分应围绕业务边界和组织能力,而不是只按代码层或数据库表拆分。