Spring Cloud Gateway如何实现熔断

Spring Cloud Gateway熔断集成

熔断应用:

金融市场中的熔断机制:在金融交易系统中,熔断机制(Circuit Breaker)是一种市场保护措施,旨在预防市场剧烈波动时可能导致的系统性风险。当某个基准指数(如股票指数或期货价格)在短时间内发生急剧上涨或下跌达到预先设定的阈值时,交易所会自动暂停交易一段时间或者限制涨跌幅度,类似于电器中的保险丝在电流过载时熔断以切断电流。例如,在美国股市中,曾经存在三级熔断机制,分别在标普500指数下跌7%、13%和20%时触发。

分布式计算中的熔断机制: 在分布式系统或微服务架构中,熔断机制是一种容错设计模式,其目的是防止因依赖的服务出现故障而引发整个系统的雪崩效应。当一个服务调用另一个服务时,如果后者频繁失败或响应时间过长,熔断器组件(如Hystrix、Resilience4j或Alibaba Sentinel)就会"熔断"该调用链路,不再继续请求有问题的服务,而是直接返回预设的错误信息或默认值,同时给调用方提供一个快速的失败反馈,而不是长时间等待或阻塞资源。在后续的一段时间内(冷却期),即使问题服务恢复,熔断器也可能保持打开状态,仅在一段时间后尝试半开状态重新发起调用,以确认服务是否真正恢复正常。这样可以确保整个系统的稳定性,并允许其他健康的服务不受影响地继续运行。
Spring Cloud Gateway 本身并不自带完整的熔断机制,但在早期版本中可以通过集成 Hystrix 来实现服务熔断和降级。然而,随着Hystrix的维护状态变更,社区推荐使用如Resilience4j或Alibaba Sentinel等其他更活跃的容错库。

SpringCloudGateway集成Hystrix实现熔断

第一步添加依赖:

在pom.xml或build.gradle文件中引入Spring Cloud Gateway与Hystrix的相关依赖。

xml 复制代码
 <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
   </dependency>

第二部添加路由配置

在Spring Cloud Gateway配置中添加Hystrix过滤器,并定义相关的路由规则

