深入解析:微服务篇面试题(不定时更新)
spring cloud的博客也可以参考一下springcloud
seata知识点可以参考我之前写的分布式事务Seata也是在csdn上的博客
行参考我之前写的sentinel的博客:Sentinel微服务保护
1. 介绍一下微服务常用组件
知识点解析:
微服务不是一个单一的技术,而是一套生态。得知道每个环节大概用什么工具。目前主流是 Spring Cloud Alibaba 体系,旧一点的是 Spring Cloud Netflix。
注册中心/配置中心:Nacos, Eureka, Zookeeper, Consul
负载均衡:Ribbon, LoadBalancer
服务调用:OpenFeign, Dubbo
服务保护(熔断降级):Sentinel, Hystrix
网关:Spring Cloud Gateway, Zuul
分布式事务: Seata
面试参考回答:
“在我们的项目中,主要使用了 Spring Cloud Alibaba 的这套组件体系。
具体包括:
注册中心和安装中心我们使用的是Nacos,用于服务的注册发现以及配置的动态管理。
服务调用使用 OpenFeign,底层集成了 Ribbon/LoadBalancer 做负载均衡。
服务网关使用的是 Spring Cloud Gateway,作为统一的流量入口,处理鉴权和路由。
流量控制和熔断降级使用的是 Sentinel,用来保护架构不被大流量冲垮。
分布式事务方面,如果涉及跨库运行,大家使用的是Seata。”
其实回答的时候也可以只用说前几个标黑的组件的名字就行
2. 服务注册和服务发现的概念
知识点解析:
把它想象成“电话簿”。
注册:多少”。就是这里的服务(Provider)启动时,告诉电话簿(注册中心):“我是谁,IP是多少,端口
发现:调用者(Consumer)想打电话,先去查电话簿,拿到号码列表,然后自己选一个打过去。
心跳:服务要定期给电话簿报平安,不然电话簿会把你划掉。
面试参考回答:
服务注册是指:服务提供者在启动时,将自己的服务名称、IP地址、端口等信息发送给注册中心(如Nacos),注册中心会把这些信息存储在一个列表中。同时,提供者会定时发送心跳来维持在线状态。
服务发现是指:服务消费者在调用接口时,不直接写死目标IP,而是向注册中心拉取可用的服务列表。消费者获取列表后,配合负载均衡策略,选择其中一个实例发起远程调用。”
3. Eureka 和 Nacos 都可以作为注册中心,说一下它们的区别
知识点解析:
这是高频题!!核心区别在于CAP理论的取舍和功能范围。
范围:Nacos = 注册中心 +配置中心注册中心。就是;Eureka 只
CAP:Eureka 只能保AP(可用性);Nacos 默认AP,但拥护切换CP(一致性)。
机制:Nacos 支持临时实例(心跳)和持久实例(健康检查)。
面试参考回答:
“它们的区别主要体现在三个方面:
功能范围不同:Nacos 不仅是注册中心,还是配备中心;而 Eureka 仅作为注册中心。
CAP理论的支持不同:Eureka 严格遵守AP(可用性),保证服务高可用,但数据可能短暂不一致。Nacos 默认是AP模式,但支持切换到CP(强一致性)模式,比如在涉及金融业务时可以使用 CP。
健康检查机制不同:Nacos 将服务分为临时实例和持久实例。临时实例重要靠心跳检测;持久实例则是 Nacos主动发请求去探测健康状态。Eureka 只有心跳机制。”
4. 项目中服务远程调用时的负载均衡是如何达成的?
知识点解析:
微服务里的负载均衡通常是客户端负载均衡。
像 Nginx 那样所有的请求先发给服务器端再分发。就是你(Consumer消费者)从 Nacos 拿到了3个地址,是你自己(在本地代码里)决定选哪一个,而不
工具:Ribbon(老)或 Spring Cloud LoadBalancer(新)。
面试参考回答:
“在项目中,我们核心通过OpenFeign配合 Ribbon(或 Spring Cloud LoadBalancer)来实现客户端负载均衡。
具体的流程是:
当我们发起远程调用时,Ribbon 会先从注册中心拉取目标服务的服务列表并缓存到本地。然后根据调整的负载均衡策略(比如默认的轮询或者随机),从列表中选择一个具体的服务实例地址,最后发起网络请求。”
5. 介绍一下 Ribbon 中常用的负载均衡策略
知识点解析:
也就是怎么选人的问题。
轮流来(RoundRobin)。
瞎蒙(Random)。
看谁响应快(WeightedResponseTime)。
看谁健康(AvailabilityFiltering)。
️ 面试参考回答:允许就说策略的中文就行
“Ribbon 内置了多种策略,常用的有:
RoundRobinRule(轮询): 这是默认策略,按照顺序依次调用服务实例。
RandomRule(随机):随机选择一个服务实例。
WeightedResponseTimeRule(权重/响应时间): 根据响应时间分配权重,响应越快被选中的概率越高。
ZoneAvoidanceRule(区域亲和): 优先选择同一机房或区域的服务,同时过滤掉性能差的实例。”
6. 什么是服务雪崩,以及服务雪崩的解决方案
知识点解析:
雪崩:A调B,B调C。C挂了,B等C等到超时,B的线程耗尽也挂了,A等B也挂了。全崩。
解决:别等了(超时)、别调了(熔断)、少调点(限流)、给个兜底数据(降级)。
️ 面试参考回答:
“服务雪崩是指在微服务调用链路中,因为某个下游服务节点故障(如响应慢或宕机),导致上游服务的线程资源被耗尽,最终导致整个链路甚至整个系统瘫痪的现象。
解决方案主要借助 Sentinel 实现:
熔断降级:当检测到下游服务异常比例过高时,暂时切断对该服务的调用,直接返回一个预设的默认值(兜底数据),避免长时间等待。然后等过一段时间后又去重新发起调用看该服务是否恢复正常。
线程隔离(舱壁模式): 限制每个业务能使用的线程数,防止一个业务耗尽所有资源。
服务限流:对高并发请求进行限流,防止框架被瞬间流量打垮。”
7. 解释一下限流算法中的漏桶算法和令牌桶算法
知识点解析:
漏桶 (Leaky Bucket):像一个底部有孔的桶。水(请求)随便倒进来,但流出去的速度是固定的。特点:强行平滑流量,不能处理突发。
令牌桶 (Token Bucket):有人匀速往桶里放令牌。请求来了要拿令牌才能经过。如果桶里存了很多令牌,就能瞬间处理一大波请求。特点:允许突发流量。
️ 面试参考回答:
“这是两种常见的限流算法:
漏桶算法:不管请求进来的速率多快,它都强制以固定的速率处理请求。假设有突发流量,多余的请求会溢出(被丢弃)。它的主要特点是平滑流量,但无法应对突发流量。
令牌桶算法:系统以固定速率往桶里放入‘令牌’,桶满了就不放了。请求进来时必须拿到令牌才能处理。因为桶里可以存令牌,所以它允许一定程度的突发流量(只要桶里有令牌,就可以瞬间处理完,所以这里就会有假如桶中积累了令牌,恶意用户可以利用这些令牌在瞬间发送大量请求,也就是所谓的脉冲攻击,导致其他用户无令牌可用。)。
在 Spring Cloud Gateway 中通常利用的是令牌桶算法。”
8. Spring Cloud Gateway 的路由和断言是什么关系?
知识点解析:
路由 (Route):是一条规则的实体。具备 ID、目标 URI、断言、过滤器。
断言 (Predicate):是路由生效的条件(If 语句)。
关系: 如果 断言为 true,就执行该路由。
️ 面试参考回答:
“在 Gateway 中,路由(Route) 是网关配置的基本模块,它包含了目标 URI、断言和过滤器。
而 断言(Predicate) 是路由判断的条件。
它们的关系是:当请求到达网关时,网关会利用断言来判断当前请求是否符合某个路由的规则(例如判断路径是否匹配 /user/**)。如果断言条件成立(返回 true),网关就会根据该路由的部署,将请求转发到对应的 URI。”
9. 说一下 Spring Cloud Gateway 中常见的过滤器
知识点解析:
请求在转发前或返回后,做些手脚。就是过滤器(Filter)就
局部过滤器(针对单个路由):加个Header,去掉个前缀。
全局过滤器(GlobalFilter):鉴权、黑白名单、统计时长。
️ 面试参考回答:
“Gateway 的过滤器主要分为局部过滤器和全局过滤器。
局部过滤器(GatewayFilter): 常见的有
AddRequestHeader(添加请求头)、StripPrefix(去除路径前缀)、RequestRateLimiter(限流)等,通常在配置文件中针对特定路由配置。全局过滤器(GlobalFilter): 作用于所有路由。我们在项目中核心用它来实现统一鉴权(校验 Token)、全局日志记录 以及 统计接口响应时间。通常需要大家自己实现
GlobalFilter接口。”
10. Sentinel 中常用的流量控制规则有哪些?
知识点解析:
怎么判断要不要拦住这个请求?
阈值类型:QPS(每秒请求数)或 线程数。
流控模式:直接(看自己)、关联(看别人,A满了限制B)、链路(看入口)。
流控效果:快速失败、Warm Up(预热)、排队等待。
可以参考我之前写的sentinel的博客:Sentinel微服务保护
️ 面试参考回答:
“Sentinel 的流控规则非常灵活,主要包括以下维度:
阈值类型: 可以基于 QPS(每秒请求数)或者并发线程数 进行控制。
流控模式:
直接模式:达到阈值直接限流。
关联模式:当关联的资源(如写入接口)达到阈值时,限制“”当前”“资源(如查询接口),常用于读写分离场景。
链路模式: 只限制从特定入口“”进来“”的流量。
流控效果: 包括 快速失败(直接报错)、Warm Up(预热,让通过量缓慢增加)和排队等待(削峰填谷)。”
11. 什么是 CAP 定理?
知识点解析:
分布式系统的三大指标,只能得其二。
C (Consistency):强一致性。所有节点数据时刻保持一致。(类似银行转账)
A (Availability):可用性。服务一直可用,哪怕读到旧内容。(类似刷朋友圈)
P (Partition Tolerance):分区容错性。网线断了系统还能跑。(分布式系统必须有P)
️ 面试参考回答:
“CAP 定理是指在分布式系统中,无法同时满足以下三个指标,最多只能满足其中两个:
Consistency(一致性):所有节点访问同一份最新的数据副本。
Availability(可用性):非故障的节点在合理时间内返回合理的响应(允许数据暂时不一致)。
Partition Tolerance(分区容错性):当网络出现分区(通讯中断)时,系统仍能继续工作。
源于分布式系统必须容忍网络故障,所以P 是必须选的。我们通常只能在CP(强一致,如 Zookeeper/Nacos CP模式)和AP(高可用,如 Eureka/Nacos AP模式)之间做权衡。”
12. 什么是 BASE 理论?
知识点解析:
CAP 中 AP 的延伸。既然做不到强一致(C),那我们就退一步。
BA:基本可用(允许慢一点,允许损失部分功能)。
S:软状态(允许有中间状态,比如“支付中”)。
E:最终一致性(过一会数据就一致了)。
️ 面试参考回答:
“BASE 理论是对 CAP 中 AP(一致性与可用性权衡)的延伸,核心思想是‘即使无法做到强一致性,但应用可以根据业务特点,采用适当的方式达到最终一致性’。
它具备三个要素:
Basically Available(基本可用):系统出了故障,但核心功能还能用,可能响应变慢或部分功能降级。
Soft state(软状态):允许系统存在中间状态(如订单支付中),且不影响整体可用性。
Eventually consistent(最终一致性):系统保证在一段时间后,所有节点的信息最终会达到一致,不需要实时一致。”
13. 介绍一下分布式锁的常见实现方案
知识点解析:
单机锁(synchronized)锁不住多台机器,所以需要找一个大家都能访问的“公证人”。
Redis: 快,最常用。
SETNX+ 过期时间 + 看门狗(WatchDog)。Zookeeper:可靠。临时顺序节点。
数据库:慢,基本不用。
️ 面试参考回答:
“常见的分布式锁实现主要有三种:
基于 Redis 实现(最推荐): 使用
setnx命令。为了防止死锁,需要设置过期时间;为了防止锁误删(A删了B的锁),得判断Value(UUID);为了解决锁过期但业务没执行完的问题,通常使用Redisson框架,它自带看门狗机制(WatchDog)自动给锁续期。性能最高。基于 Zookeeper 建立: 利用临时顺序节点。如果客户端断开,节点自动删除(释放锁),可靠性高,但性能不如 Redis。
基于数据库实现: 利用主键或唯一索引的排他性。性能最差,不推荐。”
分布式事务,分布式事务的解决方案有哪些?就是14. 什么
知识点解析:
跨了服务(跨了数据库),本地事务失效了。
Seata (AT):帮你自动生成回滚SQL。就是阿里开源,最常用。类似2PC,但
TCC:纯代码控制(Try, Confirm, Cancel)。麻烦,但性能好。
MQ 最终一致性:我这边做完发个消息,你那边慢慢做。做失败了重试。
!!!seata知识点可以参考我之前写的分布式事务Seata也是在csdn上的博客
️ 面试参考回答:
“分布式事务是指在分布式系统中,这就涉及多个服务、多个数据库的一系列操作,要么全部成功,要么全部失败。
常见的解决方案有:
Seata 的 AT 模式(最常用): 它是基于两阶段提交的升级版。无侵入,Seata 会自动生成 UNDO_LOG(回滚日志)。如果事务失败,利用日志自动回滚。
TCC 模式(Try-Confirm-Cancel):需要手动编写 Try(预留资源)、Confirm(确认)、Cancel(取消)三个接口,性能好但代码侵入性大。
MQ 最终一致性:基于消息队列。上游业务执行完发送消息,下游监听消息去执行。如果下游失败则重试,保证最终数据是一致的。适用于高并发但不要求实时一致的场景。”
15. 如何保证接口的幂等性
知识点解析:
幂等 = 同样的请求发N次,效果和发1次一样。(比如扣款,点两次只能扣一次钱)。
数据库:唯一索引(最硬核)。
Token机制:先拿票,进门撕票。没票的不让进。
Redis:存个ID,处理过就别处理了。
️ 面试参考回答:
“保证接口幂等性,防止重复提交,常用的方案有:
Token 机制(推荐):客户端请求业务前先向服务端申请一个 Token,请求时带上这个 Token。服务端收到请求后,校验并删除 Token(这个处理是原子的)。如果 Token 不存在,说明是重复请求,直接拒绝。
数据库唯一索引:比如在数据库表中将订单号设为唯一索引,重复插入会报错,借此保证幂等。
Redis 防重: 将请求的唯一标识(如 RequestId)存入Redis 并设置过期时间。每次请求先检查 Redis 中是否存在该 ID,存在则拦截。”
浙公网安备 33010602011771号