全部产品
云市场

流量控制插件

更新时间:2020-03-02 14:55:07

1. 概述

  • 流量控制插件用于对API进行限流,流量控制插件可以对APIApp(访问的AK)用户(访问方的App归属用户),以及自定义参数进行多种维度的限流

  • 流量控制插件目前支持两种配置模板

    • 参数流控配置,支持自定义参数的流控配置
    • 基础流控配置,与控制台上的流量控制功能保持兼容
  • 流量控制现在合并进了插件体系。现存的流量控制界面与接口仍然可以使用,流量控制策略流量控制插件属于同一种插件类型,如果你绑定了流量控制插件,则流量控制策略会失效

  • 使用原有的流量控制接口或控制台创建或更改流量控制,会同步数据至插件系统,但不会反向同步。

2. 基础流控配置

2.1. 流控能力

基础流控支持以下的流控维度

  • API 流量限制 该策略绑定的API在单位时间内被调用的次数不能超过设定值,单位时间可选分钟、小时、天,如5000次/分钟。
  • APP 流量限制 每个APP对该策略绑定的任何一个API在单位时间内的调用次数不能超过设定值。如50000次/小时。
  • 用户流量限制 每个阿里云账号对该策略绑定的任何一个 API 在单位时间内的调用次数不能超过设定值。一个阿里云账号可能有多个 APP,所以对阿里云账号的流量限制就是对该账号下所有 APP 的流量总和的限制。如 50 万次/天。

在一个流控策略插件里面,这三个值可以同时设置。请注意,用户流量限制应不大于 API 流量限制,APP 流量限制应不大于用户流量限制。即 APP 流量限制 <= 用户流量限制 <= API 流量限制。

此外,您可以在流控策略下添加特殊应用(APP)和特殊用户。对于特例,流控策略基础的 API 流量限制 依然有效,您需要额外设定一个阈值作为该 APP 或者该用户的流量限制值,该值不能超过策略的 API流量限制 值,同时流控策略基础的 APP流量限制 和 用户流量限制 对该 APP 或用户失效。

2.2. 插件配置

可以选择json或者yaml格式的来配置您的插件,两种格式的schema相同,可以搜索yaml to json转换工具来进行配置格式的转换,yaml格式的模板见下表

  1. ---
  2. unit: SECOND # 控制区间, 取值: SECOND, MINUTE, HOUR, DAY
  3. apiDefault: 1000 # 允许的总流量值
  4. userDefault: 30 # (可选)每个用户的默认流量最大值, 0表示不进行限制, 不能大于总流量值
  5. appDefault: 30 # (可选)每个APP允许的流量最大值, 0表示不进行限制, 不能大于总流量值
  6. specials: # (可选)特殊流控, 支持"APP"和"USER"两种特殊维度
  7. - type: "APP" # 针对不同应用(AK)进行的流控
  8. policies:
  9. - key: 10123123 # AppId, AppId的取值请在API网关控制台->应用管理->应用详情处查看
  10. value: 10 # 特殊流控值, 不能大于总流量值
  11. - key: 10123123 # AppId控
  12. value: 10 # 特殊流控值, 不能大于总流量值
  13. - type: "USER" # 针对不同的阿里云账户进行的流控
  14. policies:
  15. - key: 123455 # 阿里云账号ID, 可点击阿里云控制台左上角查看账号ID
  16. value: 100 # 特殊流控值, 不能大于总流量值

3. 参数流控配置

参数流控可以针对用户的请求参数以及条件执行进行流控,参数流控配置支持如下特性

  • 支持秒、分钟、小时、天的流控维度
  • 可以根据请求参数、系统参数设置条件,来执行不同的流控维度
  • 可以使用单个参数、或多个参数的组合来设置流控
  • 可以设置流控的范围为API或插件

3.1. 快速开始

有这样一个场景,我们希望执行如下的规则执行流控,针对每个访问的客户端IP地址,当用户使用了AppId:10001的Key做了签名认证时,设置流控为100请求/秒,对其他的场合为10请求/秒

