Home
avatar

.𝙃𝙤𝙬𝙚

向下滚动

Spring Cloud 与微服务|java知识点

服务注册与发现

在微服务架构中,服务之间通信需要知道对方的地址和健康状态。服务注册与发现机制解决了这个问题:

  • 注册:微服务启动后,将自己的信息(服务名、IP、端口等)发送到注册中心(如 Nacos、Eureka)。注册中心收到后将该服务上线,并开启心跳检测。
  • 发现:当微服务需要调用其他服务时,从注册中心获取目标服务的实例列表,通过负载均衡选择一个实例进行调用。
  • 心跳检测:注册中心通过心跳机制持续监测服务健康状态。如果某个服务长时间不应答,注册中心会将其下线。心跳时间不宜过快(增加资源消耗)也不宜过慢(不能及时发现故障),剔除时间通常比心跳时间长,允许丢失几次心跳才判定下线。
  • 动态扩缩容:服务可以动态注册和注销实例,实现水平扩缩容。

消费者如何获取服务列表

服务消费者启动时从注册中心拉取一份服务列表并缓存到本地。后续通过长连接(如 WebSocket)接收增量更新,同时还有定时刷新作为兜底。调用时直接从本地缓存获取实例列表,通过负载均衡算法选择实例发起请求,整个调用过程不经过注册中心。

CP 与 AP 模式

根据 CAP 定理,分布式系统在分区容错性(P)的前提下,只能在一致性(C)和可用性(A)之间二选一:

  • CP 模式(强一致性):保证数据一致,但可能在某些时刻拒绝服务。适合对数据一致性要求高的场景,如数据库操作、消息队列的元数据管理。
  • AP 模式(高可用性):保证服务可用,允许短暂的数据不一致。大多数微服务场景选择 AP 模式,因为只有服务高可用,才能保证整个调用链的正常工作。

Nacos 同时支持 CP 和 AP 两种模式:临时实例走 AP(Distro 协议),持久实例走 CP(Raft 协议),开发者可根据业务场景选择。

OpenFeign 远程调用

OpenFeign 是 Spring Cloud 中声明式的 HTTP 客户端,使用流程:

  1. 通过 @FeignClient 注解声明目标服务的接口。
  2. 调用时,Feign 通过动态代理拦截接口方法调用,构建 HTTP 请求。
  3. 从本地缓存的服务列表中,通过负载均衡算法选择一个目标实例。
  4. 发送 HTTP 请求并处理响应。

整个调用过程中注册中心不参与,它只是在服务启动时提供服务列表。负载均衡默认使用轮询算法,可以通过配置更换为随机、加权等策略。

Spring Cloud Gateway

Gateway 是 Spring Cloud 的 API 网关,核心能力包括路由转发、负载均衡、限流、鉴权等。

过滤器机制

Gateway 的过滤器通过 order 值确定执行顺序,数字越小越靠前:

  • 路由过滤器(Route Filter):针对特定路由的过滤器,负责请求转发、URL 重写、Header 处理等。
  • 全局过滤器(Global Filter):对所有请求生效,可实现限流、熔断、鉴权、日志记录等功能。
  • 默认过滤器(Default Filter):对所有路由生效的过滤器。

Gateway 过滤器的本质是责任链 + WebFlux 异步流式调用。请求进入网关后,依次经过 Pre 过滤器(前置处理)→ 路由转发 → 目标服务处理 → Post 过滤器(后置处理)→ 返回客户端。这种设计保证了良好的扩展性和非阻塞性能。

网关限流

限流是为了防止过多请求对服务造成压力,保障服务高可用。常见的限流算法:

  • 计数器:最简单的限流方式,请求进来时计数器加一,达到阈值后直接拒绝。实现简单但存在临界突变问题。
  • 漏桶算法:以固定速率处理请求,超出速率的请求在队列中排队。请求平滑但无法应对突发流量。
  • 令牌桶算法:以固定速率生成令牌,请求需要获取令牌才能通过。支持一定程度的突发流量,是最常用的算法。

分布式场景下,多个网关节点需要借助外部组件实现全局限流,常见方案有 Redis + Lua 脚本、ZooKeeper 等。

