SpringCloud 限流、熔断、降级的区别及实现

 更新时间:2025年03月12日 10:11:21   作者:power-辰南  
本文主要介绍了SpringCloud 限流、熔断、降级的区别及实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

在微服务架构中,Spring Cloud 提供了一系列的工具和技术来保障系统的稳定性和可靠性。其中,限流、熔断和降级是三个重要的概念,它们在不同的场景下发挥着关键作用。本文将详细介绍 Spring Cloud 中限流、熔断和降级的区别,并探讨它们的具体实现方式。

一、限流、熔断、降级的概念

(一)限流

限流是指在一段时间内,限制系统能够处理的请求数量,以防止系统因过多的请求而崩溃。限流可以有效地保护系统的资源,确保系统在高负载情况下仍然能够正常运行。

例如,一个电商网站在促销活动期间,可能会面临大量的用户请求。如果不进行限流,系统可能会因为无法处理这么多请求而崩溃,导致用户无法访问网站。通过限流,可以限制每秒能够处理的请求数量,确保系统不会被过多的请求压垮。

(二)熔断

熔断是指在系统出现故障或异常情况时,自动切断对故障服务的调用,以防止故障扩散。当系统检测到某个服务出现故障时,会立即停止对该服务的调用,并返回一个预设的错误响应。这样可以避免因一个服务的故障而影响整个系统的稳定性。

例如,一个微服务架构中的订单服务依赖于支付服务。如果支付服务出现故障,订单服务在调用支付服务时会一直等待,导致订单服务也无法正常工作。通过熔断机制,订单服务可以在检测到支付服务故障时,立即停止调用支付服务,并返回一个“支付服务暂时不可用”的错误响应,从而避免影响用户的下单体验。

(三)降级

降级是指在系统出现故障或高负载情况下,降低系统的功能或性能,以保证系统的核心功能能够正常运行。降级可以是主动的,也可以是被动的。主动降级是指在系统设计时就考虑到可能出现的故障情况,并提前制定好降级策略。被动降级是指在系统出现故障时,根据实际情况临时采取的降级措施。

例如,一个在线教育平台在高负载情况下,可能会出现视频播放卡顿的情况。为了保证用户能够正常学习,可以采取降级措施,将视频的清晰度降低,或者暂停一些非核心功能,如在线讨论等,以保证视频播放的流畅性。

二、限流、熔断、降级的区别

(一)目的不同

  • 限流:主要目的是限制系统的请求数量,防止系统因过多的请求而崩溃,保护系统的资源。
  • 熔断:主要目的是在系统出现故障时,自动切断对故障服务的调用,防止故障扩散,保证系统的稳定性。
  • 降级:主要目的是在系统出现故障或高负载情况下,降低系统的功能或性能,保证系统的核心功能能够正常运行。

(二)触发条件不同

  • 限流:通常是在系统负载达到一定程度时触发,例如每秒请求数量超过了系统的处理能力。
  • 熔断:通常是在系统检测到某个服务出现故障时触发,例如服务响应时间过长、服务抛出异常等。
  • 降级:可以在系统出现故障、高负载、资源紧张等情况下触发。

(三)处理方式不同

  • 限流:通过限制请求数量来保护系统,可能会拒绝部分请求,或者将请求放入队列中等待处理。
  • 熔断:自动切断对故障服务的调用,返回预设的错误响应。
  • 降级:降低系统的功能或性能,例如降低服务的质量、暂停一些非核心功能等。

三、Spring Cloud 限流的实现方式

(一)Guava RateLimiter

Guava RateLimiter 是 Google Guava 库提供的一种限流工具。它基于令牌桶算法实现,可以限制每秒能够处理的请求数量。

使用 Guava RateLimiter 的步骤如下:

  • 在项目中引入 Google Guava 库的依赖。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
  • 创建 RateLimiter 对象,并设置每秒能够处理的请求数量。
import com.google.common.util.concurrent.RateLimiter;
public class RateLimiterExample {
public static void main(String[] args) {
// 创建一个每秒能够处理 10 个请求的 RateLimiter 对象
RateLimiter rateLimiter = RateLimiter.create(10);
// 模拟请求处理
for (int i = 0; i < 20; i++) {
if (rateLimiter.tryAcquire()) {
// 处理请求
System.out.println("处理请求 " + i);
} else {
// 请求被限流
System.out.println("请求 " + i + " 被限流");}
       }
  }
}

