zoukankan      html  css  js  c++  java
  • 使用Sentinel实现Spring Cloud Gateway网关流量控制

    Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑:

    • GatewayFlowRule:网关限流规则,针对 API Gateway 的场景定制的限流规则,可以针对不同 route 或自定义的 API 分组进行限流,支持针对请求中的参数、Header、来源 IP 等进行定制化的限流。
    • ApiDefinition:用户自定义的 API 定义分组,可以看做是一些 URL 匹配的组合。比如我们可以定义一个 API 叫 my_api,请求 path 模式为 /foo/** 和 /baz/** 的都归到 my_api 这个 API 分组下面。限流的时候可以针对这个自定义的 API 分组维度进行限流。

    其中网关限流规则 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:参数限流配置。若不提供,则代表不针对参数进行限流,该网关规则将会被转换成普通流控规则;否则会转换成热点规则。其中的字段:
      • parseStrategy:从请求中提取参数的策略,目前支持提取来源 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:参数值的匹配模式,只有匹配该模式的请求属性值会纳入统计和流控;若为空则统计该请求属性的所有值。(1.6.2 版本开始支持)
      • matchStrategy:参数值的匹配策略,目前支持精确匹配(PARAM_MATCH_STRATEGY_EXACT)、子串匹配(PARAM_MATCH_STRATEGY_CONTAINS)和正则匹配(PARAM_MATCH_STRATEGY_REGEX)。(1.6.2 版本开始支持)

    用户可以通过 GatewayRuleManager.loadRules(rules) 手动加载网关规则,或通过 GatewayRuleManager.register2Property(property) 注册动态规则源动态推送(推荐方式)。

    Spring Cloud Gateway

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

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

    使用时需引入以下模块(以 Maven 为例):

        <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-core</artifactId>
                <version>1.7.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
                <version>1.7.2</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-transport-simple-http</artifactId>
                <version>1.7.2</version>
            </dependency>

    使用时只需注入对应的 SentinelGatewayFilter 实例以及 SentinelGatewayBlockExceptionHandler 实例即可。

    网关设置:

    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SpringCloudConfig {
    
        @Bean
        public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
            return builder.routes()
                    .route(r -> r.path("/employee/**")
                            .uri("http://localhost:8081/")
                            .id("employeeModule"))
    
                    .route(r -> r.path("/consumer/**")
                            .uri("http://localhost:8082/")
                            .id("consumerModule"))
                    .build();
        }
    
    }

    Sentinel限流设置

            Set<GatewayFlowRule> rules = new HashSet<>();
            //规则是针对 API Gateway 的 route(RESOURCE_MODE_ROUTE_ID),默认是 route。
            rules.add(new GatewayFlowRule("employeeModule")
                    .setCount(2)
                    .setIntervalSec(1)
            );
    
            //规则是针对在 Sentinel 中定义的 API 分组(RESOURCE_MODE_CUSTOM_API_NAME)
            rules.add(new GatewayFlowRule("account_api")
                    .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                    .setCount(30)
                    .setIntervalSec(1)
            );

    我们对employeeModule为id的网关设置2个qps的限流阈值,当大于2时出现:

    Blocked by Sentinel: ParamFlowException

    控制流程:

    上图的整体流程如下:

    1、外部请求进入API Gateway时会经过Sentinel实现的filter,其中会依次进行 路由/API 分组匹配、请求属性解析和参数组装。

    2、Sentinel 会根据配置的网关流控规则来解析请求属性,并依照参数索引顺序组装参数数组,最终传入SphU.entry(res, args) 中。

    3、Sentinel API Gateway Adapter Common 模块向 Slot Chain 中添加了一个 GatewayFlowSlot,专门用来做网关规则的检查。

    4、GatewayFlowSlot会从GatewayRuleManager中提取生成的热点参数规则,根据传入的参数依次进行规则检查。若某条规则不针对请求属性,则会在参数最后一个位置置入预设的常量达到普通流控的效果注意:

    当通过 GatewayRuleManager 加载网关流控规则GatewayFlowRule时,无论是否针对请求属性进行限流,Sentinel底层都会将网关流控规则转化为热点参数规则ParamFlowRule,存储在GatewayRuleManager 中,与正常的热点参数规则相隔离。转换时Sentinel会根据请求属性配置,为网关流控规则设置参数索引idx,并同步到生成的热点参数规则

    完整Demo工程下载:

    三个分布式工程打包下载

  • 相关阅读:
    【成功案例】智能企业的可持续转型
    【成功案例】三菱重工
    【成功案例】都乐(Dole)
    【成功案例】佳能
    【成功案例】DHL将美洲汇聚在一起
    【成功案例】Bantotal
    【成功案例】得益于GeneXus,毕马威墨西哥在员工培训方面节省了95%的费用
    GeneXus低码工具为美国最大的大学图书销售商之一解决了五个问题
    双均线系统
    价量时空交易系统
  • 原文地址:https://www.cnblogs.com/starcrm/p/12928808.html
Copyright © 2011-2022 走看看