常见网关限流实现差异

方案原理优势适用场景
Nginx + limit_req漏桶算法高性能、无需额外组件入口层粗粒度限流
Gateway + RequestRateLimiter令牌桶 + Redis与 Spring 生态集成好网关层精确限流
Sentinel滑动窗口 + 集群流控支持熔断降级一体化复杂微服务治理
Redis + Lua自定义算法灵活性最高自定义限流策略

分布式事务

单体应用的事务只能保证本地数据一致性。在微服务架构中,一个业务操作可能跨越多个服务和数据库,传统事务无法保证跨服务一致性,需要引入分布式事务方案。

常见分布式事务方案

方案原理一致性性能适用场景
2PC(两阶段提交)准备阶段 + 提交阶段强一致低(阻塞)数据库层面,强一致要求
TCC(Try-Confirm-Cancel)业务层面三阶段最终一致中业务侵入性强,适合核心链路
Saga正向操作 + 补偿操作最终一致高长事务、跨多服务
本地消息表本地事务 + 消息投递最终一致高异步场景
RocketMQ 事务消息半消息 + 回查最终一致高消息驱动的业务

幂等设计

幂等性是指同一个操作不管执行多少次,结果都是一致的。在微服务中,由于网络重试、消息重投等原因,同一个请求可能被重复发送,幂等设计可以防止重复扣款、重复消费等问题。

常见的幂等实现方式:

  • 请求唯一 ID:每次请求携带唯一 ID,服务端先检查是否已处理。
  • 分布式锁:对相同业务 key 加锁,防止并发重复执行。
  • 数据库唯一索引:利用数据库的唯一约束防止重复插入。
  • Redis 前置过滤:在 Redis 中记录已处理的请求 ID,快速过滤重复请求。高并发场景下 Redis 做前置过滤,数据库做最终一致性保障。

服务雪崩、熔断与降级

服务雪崩

服务雪崩是指某个服务因大量请求或热点数据而响应变慢甚至下线,导致调用它的上游服务线程阻塞,进而引发连锁反应,整个调用链大面积不可用。例如秒杀场景中,支付服务变慢导致订单、库存、消息等一系列服务阻塞。

熔断

熔断机制类似电路中的保险丝:当某个服务的错误率或响应时间超过阈值时,自动”熔断”对该服务的调用,直接返回错误或降级结果,避免持续调用加剧故障。熔断器通常有三种状态:关闭(正常调用)、打开(直接拒绝)、半开(试探性放行部分请求)。

降级

降级是在系统压力过大时,将非核心服务降级到备用逻辑(如返回排队页面、缓存数据、默认值),保障核心链路可用。降级可以是自动触发(达到阈值)或手动开关。

秒杀系统综合设计

设计一个微服务秒杀系统,需要综合考虑以下方面:

高可用架构:

  • 选择 AP 模式的注册中心,尽可能水平扩展各服务节点。
  • 各个链路节点保持多实例部署,消除单点故障。

防止超卖:

  • 使用分布式锁(Redis 或 ZooKeeper)保证库存扣减的原子性。
  • Redis 预扣库存,异步消息通知数据库最终扣减。

链路保护:

  • 在网关层添加限流,防止超量请求进入后端服务。
  • 对核心链路添加熔断和降级,非核心操作(如发短信、记录日志)快速失败。

异步削峰:

  • 使用消息队列将耗时操作(如扣款、发短信、订单入库)异步化。
  • 设置请求队列,将同步操作转化为异步处理,削平流量峰值。

数据一致性:

  • 使用分布式事务(如 RocketMQ 事务消息或 TCC)保证扣库存和创建订单的原子性。
  • 引入幂等设计,防止消息重复消费导致的数据错误。

用户体验:

  • 服务降级时返回排队提示或友好错误页面。
  • 请求结果通过轮询或 WebSocket 推送,避免长连接阻塞。

本文内容整理自 Spring Cloud 与微服务学习笔记,涵盖服务注册发现、OpenFeign、Gateway、限流、分布式事务、幂等和熔断降级等核心知识点。

java知识点 Java Spring Cloud 微服务