(二)Spring Cloud Gateway 限流

Spring Cloud Gateway 是 Spring Cloud 提供的一个 API 网关,可以实现请求的路由、过滤和限流等功能。

使用 Spring Cloud Gateway 限流的步骤如下:

  • 在项目中引入 Spring Cloud Gateway 的依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  • 在配置文件中配置限流规则。
spring:
cloud:
gateway:
routes:
- id: myroute
uri: http://localhost:8080
predicates:
- Path=/myapi/**
filters:
- name: RequestRateLimiter
args:
key-resolver: '#{@pathKeyResolver}'
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20

在上面的配置中,我们使用了 Redis 作为限流的存储介质,并设置了每秒能够处理的请求数量为 10,突发容量为 20。

  • 创建 KeyResolver 接口的实现类,用于确定限流的键。
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimitConfig {
@Bean
public KeyResolver pathKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().toString());
   }
}

在上面的代码中,我们创建了一个 KeyResolver 接口的实现类,用于根据请求的路径确定限流的键。

四、Spring Cloud 熔断的实现方式

(一)Hystrix

Hystrix 是 Netflix 开源的一个库,用于实现服务的熔断、降级和隔离等功能。它通过断路器模式来实现熔断功能,当服务出现故障时,断路器会自动打开,阻止对故障服务的调用,直到服务恢复正常。

使用 Hystrix 的步骤如下:

在项目中引入 Hystrix 的依赖。

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

在服务方法上添加 @HystrixCommand 注解,并指定熔断后的回调方法。

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
@Service
public class MyService {
@HystrixCommand(fallbackMethod = "fallbackMethod")
public String myMethod() {
// 调用远程服务或执行其他可能出现故障的操作
return "正常响应";
}
public String fallbackMethod() {
// 熔断后的回调方法
return "服务不可用,请稍后再试";
  }
}

在上面的代码中,我们在 myMethod 方法上添加了 @HystrixCommand 注解,并指定了熔断后的回调方法 fallbackMethod。当 myMethod 方法执行出现故障时,会自动调用 fallbackMethod 方法返回预设的错误响应。

(二)Resilience4j

Resilience4j 是一个轻量级的容错库,提供了熔断、重试、限速等功能。它的设计理念与 Hystrix 类似,但更加简洁和灵活。

使用 Resilience4j 的步骤如下:

在项目中引入 Resilience4j 的依赖。

<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.7.1</version>
</dependency>

在服务方法上添加 @CircuitBreaker 注解,并指定熔断后的回调方法。

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
@Service
public class MyService {
@CircuitBreaker(name = "myCircuitBreaker", fallbackMethod = "fallbackMethod")
public String myMethod() {
// 调用远程服务或执行其他可能出现故障的操作
return "正常响应";
}
public String fallbackMethod() {
// 熔断后的回调方法
return "服务不可用,请稍后再试";
  }
}

在上面的代码中,我们在 myMethod 方法上添加了 @CircuitBreaker 注解,并指定了熔断后的回调方法 fallbackMethod。当 myMethod 方法执行出现故障时,会自动调用 fallbackMethod 方法返回预设的错误响应。

五、Spring Cloud 降级的实现方式

(一)Hystrix 降级

在使用 Hystrix 实现熔断的同时,也可以实现降级功能。在熔断后的回调方法中,可以返回一个预设的降级响应,或者执行一些降级逻辑,如从缓存中获取数据等。

例如,在上面的 Hystrix 示例中,fallbackMethod 方法就是一个降级方法,当服务出现故障时,会返回一个预设的错误响应。

(二)Spring Cloud 自定义降级逻辑

除了使用 Hystrix 提供的降级功能外,还可以在 Spring Cloud 中自定义降级逻辑。可以通过实现 FallbackFactory 接口来创建自定义的降级方法。

使用自定义降级逻辑的步骤如下:

创建一个实现 FallbackFactory 接口的类,并实现 create 方法。

import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class MyServiceFallbackFactory implements FallbackFactory<MyService> {
@Override
public MyService create(Throwable cause) {
return new MyService() {
@Override
public String myMethod() {
// 自定义降级逻辑
return "服务不可用,请稍后再试";
         }
     };
  }
}

在 Feign 客户端接口上指定降级工厂类。

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "myService", fallbackFactory = MyServiceFallbackFactory.class)
public interface MyFeignClient {
@GetMapping("/myapi")
String myMethod();
}

在上面的代码中,我们创建了一个实现 FallbackFactory 接口的类 MyServiceFallbackFactory,并在 create 方法中实现了自定义的降级逻辑。然后,在 Feign 客户端接口上指定了降级工厂类为 MyServiceFallbackFactory.class。当服务出现故障时,会自动调用降级工厂类中的 create 方法创建一个降级对象,并执行降级对象中的 myMethod 方法返回预设的降级响应。

六、总结

限流、熔断和降级是微服务架构中保障系统稳定性和可靠性的重要手段。它们在不同的场景下发挥着不同的作用,但目的都是为了确保系统能够在各种情况下正常运行。

在 Spring Cloud 中,可以使用 Guava RateLimiter、Spring Cloud Gateway 等实现限流功能;使用 Hystrix、Resilience4j 等实现熔断功能;使用 Hystrix 提供的降级方法或自定义降级逻辑实现降级功能。在实际应用中,可以根据具体的需求选择合适的实现方式,并结合监控和报警系统,及时发现和处理系统中的问题,保障系统的稳定运行。

到此这篇关于SpringCloud 限流、熔断、降级的区别及实现的文章就介绍到这了,更多相关SpringCloud限流、熔断、降级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中的分布式事务解决方式

    java中的分布式事务解决方式

    分布式事务是分布式系统中确保数据一致性的重要机制,它涉及多个数据源或参与者,要么所有操作全部成功,要么全部失败,常见的解决方案包括2PC(两阶段提交协议)、3PC(三阶段提交协议)和TCC(Try-Confirm-Cancel),2PC虽然简单但存在单点故障等问题
    2024-09-09
  • Java前端实现发送date类型的参数给后端

    Java前端实现发送date类型的参数给后端

    这篇文章主要介绍了Java前端实现发送date类型的参数给后端方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Spring中@RequestMapping、@RestController和Postman

    Spring中@RequestMapping、@RestController和Postman

    本文介绍了Spring框架中常用的@RequestMapping和@RestController注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • java之向linux文件夹下写文件无权限的问题

    java之向linux文件夹下写文件无权限的问题

    这篇文章主要介绍了java之向linux文件夹下写文件无权限的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • 并发编程之Java内存模型顺序一致性

    并发编程之Java内存模型顺序一致性

    这篇文章主要介绍了并发编程Java内存模型顺序一致性,顺序一致性内存模型是一个理论参考模型,处理器的内存模型和编程语言的内存模型都会以顺序一致性内存模型作为参照,下面我们一起进入文章看看学校内容,需要的朋友可以参考一下
    2021-11-11
  • Java实现聊天室界面

    Java实现聊天室界面

    这篇文章主要为大家详细介绍了Java实现聊天室界面,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java中final与继承操作实例分析

    Java中final与继承操作实例分析

    这篇文章主要介绍了Java中final与继承操作,结合实例形式分析了Java中使用final阻止继承的相关原理与操作注意事项,需要的朋友可以参考下
    2019-09-09
  • Mybatis常用标签整理

    Mybatis常用标签整理

    日常开发中,MyBatis中标签有着举足轻重的重要性,以下是一些MyBatis框架中常见的标签及案例,感兴趣的朋友跟随小编一起看看吧
    2007-02-02
  • SpringBoot实现轻量级动态定时任务管控及组件化的操作步骤

    SpringBoot实现轻量级动态定时任务管控及组件化的操作步骤

    文章介绍了一种在SpringBoot中实现动态定时任务的解决方案,基于COLA架构理论,封装到了组件层,该组件支持类级别和方法级别的定时任务注册,并提供了易用性和扩展性,组件使用Maven形式引入,并且可以通过YAML配置文件进行设置,感兴趣的朋友一起看看吧
    2024-11-11
  • Java通过正则表达式获取字符串中数字的方法示例

    Java通过正则表达式获取字符串中数字的方法示例

    最近工作中遇到了一个需求,需要利用java获取字符串中的数字,尝试几种方法后发现利用正则表达式实现最为方法,下面这篇文章就主要介绍了Java通过正则表达式获取字符串中数字的方法,文中给出了详细的示例代码,需要的朋友可以参考下。
    2017-03-03

最新评论