SpringCloud Alibaba Sentinel网关流量控制实践总结

2024-07-14 1093阅读

官网地址:https://sentinelguard.io/zh-cn/docs/api-gateway-flow-control.html

GitHub地址:GitHub Sentinel 网关限流

【1】概述

Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。

SpringCloud Alibaba Sentinel网关流量控制实践总结

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) 注册动态规则源动态推送(推荐方式)。

        【2】Spring Cloud Gateway实践

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

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

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

              com.alibaba.csp
              sentinel-spring-cloud-gateway-adapter
              x.y.z
          
          

          ① pom依赖

              org.springframework.cloud
              spring-cloud-starter-gateway
          
          
              com.alibaba.csp
              sentinel-transport-simple-http
              1.8.6
          
          
              com.alibaba.csp
              sentinel-spring-cloud-gateway-adapter
              1.8.6
          
          
              javax.annotation
              javax.annotation-api
              1.3.2
              compile
          
          

          ② 参考官网示例编写配置类

          @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 SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
                  // Register the block exception handler for Spring Cloud Gateway.
                  return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
              }
              @Bean
              @Order(-1)
              public GlobalFilter sentinelGatewayFilter() {
                  return new SentinelGatewayFilter();
              }
              @PostConstruct
              public void doInit()
              {
                  initBlockHandler();
              }
              //处理+自定义返回的例外信息内容,类似我们的调用触发了流控规则保护
              private void initBlockHandler()
              {
                  // 1.自定义路由与限流规则:针对路由pay_routh1,限制请求QPS=2/s
                  Set rules = new HashSet();
                  rules.add(new GatewayFlowRule("pay_routh1").setCount(2).setIntervalSec(1));
                  GatewayRuleManager.loadRules(rules);
                  // 2.注册函数用于实现自定义的逻辑处理被限流的请求
                  BlockRequestHandler handler = new BlockRequestHandler()
                  {
                      @Override
                      public Mono handleRequest(ServerWebExchange exchange, Throwable t)
                      {
                          Map map = new HashMap();
                          map.put("errorCode", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
                          map.put("errorMessage", "请求太过频繁,系统忙不过来,触发限流(sentinel+gataway整合Case)");
                          return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                                  .contentType(MediaType.APPLICATION_JSON)
                                  .body(BodyInserters.fromValue(map));
                      }
                  };
                  GatewayCallbackManager.setBlockHandler(handler);
              }
          }
          

          对应yml文件如下所示:

          server:
            port: 9528
          spring:
            application:
              name: cloudalibaba-sentinel-gateway     # sentinel+gataway整合Case
            cloud:
              nacos:
                discovery:
                  server-addr: localhost:8848
              gateway:
                routes:
                  - id: pay_routh1 #pay_routh1                #路由的ID(类似mysql主键ID),没有固定规则但要求唯一,建议配合服务名
                    uri: http://localhost:9001                #匹配后提供服务的路由地址
                    predicates:
                      - Path=/pay/**                      # 断言,路径相匹配的进行路由
          

          可以在 GatewayCallbackManager 注册回调进行定制:

          • setBlockHandler:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler。默认实现为 DefaultBlockRequestHandler,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException。

            注意:

            • Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。若通过 Spring Cloud Alibaba 接入,请将 spring.cloud.sentinel.filter.enabled 配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。
            • 若使用 Spring Cloud Alibaba Sentinel 数据源模块,需要注意网关流控规则数据源类型是 gw-flow,若将网关流控规则数据源指定为 flow 则不生效。
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]