ivate final RateLimiter redisRateLimiter;
private final KeyResolver keyResolver;
private final boolean denyEmptyKey = true;
private static final String EMPTY_KEY = "____EMPTY_KEY__";
public CubeRequestLimiterGatewayFilterFactory(RateLimiter redisRateLimiter, KeyResolver keyResolver) {
super(redisRateLimiter, keyResolver);
this.redisRateLimiter = redisRateLimiter;
this.keyResolver = keyResolver;
}
@Override
public GatewayFilter apply(Config config) {
KeyResolver resolver = getOrDefault(config.getKeyResolver(), keyResolver);
RateLimiter<Object> limiter = getOrDefault(config.getRateLimiter(), redisRateLimiter);
boolean denyEmpty = getOrDefault(config.getDenyEmptyKey(), this.denyEmptyKey);
return (exchange, chain) -> resolver.resolve(exchange).defaultIfEmpty(EMPTY_KEY).flatMap(key -> {
if (EMPTY_KEY.equals(key)) {
if (denyEmpty) {
return TokenCheckGatewayFilterFactory.generateJson(exchange, R.error(9998, "请求key为空"));
}
return chain.filter(exchange);
}
String routeId = config.getRouteId();
if (routeId == null) {
Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
routeId = route.getId();
}
return limiter.isAllowed(routeId, key).flatMap(response -> {
for (Map.Entry<String, String> header : response.getHeaders().entrySet()) {
exchange.getResponse().getHeaders().add(header.getKey(), header.getValue());
}
if (response.isAllowed()) {
return chain.filter(exchange);
}
R<String> r = R.error(9998, "请求太频繁");
r.setData(key);
r.setGuid("请控制请求速度");
r.setTraceId(Stream.of(exchange.getRequest().getHeaders().getFirst("requestId"), exchange.getRequest().getQueryParams().getFirst("requestId")).filter(StringUtils::isNotBlank).findFirst().orElse(UUIDUtils.uuid()));
log.warn("too many requests: {}", JSONUtil.toJsonStr(r));
return TokenCheckGatewayFilterFactory.generateJson(exchange, r);
});
});
}
private <T> T getOrDefault(T configValue, T defaultValue) {
return (configValue != null) ? configValue : defaultValue;
}
}
测试
jmeter脚本
线程配置:
接口配置:
经过测试,对高频接口增加了限流能力,而且限流能力是可以设定的。
小结
在网关添加了最低限度的保护限流策略。
企业用户数量有限,可以使用最小的资源满足软件系统的需求;
原创不易,关注诚可贵,转发价更高!转载请注明出处,让我们互通有无,共同进步,欢迎沟通交流。
|