spring cloud gateway限流常见算法实现

 更新时间:2025年02月21日 09:08:01   作者:敲代码的小王!  
本文主要介绍了spring cloud gateway限流常见算法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言:

我们在很多时候应该会遇到一种情况吧,比如说某些秒杀类型的商品在抢购的时候,你明显的感觉到这种情况,再例如大学生们应该都经历过的一件事,那就是每个学期必须经历的选课,每当选课开始的时候是不是总会刷新的时候一直进不去,这也是做了限流的原因。

一、网关限流

1、限流的作用

1. 保护后端服务

网关限流可以有效地控制进入系统的请求流量,避免后端服务因接收到过多的请求而过载或者崩溃。特别是在高并发场景下,后端系统的处理能力可能有限,限流可以确保请求不会超出后端服务的最大承载能力。

2. 保证服务质量 (QoS)

通过限流,网关可以确保所有用户或请求都有公平的机会访问系统资源,避免某些用户或请求因过度占用系统资源而影响其他正常用户的体验。限流有助于平衡系统负载,避免部分突发请求导致服务质量下降。

3. 避免滥用和恶意攻击

限流能够有效防止恶意用户或爬虫等非正常流量对系统的恶意攻击。比如,针对DDoS攻击(分布式拒绝服务)或暴 力 破 解等恶意流量,网关通过限流可以限制每个IP或者每个用户的请求次数,从而防止系统被过载。

4. 减少资源浪费

如果没有限流,过多的请求可能会让系统资源(如CPU、内存、数据库连接等)处于超负荷状态,导致资源浪费或者资源耗尽。限流可以合理地限制请求数量,确保系统资源被有效利用,而不是被不必要的请求耗尽。

5. 提高系统可扩展性和稳定性

通过合理配置限流策略,网关能够帮助系统平衡流量,确保系统稳定运行,避免因负载过高而发生宕机或性能瓶颈。通过动态调整限流策略,还可以应对不同流量波动,提高系统的可扩展性。

6. 控制不同用户的访问频率

网关可以根据不同用户、IP地址或者API接口的不同需求配置不同的限流规则。比如,可以为VIP用户提供更高的请求频率限制,而普通用户则可以设置更严格的限流规则。这有助于实现服务质量差异化管理。

7. 提升用户体验

通过限流,可以避免系统在流量高峰期间过载导致的请求失败、响应延迟等问题,从而提升用户的体验。当系统能够持续稳定响应用户请求时,用户满意度会提高,且系统负载能够保持在合理范围。

8. 避免API滥用和负载过高

尤其在微服务架构中,API网关起到至关重要的作用。通过限流,API网关能够控制每个API接口的访问频率,防止某个API接口被频繁调用导致的性能问题,确保整个系统的API接口资源合理分配。

9. 监控与分析

限流机制还可以作为监控的一部分,帮助运营人员分析请求模式。通过记录哪些请求被限流,系统可以更好地了解哪些用户或哪些功能区域的负载较高,进而优化系统架构或流量分配。

10. 避免系统崩溃

如果网关不进行限流,系统在高并发流量下可能会因承载过多请求而崩溃,导致不可用。通过提前限制请求流量,网关可以有效避免这种情况,保持系统稳定运行。

2、网关限流的常见算法

1. 令牌桶算法 (Token Bucket)

令牌桶算法是最常见的限流算法之一,它通过控制请求的速率来实现限流。

  • 工作原理:令牌桶会以固定的速率生成令牌,每当一个请求到达时,网关会检查桶中是否有令牌。如果有,则允许请求通过,并且从桶中消耗一个令牌;如果没有,则请求被拒绝或者等待令牌的生成。
  • 优点:允许请求的突发流量,因为令牌桶可以存储令牌,支持请求的突发。
  • 适用场景:适用于那些偶尔有突发流量的应用,比如API接口。

2. 漏桶算法 (Leaky Bucket)

漏桶算法也常用于限流,其基本思想是控制流量的平均速率。

  • 工作原理:漏桶算法使用一个固定大小的桶,当请求到达时,如果桶中有空间,则请求可以进入桶中;如果桶已经满了,则新的请求会被丢弃。请求从桶中以固定速率“漏出”。
  • 优点:防止突发流量导致系统过载,保证请求的流量是平稳的。
  • 适用场景:适用于希望平滑流量,避免突发流量影响系统的场景。

3. 计数器算法 (Counter-based)

