开发者社区 > 云原生 > 中间件 > 正文

springcloud gateway sential 限流 自定义参数限流执行顺序问题

网关根据传入的参数有个开关,当开关打开时,直接返回结果,但是又想要限流起作用,

目前遇到的问题是,开关打开时,可以返回结果,然后才触发了自定义参数限流,被全局异常拦截器拦截

正常的情况,应该也要先验证符合限流条件后,才能返回结果才是正常,直接返回结果时,没有调用接口

期望,在没有调用接口的情况下,限流验证后,才直接返回结果,但是不用调用接口

展开
收起
1297240807477643 2023-10-20 13:39:59 136 0
3 条回答
写回答
取消 提交回答
  • 在使用Spring Cloud Gateway和Sentinel进行限流时,如果你需要自定义参数限流,你需要配置Sentinel的流控规则,并使用Spring Cloud Gateway的自定义过滤器工厂来实现。
    在配置Sentinel的流控规则时,你可以指定流控的Key,例如用户ID、IP地址等。然后,你可以根据这些Key来配置不同的流控规则,例如不同的用户ID可以有不同的限流策略。
    在使用Spring Cloud Gateway的自定义过滤器工厂时,你需要实现一个FilterFactory,然后在过滤器工厂的配置文件中指定这个工厂。然后,你可以在过滤器工厂的实现中使用Sentinel的流控规则来实现限流。
    关于自定义参数限流执行顺序的问题,一般来说,Spring Cloud Gateway的自定义过滤器工厂会在所有其他的过滤器之前执行,然后再由其他的过滤器进行处理。因此,如果你在自定义过滤器工厂中实现了限流,那么限流就会在其他过滤器之前执行。

    2023-10-21 10:21:59
    赞同 展开评论 打赏
  • 公众号:网络技术联盟站,InfoQ签约作者,阿里云社区签约作者,华为云 云享专家,BOSS直聘 创作王者,腾讯课堂创作领航员,博客+论坛:https://www.wljslmz.cn,工程师导航:https://www.wljslmz.com

    你可以尝试在自定义限流过滤器中,先进行限流验证,然后再返回结果。这样即使开关打开,也不会触发全局异常拦截器。以下是一个示例:

    public class CustomRateLimitFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 获取请求参数中的开关
            String switchParam = exchange.getRequest().getQueryParams().getFirst("switch");
    
            // 如果开关为开启状态,直接返回结果
            if ("on".equalsIgnoreCase(switchParam)) {
                return chain.filter(exchange);
            }
    
            // 否则,进行限流验证
            return rateLimitService.isAllowed(exchange)
                    .flatMap(allowed -> {
                        if (allowed) {
                            return chain.filter(exchange);
                        } else {
                            // 限流验证未通过,返回错误信息
                            return Mono.just(new ResponseEntity<>(HttpStatus.TOO_MANY_REQUESTS));
                        }
                    });
        }
    
        @Override
        public int getOrder() {
            return -1; // 设置优先级低于其他过滤器
        }
    }
    

    在这个示例中,我们首先检查请求参数中的开关是否为开启状态。如果是,则直接调用chain.filter(exchange)返回结果。如果不是,则进行限流验证。如果限流验证通过,再调用chain.filter(exchange)返回结果;否则,返回一个包含错误信息的响应。

    2023-10-20 14:58:00
    赞同 展开评论 打赏
  • 面对过去,不要迷离;面对未来,不必彷徨;活在今天,你只要把自己完全展示给别人看。

    要实现在没有调用接口的情况下,先进行自定义参数限流验证再直接返回结果,可以通过以下方式来处理:

    1. 将自定义参数限流的逻辑放在网关的 Filter 中:在 Spring Cloud Gateway 中,可以创建一个自定义的 Gateway Filter 来处理请求。在该 Filter 中,你可以获取到请求的参数,并根据开关状态进行限流验证。如果开关打开,则直接返回结果;如果符合限流条件,则继续执行后续的 Filter 和路由操作;如果不符合限流条件,则可以选择返回相应的错误信息或者触发全局异常拦截器。

    2. 结合 Sentinel 实现动态的限流策略:使用 Sentinel 作为限流工具,结合网关,在请求进入网关时,根据开关状态和自定义参数进行限流验证。你可以配置动态的限流规则,通过 Sentinel Dashboard 进行管理和修改。根据规则的结果,可以直接返回结果或继续执行后续的处理。

    3. 利用缓存来判断是否调用接口:在网关中,可以使用缓存来记录该请求是否已经被处理过。当开关打开时,首先检查缓存中是否存在对应的结果,如果存在,则直接返回结果;如果不存在,则进行限流验证并调用接口,然后将结果存入缓存。

    2023-10-20 14:24:25
    赞同 展开评论 打赏

为企业提供高效、稳定、易扩展的中间件产品。

相关电子书

更多
搭建基于SpringCloud的微服务应用 立即下载
低代码开发师(初级)实战教程 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载