pom 依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
局部过滤器
package com.changgou.system.filter;
import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author G_Y
* @Date 2020/8/17 19:06
* @Description: // 秒杀限流局部过滤器
**/
@Component
public class SecKillRateLimiter2GatewayFilterFactory
extends AbstractGatewayFilterFactory<Object>
implements InitializingBean {
private Map<Long, RateLimiter> rateLimiterHashMap = new HashMap<>();
{
rateLimiterHashMap.put(-1L, RateLimiter.create(10));// 默认限流速率
}
@Override
public void afterPropertiesSet() throws Exception {
// 程序启动 或 利用 定时任务 或 利用 配置中心,将 秒杀商品对应的 限流速率 加载到程序
Map<Long, Integer> goodsLimitRate = new HashMap<>();
goodsLimitRate.put(111110L, 1); // 商品111111 对应 限流速率 为 一秒1个
goodsLimitRate.put(111112L, 3);
goodsLimitRate.put(111113L, 20);
// 如上比如是 从数据库加载到的 商品 对应 的限流速率 map
// 初始化rateLimiterHashMap
goodsLimitRate.forEach((k, v) -> {
rateLimiterHashMap.put(k, RateLimiter.create(v));
});
}
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
if (!"/test/secKill".equals(request.getURI().getPath())) {
return chain.filter(exchange);
}
List<String> goodsId = request.getQueryParams().get("goodsId");
if (CollectionUtils.isEmpty(goodsId)) {
throw new IllegalArgumentException("Error Arg");
}
String goodsIdStr = goodsId.get(0);
RateLimiter rateLimiter = rateLimiterHashMap.get(Long.parseLong(goodsIdStr));
if(rateLimiter == null) {
return chain.filter(exchange);
}
boolean b = rateLimiter.tryAcquire();
if (b) {
return chain.filter(exchange);
}
response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return response.setComplete();
};
}
}
局部过滤器配置

image.png
网友评论