Spring Cloud Gateway可以通过集成限流组件来实现限流

108 阅读1分钟

添加Redis依赖

pom文件新增如下配置

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

配置Redis连接

在application.yml文件中添加以下配置:

yaml
spring:
  redis:
    host: localhost
    port: 6379
    database: 0
    

实现限流过滤器

创建一个RateLimiterGatewayFilterFactory类,实现GatewayFilterFactory接口:

public class RateLimiterGatewayFilterFactory extends AbstractGatewayFilterFactory<RateLimiterGatewayFilterFactory.Config> {
     private final RedisTemplate<String, String> redisTemplate;
     public RateLimiterGatewayFilterFactory(RedisTemplate<String, String> redisTemplate) {
        super(Config.class);
        this.redisTemplate = redisTemplate;
    }
     @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            String key = exchange.getRequest().getPath().toString();
            String value = redisTemplate.opsForValue().get(key);
            if (value != null && Integer.parseInt(value) >= config.getPermits()) {
                exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
                return exchange.getResponse().setComplete();
            }
            redisTemplate.opsForValue().increment(key);
            redisTemplate.expire(key, config.getDuration(), TimeUnit.SECONDS);
            return chain.filter(exchange);
        };
    }
     public static class Config {
        private int permits;
        private int duration;
         public int getPermits() {
            return permits;
        }
         public void setPermits(int permits) {
            this.permits = permits;
        }
         public int getDuration() {
            return duration;
        }
         public void setDuration(int duration) {
            this.duration = duration;
        }
    }
}

配置限流过滤器

在application.yml文件中添加以下配置:

yaml
spring:
  cloud:
    gateway:
      routes:
        - id: rate_limiter_route
          uri: http://localhost:8081
          predicates:
            - Path=/rateLimiter/**
          filters:
            - name: RateLimiter
              args:
                permits: 5
                duration: 60
                

这里配置了一个路由,请求路径为/rateLimiter/**,并添加了一个名为RateLimiter的过滤器,并传入permits和duration参数。permits表示每秒允许的请求数,duration表示限流的时间窗口,这里设置为60秒。

测试

启动应用后,访问http://localhost:8080/rateLimiter/test,如果在60秒内请求次数超过5次,将会返回HTTP状态码429,表示请求过多。