前言
如果不使用Alibaba Sentinel的网关流控规则,
是否可以选择使用SpringCloudGateway基于Redis的限流组件?
基于这个问题,笔者想了解一下scg自带限流组件的实现原理。
一、使用案例
1、pom
注意要加入redis-reactive依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
复制代码
2、KeyResolver
实现一个KeyResolver解析限流资源key,比如针对某个请求路径、针对某个请求路径+用户等。
@Component
public class ExampleKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
String uri = exchange.getRequest().getURI().getPath();
HttpHeaders headers = exchange.getRequest().getHeaders();
List<String> keys = headers.get("client_id");
if (CollectionUtils.isEmpty(keys)) {
return Mono.just(uri);
}
return Mono.just(uri + "_" + keys.get(0));
}
}
复制代码
3、路由配置
这里通过编码方式创建一个RouteLocator配置路由。
注:也可以通过RouteDefinitionLocator配置,也可以通过yml配置。
@Bean
public RouteLocator rateLimitRouteLocator(RouteLocatorBuilder builder, ExampleKeyResolver exampleKeyResolver) {
return builder.routes()
// curl --header "client_id:aacc" -v localhost:8080/ratelimiter
.route("test_rate_limit", predicateSpec -> predicateSpec
.path("/ratelimiter") // PathRoutePredicate匹配路径
.filters(
// RedisRateLimiter
gatewayFilterSpec -> gatewayFilterSpec.requestRateLimiter().rateLimiter(RedisRateLimiter.class, config -> {
config.setReplenishRate(1);