源码路由降级实现逻辑?

访客 源码剖析 1

本文目录导读:

  1. 核心逻辑流程图(通用)
  2. 框架源码中的降级实现逻辑(以 Sentinel 为例)
  3. 另一个常见实现:Hystrix(已进入维护期,但逻辑经典)
  4. 网关层降级(Spring Cloud Gateway)
  5. 降级实现的3个核心模块
  6. 源码阅读建议

“源码路由降级”这个说法,通常是指在微服务架构分布式系统中,当服务调用(RPC/HTTP)发生故障(如超时、异常)时,自动将请求从“真实的服务提供方”切换到“一个备用的、简化逻辑或返回兜底数据的方法”的过程,这里的“源码”可能指代框架源码(如 Spring Cloud、Dubbo、Sentinel)或业务源码

由于问题比较宽泛,我会从通用实现逻辑主流框架(Sentinel、Hystrix、Spring Cloud Gateway) 两个层面来拆解。


核心逻辑流程图(通用)

无论是什么框架,降级的本质都是一个策略拦截器

用户请求 → [过滤器/拦截器] → 判断:是否熔断/降级?
    |
    ├── 否 → 调用真实业务逻辑(真实远程服务/本地方法)
    |        ├── 成功 → 正常返回
    |        └── 失败(超时/异常/错误码) → 触发降级逻辑
    |
    └── 是 → 直接调用降级方法(Fallback方法/兜底数据)

框架源码中的降级实现逻辑(以 Sentinel 为例)

Sentinel 是目前最主流的流量控制/熔断降级组件,其代码实现逻辑非常清晰:

核心骨架:SphU.entry()

当调用一个受保护的资源时,Sentinel 会构建一个责任链(ProcessorSlotChain)。

降级关键类:DegradeSlot

在责任链中,DegradeSlot 负责检查熔断降级,其内部逻辑如下:

  • 获取熔断规则:从规则中心(内存或配置中心)获取当前资源的 DegradeRule
  • 状态机判断
    • CLOSED(关闭):正常放行,每次调用后,记录成功/失败/慢调用次数。
    • OPEN(开启):直接抛出 DegradeException,触发降级,在 open 状态会有一个“半开探测”定时任务。
    • HALF_OPEN(半开):允许一次请求通过,成功则关闭熔断;失败则继续开启。
  • 触发降级
    • getState() == State.OPEN 时,DegradeSlot 直接返回异常,Entry 创建失败。
    • 外层代码捕获异常后,调用预设的 fallback() 方法。

降级方法调用(代码层面)

降级方法通常通过 注解@SentinelResource)或 手动 API 绑定。

// 注解方式(源码中通过 AOP 解析)
@SentinelResource(value = "getUser", 
                  fallback = "getUserFallback", // 降级方法
                  blockHandler = "getUserBlockHandler") // 流量控制方法
public User getUser(String id) {
    // 真实远程调用
    return userService.findById(id);
}
// 降级方法必须与原方法签名一致(或加 BlockException 参数)
public User getUserFallback(String id, Throwable e) {
    return new User("默认用户"); // 兜底数据
}

源码逻辑

  1. AOP 切面拦截 getUser 调用。
  2. 执行 SphU.entry("getUser")
  3. DegradeSlot 报错,捕获 DegradeException
  4. 通过反射调用 getUserFallback 方法。

另一个常见实现:Hystrix(已进入维护期,但逻辑经典)

Hystrix 的降级核心在 HystrixCommandrun()getFallback() 方法中。

源码逻辑:

  1. 执行 run():调用真实服务。
  2. 超时/失败
    • 通过 线程池信号量 隔离,调用 run()
    • 如果超时(Timeout!)、线程池拒绝(ThreadPoolRejected)、执行异常(Failure),进入 getFallback()
  3. 熔断器(CircuitBreaker)
    • 基于滑动窗口统计(10秒内请求失败数超过阈值)。
    • 熔断开启后,isCircuitBreakerOpen() 返回 true,直接跳过 run() 执行 getFallback()
    • 半开状态:允许单个请求探测。
graph TD
    A[请求进入] --> B{Circuit Breaker?};
    B -- Open/半开(半开且非探测请求) --> C[直接调用 getFallback()];
    B -- Closed/半开(探测请求) --> D[尝试调用 run()];
    D --> E{run() 成功?};
    E -- 成功 --> F[返回结果 并 重置计数器];
    E -- 失败/超时/拒绝 --> C;

网关层降级(Spring Cloud Gateway)

在 API 网关层面,降级通常是为某个路由(Route)配置一个 fallback URI

源码逻辑(基于 Spring Cloud Gateway + Hystrix/Sentinel 集成):

  1. 过滤链(Filter Chain)HystrixGatewayFilterSentinelGatewayFilter
  2. 执行转发:向目标服务(如 http://user-service)发起转发。
  3. 异常/超时
    • 转发失败(连接超时、5xx 错误)。
    • 熔断器打开。
  4. 路由重定向
    • 修改请求的 URI 到 forward:/fallbackHandler 或另一个稳定的服务地址。
    • 返回统一错误页面或静态缓存数据。
# 配置示例
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          filters:
            - name: Hystrix
              args:
                name: userFallback
                fallbackUri: forward:/fallback  # 降级后转发到网关本地的 /fallback 端点
          predicates:
            - Path=/api/user/**

降级实现的3个核心模块

  1. 状态判断(熔断器)
    • 基于错误率/慢调用率/异常数(滑动窗口统计)。
    • 三种状态:Closed(关闭)、Open(开启)、Half-Open(半开)。
  2. 隔离机制
    • 线程池隔离(Hystrix):线程池满则降级。
    • 信号量隔离(Sentinel/Hystrix):并发数超限则降级。
  3. 兜底处理(Fallback)
    • 调用完整业务逻辑的失败替代方案。
    • 常见形式:返回缓存数据、默认值、空结果、错误码。

源码阅读建议

如果你想深入学习,建议按以下顺序阅读相关源码:

组件 关键类/包 查看重点
Sentinel DegradeSlot, CircuitBreaker, ExceptionStrategy 状态机转换、滑动窗口、半开逻辑
Hystrix HystrixCommand, HystrixCircuitBreaker, HystrixThreadPool 线程池隔离、熔断器实现
Spring Cloud HystrixGatewayFilter, CachingFallbackFilter 网关层降级路由

如果问题是指“业务代码中手动实现降级”,核心就是 try-catch + 条件判断 + 静态数据缓存,也就是所谓的“手动降级”,这两种方式在架构上原理一致,只是框架帮你封装了状态统计与自动切换的逻辑。

标签: 策略路由

抱歉,评论功能暂时关闭!