import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* 对某些接口在某个ip下的限流
* 在验签、鉴权之后执行
*/
@Slf4j
@Component
@AllArgsConstructor
public class RedisRateLimitFilter implements GlobalFilter, Ordered {
@Autowired
private RedisTemplate redisTemplate;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Integer limit = 2;
Integer duration = 1;
String key = exchange.getRequest().getPath().toString();
Object value = redisTemplate.opsForValue().get(key);
if (Objects.nonNull(value)&& StringUtils.isNotEmpty(value.toString()) && Integer.parseInt(value.toString()) >= limit) {
exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
return exchange.getResponse().setComplete();
}
if (Objects.isNull(value) || StringUtils.isEmpty(value.toString())) {
redisTemplate.opsForValue().set(key,1, duration, TimeUnit.MINUTES);
}else{
redisTemplate.opsForValue().increment(key, 1);
redisTemplate.expire(key, duration, TimeUnit.MINUTES);
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1000;
}
}
spring-cloud gateway 自定义滑动窗口限流
最新推荐文章于 2023-05-29 15:59:02 发布