限流规则
作者:唐亚峰 | battcn
字数统计:351 字
顾名思义,限流就是限制流量。通过限流,我们可以很好地控制系统的 QPS,从而达到保护系统的目的。 常见的限流算法有:计数器
算法,漏桶(Leaky Bucket)
算法,令牌桶(Token Bucket)
算法。
Spring Cloud Gateway
官方提供了 RequestRateLimiterGatewayFilterFactory
过滤器工厂,使用 Redis
和 Lua
脚本实现了令牌桶的方式。
添加依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
添加配置
yaml
spring:
application:
name: wemirr-platform-gateway
cloud:
gateway:
enabled: true
discovery:
locator:
enabled: true
lowerCaseServiceId: true
routes:
- id: wemirr-platform-authority
uri: lb://wemirr-platform-authority
predicates:
- Path=/authority/**
filters:
# 限流过滤器
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100 # 允许用户每秒处理多少个请求
redis-rate-limiter.burstCapacity: 100 # 令牌桶的容量,允许在一秒钟内完成的最大请求数
# 使用 IP 限流策略(使用 SpEL 按名称引用 bean)
key-resolver: "#{@ipKeyResolver}"
实现代码
java
package com.wemirr.platform.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.context.annotation.Primary;
import reactor.core.publisher.Mono;
import java.util.Objects;
/**
* @author Levin
*/
@Configuration
public class KeyResolverConfiguration {
private static final String AUTHORIZATION = "authorization";
/**
* IP 限流
*
* @return IP限流
*/
@Primary
@Bean(name = "ipKeyResolver")
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
}
/**
* 用户限流
* 使用这种方式限流,请求路径中必须携带userId参数
*
* @return 用户限流
*/
@Bean(name = "tokenKeyResolver")
public KeyResolver tokenKeyResolver() {
return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getHeaders().getFirst(AUTHORIZATION)));
}
/**
* 接口限流
* 获取请求地址的uri作为限流key
*
* @return 接口限流
*/
@Bean(name = "apiKeyResolver")
public KeyResolver apiKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().value());
}
}