springCloud 网关限流算法-16

x目录

一,漏桶算法

二,令牌桶算法

 三,基于Filter的限流

        3.1 环境搭建

        3.2 启动redis

3.3 配置KeyResolver

3.4 测试


一,漏桶算法

漏桶算法可以很好地限制容量池的大小,从而防止流量暴增。漏桶可以看作是一个带有常量服务时间的 单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。 在网络中,漏桶算法可以控制端口的 流量输出速率,平滑网络上的突发流量,实现流量整形,从而为网络提供一个稳定的流量。

为了更好的控制流量,漏桶算法需要通过两个变量进行控制:一个是桶的大小,支持流量突发增多时可 以存多少的水(burst),另一个是水桶漏洞的大小(rate)。

漏桶算法可以限制请求速度

二,令牌桶算法

        令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用 的平均速率的同时还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令 牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令 牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。放令牌这个动作是持续不断的 进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这 时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就 已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时 的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。

 三,基于Filter的限流

        SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂 RequestRateLimiterGatewayFilterFactory 实现。在过滤器工厂中是通过Redis和lua脚本结合的方 式进行流量控制。

        3.1 环境搭建

                在springCloud getway 模块 导入redis 依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--监控依赖-->
        <!--<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>-->
        <!--redis 依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>

    </dependencies>

        3.2 启动redis

        启动redis ,并且点击redis -cli.exe 文件,后,输入monitor,就可以开启redis 监听,当我们访问接口时,有监听了才是正常的,不然启动网关限流无效。

        修改application.yml配置文件,在application.yml配置文件中加入限流的配置,代码如下:

server:
  port: 8080 #端口
spring:
  application:
    name: api-gateway-server #服务名称
  redis:
    host: localhost
    pool: 6379
    database: 0
  cloud: #配置SpringCloudGateway的路由
    gateway:
      routes:
        - id: service-product
          uri: lb://service-product
          predicates:
            - Path=/service-product/**
          filters:
            - name: RequestRateLimiter
              args:
                # 使用SpEL从容器中获取对象
                key-resolver: '#{@pathKeyResolver}'
                # 令牌桶每秒填充平均速率
                redis-rate-limiter.replenishRate: 1
                # 令牌桶的上限
                redis-rate-limiter.burstCapacity: 3
            - RewritePath=/service-product/(?<segment>.*), /$\{segment}
#eureka注册中心
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9003/eureka/
  instance:
    prefer-ip-address: true #使用ip地址注册

在 application.yml 中添加了redis的信息,并配置了RequestRateLimiter的限流过滤器:

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

3.3 配置KeyResolver,基于请求路径的限流

为了达到不同的限流效果和规则,可以通过实现 KeyResolver 接口,定义不同请求类型的限流键。

@Configuration
public class KeyResolverConfiguration {
    /**
     * 基于请求路径的限流
     */
    @Bean
    public KeyResolver pathKeyResolver() {
        return new KeyResolver() {
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getPath().toString());
            }
        };
    }

}

3.4 测试

这个时候,依赖,配置文件,网关filter 都准备好了,重启gateway 模块,疯狂点击通过网关服务请求的接口,如:http://localhost:8080/service-product/product/1,会出现

 及为生效。

3.5  基于参数的限流

        3.5.1 在限流的配置文件里添加如下代码

 /**
     * 
     * 基于用户的限流 
     * */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest().getQueryParams().getFirst("user")
        );
    }
package com.zjk.gateway.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class KeyResolverConfiguration {
    /**
     * 基于请求路径的限流
     */
    @Bean
    public KeyResolver pathKeyResolver() {
        return new KeyResolver() {
            public Mono<String> resolve(ServerWebExchange exchange) {
                return Mono.just(exchange.getRequest().getPath().toString());
            }
        };
    }

    /**
     *
     * 基于用户的限流
     * */
    @Bean
    public KeyResolver userKeyResolver() {
        return exchange -> Mono.just(
                exchange.getRequest().getQueryParams().getFirst("user")
        );
    }
}

3.5.2 修改gateway 模块配置文件

修改成和上面定义的bean 同样的对象 

 

 并且把pathKeyResolver 注释掉

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vegetari

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值