SpringCloudGateway核心过滤器之请求限流详解-创新互联

环境:SpringBoot2.4.13 + Spring Cloud Gateway3.0.1

创新互联专注于长宁企业网站建设,响应式网站建设,电子商务商城网站建设。长宁网站建设公司,为长宁等地区提供建站服务。全流程定制网站制作,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务
概述

RequestRateLimiter GatewayFilter工厂使用一个RateLimiter实现来确定当前请求是否允许继续。如果不是,返回HTTP 429 - Too Many Requests(默认情况下)的状态。

该过滤器接受一个可选的keyResolver参数和特定于速率限制器的参数。该参数的作用就是用来根据你设定的规则生成key,比如在redis中使用什么key。

keyResolver是一个实现KeyResolver接口的bean。在配置中,使用SpEL按名称引用bean。#{@userKeyResolver}是一个SpEL表达式,它引用了一个名为userKeyResolver的bean。KeyResolver接口如下所示:

public interface KeyResolver {

	Monoresolve(ServerWebExchange exchange);

}

默认情况下,如果KeyResolver没有找到key,请求将被拒绝。你可以通过设置
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true或false)和spring.cloud.gateway.filter.request-rate- limititer来调整这种行为。empty-key-status-code属性。

注意:RequestRateLimiter不能用“快捷方式”表示法进行配置。以下示例无效:

# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
使用Redis限流

Redis的实现是基于Stripe所做的工作。它需要使用
spring-boot-starter-data-redis-reactive Spring Boot Starter。使用的算法是令牌桶算法。

计数器算法:有时间临界问题。

漏桶算法: 速率固定,有浪费资源问题。

配置属性说明:

redis-rate-limiter.replenishRate
允许用户在不丢弃任何请求的情况下每秒执行多少请求。这是令牌桶被填充的速率。
redis-rate-limiter.burstCapacity
允许用户在一秒钟内执行的大请求数。这是令牌桶可以容纳的令牌数量。将该值设置为零将阻止所有请求。
redis-rate-limiter.requestedTokens
一个请求花费多少令牌。这是为每个请求从桶中提取令牌的数量,默认为1。
  1. 一个稳定的速率是通过设置相同的值replenishRate和burstCapacity。
  2. 可以通过将burstCapacity设置为高于replenishRate来允许临时突发。

速率限制器需要在突发之间留出一段时间(根据replenishRate补发率),因为两个连续的爆发将导致丢弃的请求(HTTP 429 - Too Many requests)。

低于1个请求/秒的速率限制是通过以下方式实现的:将replenishRate设置为所需的请求数量,将requestedTokens设置为以秒为单位的时间跨度,将burstCapacity设置为replenishRate和requestedToken的乘积,例如,将replenishRate设为1,requestedTokens=60, burstCapability设置为60,将导致1 request/min的限制。

配置示例:

