java版spring cloud+spring boot 社交电子商务平台-- gateway限流

社交电商平台源码请加企鹅求求:一零三八七七四六二六。限流一般有两个实现方式,令牌桶和漏桶。

金牌桶是初始化令牌(容器)的个数,通过拿走里边的令牌就能通过, 没有令牌不能报错,可以设置向容器中增加令牌的速度和最大个数

漏桶是向里边放入请求,当请求数量达到最大值后,丢弃,漏桶中的数据以一定速度流出,没有则不流出

金牌桶实现方式如下:

pom


    com.github.vladimir-bukhtoyarov
    bucket4j-core
    4.0.0



    org.springframework.boot
    spring-boot-starter-data-redis-reactive

创建下边类并且继承下边类

public class LimitFilter implements GatewayFilter, Ordered {

    private final Logger logger = LoggerFactory.getLogger(LimitFilter.class);

    int capacity;
    int refillTokens;
    Duration refillDuration;

    public LimitFilter(int capacity, int refillTokens, Duration refillDuration) {
        this.capacity = capacity;
        this.refillTokens = refillTokens;
        this.refillDuration = refillDuration;
    }

    private static final Map CACHE = new ConcurrentHashMap<>();
    private Bucket createNewBucket() {
        Refill refill = Refill.of(refillTokens,refillDuration);
        Bandwidth limit = Bandwidth.classic(capacity,refill);
        return Bucket4j.builder().addLimit(limit).build();
    }

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
        Bucket bucket = CACHE.computeIfAbsent(ip,k -> createNewBucket());
        logger.info("IP: " + ip + ",TokenBucket Available Tokens: " + bucket.getAvailableTokens());
        if (bucket.tryConsume(1)) {
            return chain.filter(exchange);
        } else {
            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
            return exchange.getResponse().setComplete();
        }

    }

    @Override
    public int getOrder() {
        return 0;
    }
}

配置路由

  @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
// @formatter:off
        return builder.routes()
                .route(r -> r.path("/consulserver/**")
                        .filters(f -> f.stripPrefix(1)
                                .filter(new LimitFilter(10,1,Duration.ofSeconds(1))))
                        .uri("lb://consulserver")
                        .order(0)
                        .id("throttle_customer_service")
                ).build();
// @formatter:on
    } 

你可能感兴趣的:(java版spring cloud+spring boot 社交电子商务平台-- gateway限流)