技术交流28群

服务热线

135-6963-3175

微信服务号

gateway集成sentinel自定义限流规则 更新时间 2019-10-10 浏览1983次

关于spring cloud gateway进行sentinel的集成和自定义规则加载。

1、首先定义全局配置类

@Configuration
public class GovernConfiguration {
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;
    public GovernConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
                               ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }
    //异常处理器
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }
    //限流拦截器
    @Bean
    public GovernFilter sentinelGatewayFilter(SidecarLoadBalancerClientFilter sidecarLoadBalancerClientFilter) {
        return new GovernSentiFilter();
    }
    //可声明一个bean进行自定义规则的加载(略)
    
}

2、然后定义GovernSentiFilter类

public class GovernFilter implements GatewayFilter, GlobalFilter, Ordered {
    private final int order;
    public GovernFilter() {
        this(Ordered.HIGHEST_PRECEDENCE);
    }
    public GovernFilter(int order) {
        this.order = order;
    }
    private final GatewayParamParser<ServerWebExchange> paramParser = new GatewayParamParser<>(
            new ServerWebExchangeItemParser());
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        //根据规则组装限流资源标志id
        //扩展点: 可在此处通过path进行规则的匹配计算出最终限流id
        List<String> resources = ...;
        if (resources.size() == 0) {
            return chain.filter(exchange);
        }
        Mono<Void> filter = chain.filter(exchange);
        //通过上面结果id进行限流
        for(String resource: resources){
            filter = from((Publisher)((Function)buildSentinelTransformer(exchange, resource)).apply(filter));
        }
        return filter;
    }
    private SentinelReactorTransformer<Void> buildSentinelTransformer(ServerWebExchange exchange, String finalPath) {
        String origin ="";
        return new SentinelReactorTransformer<>(new EntryConfig(finalPath, ResourceTypeConstants.COMMON_WEB,
                EntryType.IN, new ContextConfig(finalPath, origin)));
    }
}

3、在限流slot里通过步骤2的id反向计算出规则进行原规则的获取,进而进行相关定义流控行为的处理。

待补充...