spring:
  cloud:
    gateway:
      default-filters:
      - StripPrefix=1
      routes:
      - id: o001
        uri: lb://order-service
        predicates:
        - Path=/api-a/**, /api-b/**
        filters:
        - name: RequestRateLimiter
          args:
            #每秒允许用户执行的请求数,而不丢弃任何请求。这是令牌桶的填充速率。
            redis-rate-limiter.replenishRate: 1
            #允许用户在一秒钟内完成的大请求数。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。
            redis-rate-limiter.burstCapacity: 2
            #一个请求需要多少令牌。这是每个请求从存储桶中获取的令牌数,默认为1。
            redis-rate-limiter.requestedTokens: 1
            keyResolver: "#{@userKeyResolver}"
            #自定义状态码
            #statusCode: INTERNAL_SERVER_ERROR
@Configuration
public class RedisRateConfig {

  @Bean
  public KeyResolver userKeyResolver() {
    // 以orderId限流
    // return exchange ->Mono.just(exchange.getRequest().getQueryParams().getFirst("orderId"));
    // 以ip限流
    return exchange ->Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()) ;
  }

}

解释:

这定义了每个IP1个请求速率的限制。允许2个请求的突发,但是在下一秒,只有1个请求可用。KeyResolver是一个获取用户请求参数的简单方法(注意,不建议在生产环境中使用)。

自定义限速器

还可以将速率限制器定义为实现RateLimiter接口的bean。在配置中,您可以使用SpEL按名称引用bean。#{@userRateLimiter}是一个SpEL表达式,它引用了一个名为userRateLimiter的bean。下面的清单定义了一个使用上一个清单中定义的KeyResolver的速率限制器:

spring:
  cloud:
    gateway:
      default-filters:
      - StripPrefix=1
      routes:
      - id: o001
        uri: lb://order-service
        predicates:
        - Path=/api-a/**, /api-b/**
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@userRateLimiter}"
            keyResolver: "#{@userKeyResolver}"
public class UserRateLimiter implements RateLimiter{
  @Override
  public MapgetConfig() {
    return null;
  }
  @Override
  public ClassgetConfigClass() {
    return null;
  }
  @Override
  public Config newConfig() {
    return null;
  }
  @Override
  public MonoisAllowed(String routeId, String id) {
    return null;
  }
  public static class Config {
    @Min(1)
    private int replenishRate;
    @Min(0)
    private int burstCapacity = 1;
    @Min(1)
    private int requestedTokens = 1;
    public int getReplenishRate() {
      return replenishRate;
    }
    public Config setReplenishRate(int replenishRate) {
      this.replenishRate = replenishRate;
      return this;
    }
    public int getBurstCapacity() {
      return burstCapacity;
    }
    public Config setBurstCapacity(int burstCapacity) {
      this.burstCapacity = burstCapacity;
      return this;
    }
    public int getRequestedTokens() {
      return requestedTokens;
    }
    public Config setRequestedTokens(int requestedTokens) {
      this.requestedTokens = requestedTokens;
      return this;
    }
    @Override
    public String toString() {
      return new ToStringCreator(this).append("replenishRate", replenishRate)
        .append("burstCapacity", burstCapacity).append("requestedTokens", requestedTokens).toString();
    }
  }
}

完毕!!!

Spring Cloud Gateway核心过滤器之请求限流详解

原创2022-11-21 08:20·Spring全家桶实战案例

环境:SpringBoot2.4.13 + Spring Cloud Gateway3.0.1


概述

RequestRateLimiter GatewayFilter工厂使用一个RateLimiter实现来确定当前请求是否允许继续。如果不是,返回HTTP 429 - Too Many Requests(默认情况下)的状态。

该过滤器接受一个可选的keyResolver参数和特定于速率限制器的参数。该参数的作用就是用来根据你设定的规则生成key,比如在redis中使用什么key。

keyResolver是一个实现KeyResolver接口的bean。在配置中,使用SpEL按名称引用bean。#{@userKeyResolver}是一个SpEL表达式,它引用了一个名为userKeyResolver的bean。KeyResolver接口如下所示:

public interface KeyResolver {

	Monoresolve(ServerWebExchange exchange);

}

默认情况下,如果KeyResolver没有找到key,请求将被拒绝。你可以通过设置
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key (true或false)和spring.cloud.gateway.filter.request-rate- limititer来调整这种行为。empty-key-status-code属性。

注意:RequestRateLimiter不能用“快捷方式”表示法进行配置。以下示例无效:

# INVALID SHORTCUT CONFIGURATION
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}
使用Redis限流

Redis的实现是基于Stripe所做的工作。它需要使用
spring-boot-starter-data-redis-reactive Spring Boot Starter。使用的算法是令牌桶算法。

计数器算法:有时间临界问题。

漏桶算法: 速率固定,有浪费资源问题。

配置属性说明:

redis-rate-limiter.replenishRate
允许用户在不丢弃任何请求的情况下每秒执行多少请求。这是令牌桶被填充的速率。
redis-rate-limiter.burstCapacity
允许用户在一秒钟内执行的大请求数。这是令牌桶可以容纳的令牌数量。将该值设置为零将阻止所有请求。
redis-rate-limiter.requestedTokens
一个请求花费多少令牌。这是为每个请求从桶中提取令牌的数量,默认为1。
  1. 一个稳定的速率是通过设置相同的值replenishRate和burstCapacity。
  2. 可以通过将burstCapacity设置为高于replenishRate来允许临时突发。

速率限制器需要在突发之间留出一段时间(根据replenishRate补发率),因为两个连续的爆发将导致丢弃的请求(HTTP 429 - Too Many requests)。

低于1个请求/秒的速率限制是通过以下方式实现的:将replenishRate设置为所需的请求数量,将requestedTokens设置为以秒为单位的时间跨度,将burstCapacity设置为replenishRate和requestedToken的乘积,例如,将replenishRate设为1,requestedTokens=60, burstCapability设置为60,将导致1 request/min的限制。

配置示例:

spring:
  cloud:
    gateway:
      default-filters:
      - StripPrefix=1
      routes:
      - id: o001
        uri: lb://order-service
        predicates:
        - Path=/api-a/**, /api-b/**
        filters:
        - name: RequestRateLimiter
          args:
            #每秒允许用户执行的请求数,而不丢弃任何请求。这是令牌桶的填充速率。
            redis-rate-limiter.replenishRate: 1
            #允许用户在一秒钟内完成的大请求数。这是令牌桶可以容纳的令牌数。将此值设置为零将阻止所有请求。
            redis-rate-limiter.burstCapacity: 2
            #一个请求需要多少令牌。这是每个请求从存储桶中获取的令牌数,默认为1。
            redis-rate-limiter.requestedTokens: 1
            keyResolver: "#{@userKeyResolver}"
            #自定义状态码
            #statusCode: INTERNAL_SERVER_ERROR
@Configuration
public class RedisRateConfig {

  @Bean
  public KeyResolver userKeyResolver() {
    // 以orderId限流
    // return exchange ->Mono.just(exchange.getRequest().getQueryParams().getFirst("orderId"));
    // 以ip限流
    return exchange ->Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()) ;
  }

}

解释:

这定义了每个IP1个请求速率的限制。允许2个请求的突发,但是在下一秒,只有1个请求可用。KeyResolver是一个获取用户请求参数的简单方法(注意,不建议在生产环境中使用)。

自定义限速器

还可以将速率限制器定义为实现RateLimiter接口的bean。在配置中,您可以使用SpEL按名称引用bean。#{@userRateLimiter}是一个SpEL表达式,它引用了一个名为userRateLimiter的bean。下面的清单定义了一个使用上一个清单中定义的KeyResolver的速率限制器:

spring:
  cloud:
    gateway:
      default-filters:
      - StripPrefix=1
      routes:
      - id: o001
        uri: lb://order-service
        predicates:
        - Path=/api-a/**, /api-b/**
        filters:
        - name: RequestRateLimiter
          args:
            rate-limiter: "#{@userRateLimiter}"
            keyResolver: "#{@userKeyResolver}"
public class UserRateLimiter implements RateLimiter{
  @Override
  public MapgetConfig() {
    return null;
  }
  @Override
  public ClassgetConfigClass() {
    return null;
  }
  @Override
  public Config newConfig() {
    return null;
  }
  @Override
  public MonoisAllowed(String routeId, String id) {
    return null;
  }
  public static class Config {
    @Min(1)
    private int replenishRate;
    @Min(0)
    private int burstCapacity = 1;
    @Min(1)
    private int requestedTokens = 1;
    public int getReplenishRate() {
      return replenishRate;
    }
    public Config setReplenishRate(int replenishRate) {
      this.replenishRate = replenishRate;
      return this;
    }
    public int getBurstCapacity() {
      return burstCapacity;
    }
    public Config setBurstCapacity(int burstCapacity) {
      this.burstCapacity = burstCapacity;
      return this;
    }
    public int getRequestedTokens() {
      return requestedTokens;
    }
    public Config setRequestedTokens(int requestedTokens) {
      this.requestedTokens = requestedTokens;
      return this;
    }
    @Override
    public String toString() {
      return new ToStringCreator(this).append("replenishRate", replenishRate)
        .append("burstCapacity", burstCapacity).append("requestedTokens", requestedTokens).toString();
    }
  }
}

完毕!!!

图片

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

网站栏目:SpringCloudGateway核心过滤器之请求限流详解-创新互联
分享URL:https://www.cdcxhl.com/article32/jippc.html

成都网站建设公司_创新互联,为您提供标签优化外贸网站建设建站公司全网营销推广微信小程序软件开发

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都定制网站网页设计