计数器算法通过对请求计数并进行周期性重置来实现限流。

  • 工作原理:每次接收到请求时,都会增加一个计数器的值,当计数器达到预设的限制时,新的请求将被拒绝。计数器会在一段时间后(如每秒、每分钟)被重置为零。
  • 优点:简单易实现。
  • 缺点:可能存在短时间内请求数过多的问题,特别是在请求突发时。

3、令牌桶算法在gateway中的具体实现

spring cloud gateway 默认使用redis的RateLimter限流算法来实现。所以我们要使用首先需要引入redis的依赖。

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

在GatewayApplicatioin引导类中添加如下代码,KeyResolver用于计算某一个类型的限流的KEY也就是说,可以通过KeyResolver来指定限流的Key。

//定义一个KeyResolver
    @Bean
    public KeyResolver ipKeyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
            }
        };
    }

修改application.yml中配置项,指定限制流量的配置以及REDIS的配置

spring:
  cloud:
    gateway:
      routes:
      - id: goods
        uri: lb://goods
        predicates:
        - Path=/goods/**
        filters:
        - StripPrefix= 1
        - name: RequestRateLimiter #请求数限流 名字不能随便写 
          args:
            key-resolver: "#{@ipKeyResolver}"
            redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
            redis-rate-limiter.burstCapacity: 1 #令牌桶总容量
  redis:
    host: 192.168.200.128 #自己redis的ip和端口以及密码配置
    port: 6379

解释:

  • burstCapacity:令牌桶总容量。
  • replenishRate:令牌桶每秒填充平均速率。
  • key-resolver:用于限流的键的解析器的 Bean 对象的名字。它使用 SpEL 表达式根据#{@beanName}从 Spring 容器中获取 Bean 对象。

通过在replenishRate和中设置相同的值来实现稳定的速率burstCapacity。设置burstCapacity高于时,可以允许临时突发replenishRate。在这种情况下,需要在突发之间允许速率限制器一段时间(根据replenishRate),因为2次连续突发将导致请求被丢弃(HTTP 429 - Too Many Requests)key-resolver: "#{@userKeyResolver}" 用于通过SPEL表达式来指定使用哪一个KeyResolver.

如上配置:

表示 一秒内,允许 一个请求通过,令牌桶的填充速率也是一秒钟添加一个令牌。最大突发状况 也只允许 一秒内有一次请求,可以根据业务来调整 。

在做好以上的所有配置之后,当你再次访问具体的微服务的时候,如果你访问的请求超过了每秒1个的速度,那么你就会被限流,页面会显示429错误。如图所示:

到此这篇关于spring cloud gateway限流常见算法实现的文章就介绍到这了,更多相关spring cloud gateway限流内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中关于优先队列PriorityQueue的使用及相关方法

    Java中关于优先队列PriorityQueue的使用及相关方法

    这篇文章主要介绍了Java中关于优先队列PriorityQueue的使用及相关方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • SkyWalking 自定义插件(Spring RabbitMQ)具体分析过程

    SkyWalking 自定义插件(Spring RabbitMQ)具体分析过程

    这篇文章主要介绍了SkyWalking 自定义插件(Spring RabbitMQ)具体分析过程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • JDK9的新特性之String压缩和字符编码的实现方法

    JDK9的新特性之String压缩和字符编码的实现方法

    这篇文章主要介绍了JDK9的新特性之String压缩和字符编码的实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • 掌握模块化开发Spring Boot子模块使用技巧

    掌握模块化开发Spring Boot子模块使用技巧

    这篇文章主要为大家介绍了掌握模块化开发Spring Boot子模块使用技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Java 替换字符串右侧出现的第一个子串方式

    Java 替换字符串右侧出现的第一个子串方式

    这篇文章主要介绍了Java 替换字符串右侧出现的第一个子串方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Dubbo+Nacos服务启动报错,返回unknown user的问题

    Dubbo+Nacos服务启动报错,返回unknown user的问题

    这篇文章主要介绍了Dubbo+Nacos服务启动报错,返回unknown user的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • MyBatis-Plus非表字段的三种处理方法小结

    MyBatis-Plus非表字段的三种处理方法小结

    这篇文章主要介绍了MyBatis-Plus非表字段的三种处理方法小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • Jdbctemplate多数据源配置方法详解

    Jdbctemplate多数据源配置方法详解

    这篇文章主要介绍了Jdbctemplate多数据源配置方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java数据结构最清晰图解二叉树前 中 后序遍历

    Java数据结构最清晰图解二叉树前 中 后序遍历

    树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示
    2022-01-01
  • Java解释器的运行过程介绍

    Java解释器的运行过程介绍

    今天小编就为大家分享一篇关于Java解释器的运行过程介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04

最新评论