【Spring Cloud】Gateway 服务网关限流

【Spring Cloud】Gateway 服务网关限流

码农世界 2024-06-21 后端 104 次浏览 0个评论

文章目录

  • route限流
    • 导入依赖
    • 编写配置类
    • 测试
    • 自定义API分组
    • 总结

      网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,我们本次采用前面学过的 Sentinel 组件来实现网关的限流。

      Sentinel 支持对 SpringCloud Gateway、Zuul等主流网关进行限流。

      【Spring Cloud】Gateway 服务网关限流

      从1.6.0版本开始,Sentinel提供了SpringCloud Gateway的适配模块,可以提供两种资源维度的限流:

      • route维度:即在Spring配置文件中配置的路由条目,资源名为对应的routeld;
      • 自定义API维度:用户可以利用Sentinel提供的API来自定义一些API分组;

        route限流

        导入依赖

        
        	com.alibaba.csp
        	>sentinel-spring-cloud-gateway-adapter
        
        

        编写配置类

        基于Sentinel的Gateway限流是通过其提供的Filter来完成的,使用时只需注入对应的SentinelGatewayFilter实例以及SentinelGatewayBlockExceptionHandler实例即可。

        @Configuration
        public class GatewayConfiguration {
            private final List viewResolvers;
            private final ServerCodecConfigurer serverCodecConfigurer;
            public GatewayConfiguration(ObjectProvider> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
                this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
                this.serverCodecConfigurer = serverCodecConfigurer;
            }
            //初始化一个限流的过滤器
            @Bean
            @Order(Ordered.HIGHEST_PRECEDENCE)
            public GlobalFilter sentinelGatewayFilter() {
                return new SentinelGatewayFilter();
            }
            //配置初始化的限流参数
            @PostConstruct
            public void initGatewayRules() {
                Set rules = new HashSet<>();
                rules.add(new GatewayFlowRule("shop-product")//资源名称,对应路由id
                                .setCount(1)//限流阀值
                                .setIntervalSec(1)//统计时间窗口,单位是秒,默认是1秒
                );
                GatewayRuleManager.loadRules(rules);
            }
            //配置限流异常处理器
            @Bean
            @Order(Ordered.HIGHEST_PRECEDENCE)
            public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
                return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
            }
            //自定义限流异常页面
            @PostConstruct
            public void initBlockHandlers() {
                BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
                    @Override
                    public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
                        Map map= new HashMap<>();
                        map.put("code", 0);
                        map.put("message", "接口被限流了");
                        return ServerResponse
                                .status(HttpStatus.OK)
                                .contentType(MediaType.APPLICATION_JSON_UTF8)
                                .body(BodyInserters.fromObject(map));
                    }
                } ;
                GatewayCallbackManager.setBlockHandler(blockRequestHandler);
            }
        }
        

        其中,GatewayFlowRule 网关限流规则中提供了如下属性:

        • resource:资源名称,可以是网关中的route名称或者用户自定义的API分组名称。
        • resourceMode:资源模型,限流规则是针对API Gateway的 route (RESOURCE_MODE_ROUTE_ID)还是用户在Sentinel 中定义的API分组(RESOURCE_MODE_CUSTOM_API_NAME),默认route。
        • grade:限流指标维度,同限流规则的 grade 字段。
        • count:限流阈值。
        • intervalSec:统计时间窗口,单位是秒, 默认是1 秒。
        • controlBehavior:流量整形的控制效果,同限流规则的controlBehavior字段,目前支持快速失败和匀速排队两种模式,默认快速失败。
        • burst:应对突发请求时额外允许的请求数目。
        • maxQueueingTimeoutMs:匀速排队模式下的最长排队时间,单位是毫秒,仅在匀速排队模式下生效。
        • paramItem:参数限流配置。若不提供,则代表针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换热点规则。其中的字段如下:
          • arseStrategy: 从请求中提取参数的策略,目前支持提取来源IP(PARAM_PARSE_STRATEGY_CLIENT_IP)、Host(PARAM_PARSE_STRATEGY_HOST)、任意Header(PARAM_PARSE_STRATEGY_HEADER)和任意URL 参数(PARAM_PARSE_STRATEGY_URL_PARAM)四种模式。
            • fieldName:若提取策略选择Header模式或者URL参数模式,则需要指定对应的Header名称或URL参数名称。
              • pattern和matchStrategy: 为后续参数匹配特性预留,目前末实现。

                测试

                在一秒钟内多次访问http://localhost:7000/product/product/1?token=1232就可以看到限流启作用了。

                【Spring Cloud】Gateway 服务网关限流

                自定义API分组

                自定义API分组是一种更细粒度的限流规则定义

                //配置初始化的限流参数
                @PostConstruct
                public void initGatewayRules() {
                    Set rules = new HashSet<>();
                    rules.add(new GatewayFlowRule("shop_product_api").setCount(1).setIntervalSec(1));
                    rules.add(new GatewayFlowRule("shop_order_api").setCount(1).setIntervalSec(1));
                    GatewayRuleManager.loadRules(rules);
                }
                //自定义API分组
                @PostConstruct
                private void initCustomizedApis(){
                    Set definitions = new HashSet<>();
                    //定义小组1
                    ApiDefinition api1 = new ApiDefinition("shop_product_api")
                            .setPredicateItems(new HashSet(){{
                                //以/product/product/api1开头的请求
                                add(new ApiPathPredicateItem().setPattern("/product/product/**")
                                        .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                            }});
                    //定义小组2
                    ApiDefinition api2 = new ApiDefinition("shop_order_api")
                            .setPredicateItems(new HashSet(){{
                                //完全匹配/order/order2/message
                                add(new ApiPathPredicateItem().setPattern("/order/order2/message"));
                            }});
                    definitions.add(api1);
                    definitions.add(api2);
                    GatewayApiDefinitionManager.loadApiDefinitions(definitions);
                }
                

                在一秒钟内多次访问http://localhost:7000/product/product/1?token=1232也可以看到限流启作用了。

                【Spring Cloud】Gateway 服务网关限流

                总结

                到这儿,Gateway 服务网关限流的内容就已经介绍完了。下一篇将为大家带来链路追踪Sleuth相关的文章,敬请期待吧!

                后续的文章,我们将继续完善我们的微服务系统,集成更多的Alibaba组件。想要了解更多JAVA后端知识,请点击文末名片与我交流吧。留下您的一键三连,让我们在这个寒冷的东西互相温暖吧!

转载请注明来自码农世界,本文标题:《【Spring Cloud】Gateway 服务网关限流》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,104人围观)参与讨论

还没有评论,来说两句吧...

Top