yaml 复制代码
  spring:
     cloud:
       gateway:
         routes:
           - id: your_route_id
             uri: lb://your_service_id
             predicates:
               - Path=/api/** # 例如,匹配所有/api开头的路径
             filters:
               - name: Hystrix
                 args:
                   name: fallbackcmd
                   fallbackUri: forward:/fallback  # 当熔断发生时转发到的本地fallback处理逻辑

第三步添加回退提示

创建一个Controller或Endpoint来处理当Hystrix触发熔断时的回退操作。

java 复制代码
  @RestController
   public class FallbackController {

       @GetMapping("/fallback")
       public Mono<String> fallback() {
           return Mono.just("Fallback response due to service unavailable.");
       }
   }

第四步添加Hystrix熔断配置

确保Hystrix的全局配置已启用,并根据需要配置熔断阈值、超时时间等参数。

java 复制代码
import com.netflix.hystrix.HystrixCommandProperties;

@Configuration
public class HystrixConfiguration {

    @Bean
    public HystrixCommandProperties.Setter hystrixCommandProperties() {
        return HystrixCommandProperties.Setter()
                .withExecutionTimeoutInMilliseconds(5000) // 设置命令执行超时时间为5秒
                .withCircuitBreakerEnabled(true) // 启用熔断器
                .withCircuitBreakerErrorThresholdPercentage(50) // 当错误率达到50%时触发熔断
                .withCircuitBreakerSleepWindowInMilliseconds(30000); // 熔断后的休眠窗口期为30秒
    }
}
yaml 复制代码
hystrix:
  command:
    default: # 这里是全局默认配置,也可以针对特定命令键做单独配置
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000 # 设置命令执行超时时间为5秒
      circuitBreaker:
        enabled: true # 启用熔断器
        errorThresholdPercentage: 50 # 当错误率达到50%时触发熔断
        sleepWindowInMilliseconds: 30000 # 熔断后的休眠窗口期为30秒

第五步实现熔断逻辑

自定义熔断 Hystrix Gateway Filter来完成熔断逻辑的适配。

java 复制代码
参考
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.exception.HystrixRuntimeException;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

public class HystrixGatewayFilterFactory extends AbstractGatewayFilterFactory<HystrixGatewayFilterFactory.Config> {

    public static class Config {
        // 可配置属性,如命令名称、组键等
        private String commandKey;
        // 其他可能的配置项...

        // 构造函数和getters/setters省略...
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            // 创建Hystrix Command,封装请求处理逻辑
            HystrixCommand<String> command = new HystrixCommand<String>(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(config.getCommandKey()))) {
                @Override
                protected String run() throws Exception {
                    // 执行原始请求并获取响应
                    return chain.filter(exchange).block();
                }

                // 自定义fallback逻辑
                @Override

SpringCloudGateway集成Sentinel实现熔断

第一步配置依赖

xml 复制代码
 <dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-sentinel-gateway</artifactId>
       <version>{latest_version}</version>
   </dependency>
yaml 复制代码
  implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel-gateway:{latest_version}'

第二步配置拦截器

yaml 复制代码
  spring:
     cloud:
       gateway:
         routes:
           - id: your_route_id
             uri: lb://your_service_id
             predicates:
               - Path=/your-api-path/**
             filters:
               - name: SentinelGatewayFilter
                 args:
                   resource: your_api_resource_name
                   limitApp: default # 可选,限制调用来源应用,默认不限制
                   fallbackUri: forward:/fallback  # 可选,设置降级处理逻辑路径

第三步启动sentinel服务

通过 Docker 镜像快速部署 Sentinel 控制台

拉取 Sentinel 控制台镜像: 在终端中运行以下命令从 Docker Hub 拉取最新的 Sentinel 控制台镜像:

powershell 复制代码
docker pull bladex/sentinel-dashboard

运行 Sentinel 控制台容器: 使用以下命令创建并启动一个 Docker 容器,其中 -p 参数用于映射宿主机端口到容器内部的 Sentinel 控制台端口(默认为 8080),--name 参数用于指定容器名称,-d 参数表示在后台运行。

powershell 复制代码
 docker run -d --name sentinel-dashboard -p 8080:8080 bladex/sentinel-dashboard

访问 Sentinel 控制台: Sentinel 控制台服务启动后,可以通过浏览器访问 http://localhost:8080 来登录控制台。默认用户名和密码都是 sentinel。

手动下载编译后的 jar 包运行

下载 Sentinel 控制台 jar 包: 访问 Sentinel GitHub Release 页面 下载最新版本的 sentinel-dashboard.jar 文件。

运行 Sentinel 控制台: 在下载目录下,使用 Java 运行该 jar 包,并指定端口号(例如 8080)

powershell 复制代码
 java -jar sentinel-dashboard.jar --server.port=8080

访问 Sentinel 控制台: 同样地, Sentinel 控制台服务启动后,可以在浏览器中输入 http://localhost:8080 来访问和管理 Sentinel 策略。

配置熔断规则

登录 Sentinel 控制台,为之前定义的资源名称(例如 your_api_resource_name)配置流控、降级、系统保护等策略。

编写降级处理逻辑

如果在配置中指定了 fallbackUri,则需要在服务端实现对应的降级处理逻辑,当触发熔断时将执行这个逻辑。

yaml配置

在 Spring Cloud Gateway 的路由配置中,为 SentinelGatewayFilter 添加 fallbackUri 参数,指定一个本地处理熔断或降级的 URI。

yaml 复制代码
 spring:
     cloud:
       gateway:
         routes:
           - id: your_route_id
             uri: lb://your_service_id
             predicates:
               - Path=/your-api-path/**
             filters:
               - name: SentinelGatewayFilter
                 args:
                   resource: your_api_resource_name
                   fallbackUri: forward:/fallback
具体实现

在您的 Spring Boot 应用中创建一个 Controller 或者 Endpoint 来处理这个 /fallback 请求。

java 复制代码
@RestController
   public class FallbackController {

       @GetMapping("/fallback")
       public Mono<String> fallback(ServerWebExchange exchange) {
           // 这里可以根据需要自定义降级返回的内容
           return Mono.just("Fallback response due to service unavailable.");
       }
   }
相关推荐
弈芯12 小时前
SpringCloud微服务拆分最佳实践
spring cloud
麦兜*20 小时前
【Prometheus】 + Grafana构建【Redis】智能监控告警体系
java·spring boot·redis·spring·spring cloud·grafana·prometheus
sniper_fandc2 天前
Spring Cloud系列—SkyWalking告警和飞书接入
spring cloud·skywalking
abigalexy2 天前
深入图解Spring Cloud底层设计
spring·spring cloud
楠有枝4 天前
普通用户使用docker命令
spring cloud·docker·eureka
孤狼程序员4 天前
【Spring Cloud 微服务】2.守护神网关Gateway
spring cloud·微服务·gateway
朱皮皮呀4 天前
Spring Cloud——服务注册与服务发现原理与实现
运维·spring cloud·eureka·服务发现·php
朱皮皮呀5 天前
微服务流量分发核心:Spring Cloud 负载均衡解析
spring cloud·微服务·负载均衡
源码宝6 天前
【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
java·大数据·spring cloud·数据分析·源码·智慧工地·云平台
2301_793086876 天前
SpringCloud 07 微服务网关
java·spring cloud·微服务