秒杀限流-网关-商品维度限流控制

pom 依赖

        
            com.google.guava
            guava
            28.0-jre
        

局部过滤器

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
        implements InitializingBean {

    private Map rateLimiterHashMap = new HashMap<>();

    {
        rateLimiterHashMap.put(-1L, RateLimiter.create(10));// 默认限流速率
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 程序启动 或 利用 定时任务 或 利用 配置中心,将 秒杀商品对应的 限流速率 加载到程序
        Map 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 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

你可能感兴趣的:(秒杀限流-网关-商品维度限流控制)