针对这个场景我们的插件配置文件为,这里我们使用yaml来配置插件

  1. ---
  2. scope: "PLUGIN"
  3. #
  4. # 这个流控依赖两个系统参数
  5. # 1. 用户签名的AppId,通过系统参数CaAppId获取
  6. # 2. 用户来源的ClientIP,通过系统参数CaClientIp获取
  7. parameters:
  8. AppId: "System: CaAppId"
  9. ClientIP: "System: CaClientIp"
  10. rules:
  11. # 第一条流控策略,当`AppId`为`10001`时生效,对每个ClientIP限流为`100/秒`
  12. - name: "Vip"
  13. condition: "$AppId = 10001"
  14. byParameters: "ClientIP"
  15. value: 100
  16. period: SECOND
  17. # 第二条流控策略名为`PerClientIP`,对每个ClientIP限流为`10/秒`
  18. - name: "PerClientIP"
  19. byParameters: "ClientIP"
  20. value: 10
  21. period: SECOND

3.1. 插件配置

参数流控插件使用yaml或等价的json格式进行插件元数据配置。

  1. ---
  2. scope: "PLUGIN" # 流控插件的作用范围: 目前可选为"PLUGIN", "API"
  3. defaultLimit: 100 # 默认流控值,如果设置了默认流控值,
  4. defaultPeriod: SECOND # 默认流控周期
  5. defaultErrorMessage: "Throttled by 100/SECOND"
  6. parameters: # 参数列表, 可用于流控的参数
  7. clientIp: "System:CaClientIp"
  8. userId: "Token:userId"
  9. rules:
  10. - name: "ByClientIp"
  11. byParameters: "clientIp"
  12. condition: "$clientIp !in_cidr '61.7.8.8/24'"
  13. limit: 10
  14. period: MINUTE
  15. errorMessage: "Throttled by 10/MINUTE from ${clientIp}"
  16. - name: "每个用户限制10条/分钟,管理员除外"
  17. byParameters: "clientIp"
  18. condition: "$userId !like 'admin%'"
  19. limit: 10
  20. period: MINUTE
  21. - name: "每个IP限制10条/分钟"
  22. byParameters: "clientIp"
  23. condition: "$clientIp in_cidr '67.0.0.0/8'"
  24. limit: 10
  25. period: MINUTE
  26. - name: "每个用户限制15条/分钟"
  27. condition: "$userId !like 'admin%'"
  28. limit: 15
  29. period: MINUTE
  30. byParameters: "clientIp"

插件配置的字段说明如下:

  • scope(必选): 流控插件的作用范围,支持APIPLUGIN两种取值,如果多个API都绑定了同一个插件,则scope的取值会影响流控策略的作用范围,比如:某个策略取值为10次/秒
    • 当取值为API时: 流控策略在每个API中分别生效,在本例子中,每个API的限流均为10次/秒
    • 当取值为PLUGIN时: 所有绑定了本插件的API共享这个限流,如果本例子中的插件绑定了一堆API,则这一堆API的总流控限制为10次/秒
  • parameters(必选): 参与流控的参数表,参考参数与条件表达式文档中的描述
  • rules(可选): 流控策略的列表, 如果没有设置默认流控defaultLimitperiod, 则不能为空,每个流控策略包含以下字段:
    • name(必选): 流控策略的名称, 合法值为[A-Za-z0-9_-]+,在同一个插件中保持唯一
    • byParameters(必选): 流控参数,如果使用多个参数组合流控,以,分割,比如: ClientIP表示,针对每个ClientIP的取值分别进行流控,UserId,Action表示对这两个参数的组合取值分别进行流控
    • condition(可选): 如果设置了条件,只有当条件符合时,才会执行此条流控策略
    • limit(必选): 流控值, 正整数,当为-1时表示当命中此条件时不需要流控
    • period(必选): 流控周期, 取值: SECOND,MINUTE,HOUR,DAY
    • errorMessage(必选) 定制错误信息,可以以模板的方式来定义,在parameters中定义的参数,可以在${Name}的方式来配置
  • defaultLimit(可选): 默认流控值, 正整数
  • defaultPeriod(可选): 流控周期, 取值: SECOND,MINUTE,HOUR,DAY
  • defaultErrorMessage(可选): 定制错误信息,当配置了定制的错误信息后,返回的X-Ca-Error-Message头会使用定制的错误信息,这个信息无法使用参数

3.2. 参数说明

流控插件支持以下位置的参数

位置名称 适用范围 说明
Method 请求 HTTP请求方法 (大写),如: GET, POST
Path 请求 HTTP完整请求路径, 如: /path/to/query
Header 请求 使用Header:{Name}获取名字为{Name}的HTTP头的第一个值
Query 请求 使用Query:{Name}获取QueryString中名字为{Name}的第一个值
Form 请求 使用Form:{Name}获取请求Form中名字为{Name}的第一个值
Host 请求 使用Host:{Name}获取匹配到的泛域名模板参数
Parameter 请求 使用Parameter:{Name}获取用户API自定义参数中名字为Name的第一个值
System 请求 使用System:{Name}获取名字为{Name}系统参数
Token 请求 当处于jwt,oauth2授权场景时,使用Token:{Name}获取token中名字为{Name}的值

