gateway集成阿里Sentinel后,控制台如何根据url动态限流

/ 后端 / 没有评论 / 614浏览

gateway网关集成Sentinel后,控制台默认限流是根据服务进行的,默认为资源名为ReactiveCompositeDiscoveryClient_服务名称,如下图:

alt

所以限流都是根据整个服务进行的,那么如何像单机一样根据url分组限流呢;有两种方式:

1.通过初始化配置:

@Configuration
public class SentinelInitUrlConfig {

    @PostConstruct
    public void doInit() {
        loadApiDefinitions();
    }

    public void loadApiDefinitions() {
        Set<ApiDefinition> apiDefinitions = GatewayApiDefinitionManager.getApiDefinitions();

        ApiDefinition api = new ApiDefinition("分组")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/auth/*")
                            //参数值的匹配策略
                            // 精确匹配(PARAM_MATCH_STRATEGY_EXACT)
                            // 子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)
                            // 正则匹配(PARAM_MATCH_STRATEGY_REGEX)
                            .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_EXACT));
                }});
        apiDefinitions.add(api);
        GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions);
    }
}

2.通过过滤器动态添加分组:

@Component
@Order(Integer.MIN_VALUE)
public class SentinelUrlFilter implements GlobalFilter {
    private Set<String> uris = new CopyOnWriteArraySet<>();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        Route gatewayUrl = exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
        String uri = "/" + gatewayUrl.getUri().getHost() + exchange.getRequest().getURI().getPath();

        if (uris.add(uri)) {
            loadApiDefinitions(uri);
        }

        return chain.filter(exchange);
    }

    public void loadApiDefinitions(String uri) {

        Set<ApiDefinition> apiDefinitions = GatewayApiDefinitionManager.getApiDefinitions();

        ApiDefinition api = new ApiDefinition(uri)
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern(uri)
                            .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_EXACT));
                }});
        apiDefinitions.add(api);
        GatewayApiDefinitionManager.loadApiDefinitions(apiDefinitions);
    }
}