3.3. 执行规则

API网关按照如下的顺序执行参数流控

  • 插件会使用parameters的配置,从请求上下文中获取参数表
  • 所有condition执行结果为true或未配置condition的策略都会被执行
  • 如果命中策略列表中有多条策略的byParameters配置相同, 则选择配置顺序靠前的那一条执行, 其余的策略不会生

4. 配置样例

4.1. 基础流控配置样例

基础流控可支持API流控、不同AppKey、以及不同用户级别的流控

  1. ---
  2. unit: SECOND # 默认的流控单位, 支持: SECOND,MINUTE,HOUR,DAY
  3. apiDefault: 50 # API整体流控
  4. appDefault: 20 # (可选)针对每个APP的流控值, 不大于API整体流控
  5. userDefault: 30 # (可选)针对每个用户的流控值, 不大于API整体流控
  6. specials: # (可选)特殊流控, 支持"APP"和"USER"两种特殊维度
  7. - type: "APP" # 针对不同应用(AppKey)进行的流控
  8. policies:
  9. - key: 10001 # AppId, AppId的取值请在API网关控制台->应用管理->应用详情处查看
  10. value: 3 # 特殊流控值, 不大于API整体流控
  11. - key: 10003
  12. value: 40
  13. - type: "USER" # 针对不同的阿里云账户进行的流控
  14. policies:
  15. - key: 102 # 阿里云账号ID, 可点击阿里云控制台上角查看账号ID
  16. value: 10 # 特殊流控值, 不大于API整体流控
  17. - key: 233
  18. value: 35

4.2. 按照源IP进行参数限流

在这个例子中,我们配置了的限流策略,

  • 每个源IP允许100次/分钟的调用
  • 客户端IP处于58.66.66.0/24范围时,不限制访问
  • 对客户端IP为处于63.0.0.22,73.0.2.0/24范围时,访问限制为5次/天
  1. ---
  2. scope: API # 限流的作用范围,可选API, PLUGIN
  3. parameters: # 设置限流的参数,我们仅针对客户端IP进行限流, 客户端IP从系统变量`CaClientIp`中获取
  4. ClientIp: "System:CaClientIp"
  5. rules:
  6. - name: whitelist # 白名单策略, 当客户端IP符合条件时,不执行限流
  7. condition: "$ClientIp in_cidr '58.66.66.0/24'"
  8. limit: -1 # `-1`表示不进行限流
  9. - name: banList # 特殊限制策略, 当客户端IP符合条件时,按照`ClientIp`参数执行每天5次的限流
  10. condition: "$ClientIp in_cidr '63.0.0.22' or $ClientIp in_cidr '73.0.2.0/24'"
  11. byParameters: "ClientIp"
  12. limit: 5
  13. period: DAY
  14. - name: 100perIp # 默认策略,每个IP,100次/分钟访问
  15. byParameters: "ClientIp"
  16. limit: 100
  17. period: MINUTE # 周期,支持: SECOND, MINUTE, HOUR, DAY

5. 相关错误码

错误代码 Http状态码 Message 描述
T429ID 429 Throttled by INNER DOMAIN Flow Control, ${Domain} is a test domain, only 1000 requests per day 当使用默认二级域名访问时,限制1000次/天,请绑定正式域名以解除这个限制
T429IN 429 Throttled by INSTANCE Flow Control 触发当前实例的流控限制
T429GR 429 Throttled by GROUP Flow Control 触发当前分组的流控限制
T429PA 429 Throttled by API Flow Control 触发插件上的默认API流控
T429PR 429 Throttled by PLUGIN Flow Control 触发插件的特殊流控
T429UP 429 Throttled by Usage Plan Flow Control 触发使用计划的流控

6. 使用限制

  • 参数定义个数不超过16
  • 单个表达式的字符数不超过512个字符
  • 插件元数据的大小限制为16380个字符
  • 每个插件中rules最大不超过16
  • 每个rule中的byParameters最大不超过3个
  • 当限流参数的分散度太高时,可能释放掉实际使用数据不高的数据,比如:使用了天级别的源IP流控时,系统存储了过多的流控记录时,会释放掉一部分记录,在共享实例下的参数流控插件允许的不同参数个数为1000,在专享实例下的参数流控插件允许的不同参数个数为100000