AI Token限流

本文介绍AI Token限流。

背景信息

ai-token-ratelimit插件实现了基于特定键值实现token限流,键值来源可以是 URL 参数、HTTP 请求头、客户端 IP 地址、consumer 名称、cookie中 key 名称。其借助Redis实现全局的token限流,工作流程如下图所示:

image

配置说明

配置项

数据类型

必填

默认值

说明

rule_name

string

-

限流规则名称,根据限流规则名称+限流类型+限流key名称+限流key对应的实际值来拼装Redis key。

rule_items

array of object

-

限流规则项,按照rule_items下的排列顺序,匹配第一个rule_item后命中限流规则,后续规则将被忽略。

rejected_code

int

429

请求被限流时,返回的HTTP状态码。

rejected_msg

string

Too many requests

请求被限流时,返回的响应体。

redis

object

-

Redis相关配置。

rule_items中每一项的配置字段说明。

配置项

数据类型

必填

默认值

说明

limit_by_header

string

否,limit_by_*中选填一项。

-

配置获取限流键值的来源 HTTP 请求头名称。

limit_by_param

string

否,limit_by_*中选填一项。

-

配置获取限流键值的来源 URL 参数名称。

limit_by_consumer

string

否,limit_by_*中选填一项。

-

根据 consumer 名称进行限流,无需添加实际值。

limit_by_cookie

string

否,limit_by_*中选填一项。

-

配置获取限流键值的来源 Cookie中 key 名称。

limit_by_per_header

string

否,limit_by_*中选填一项。

-

按规则匹配特定 HTTP 请求头,并对每个请求头分别计算限流,配置获取限流键值的来源 HTTP 请求头名称,配置limit_keys时支持正则表达式或*

limit_by_per_param

string

否,limit_by_*中选填一项。

-

按规则匹配特定 URL 参数,并对每个参数分别计算限流,配置获取限流键值的来源 URL 参数名称,配置limit_keys时支持正则表达式或*

limit_by_per_consumer

string

否,limit_by_*中选填一项。

-

按规则匹配特定 consumer,并对每个 consumer 分别计算限流,根据 consumer 名称进行限流,无需添加实际值,配置limit_keys时支持正则表达式或*

limit_by_per_cookie

string

否,limit_by_*中选填一项。

-

按规则匹配特定 Cookie,并对每个 Cookie 分别计算限流,配置获取限流键值的来源 Cookie中 key 名称,配置limit_keys时支持正则表达式或*

limit_by_per_ip

string

否,limit_by_*中选填一项。

-

按规则匹配特定 IP,并对每个 IP 分别计算限流,配置获取限流键值的来源 IP 参数名称,从请求头获取,以from-header-对应的header名,示例:from-header-x-forwarded-for,直接获取对端socket ip,配置为from-remote-addr

limit_keys

array of object

-

配置匹配键值后的限流次数。

limit_keys中每一项的配置字段说明。

配置项

数据类型

必填

默认值

说明

key

string

-

匹配的键值,limit_by_per_header,limit_by_per_param,limit_by_per_consumer,limit_by_per_cookie 类型支持配置正则表达式(以regexp:开头后面跟正则表达式)或者*(代表所有),正则表达式示例:regexp:^d.*(以d开头的所有字符串);limit_by_per_ip支持配置 IP 地址或 IP 段。

token_per_second

int

否,token_per_secondtoken_per_minutetoken_per_hourtoken_per_day 中选填一项。

-

允许每秒请求Token数。

token_per_minute

int

否,token_per_secondtoken_per_minutetoken_per_hourtoken_per_day 中选填一项。

-

允许每分钟请求Token数。

token_per_hour

int

否,token_per_secondtoken_per_minutetoken_per_hourtoken_per_day 中选择填写一项。

-

允许每小时请求Token数。

token_per_day

int

否,token_per_secondtoken_per_minutetoken_per_hourtoken_per_day 中选填一项。

-

允许每天请求Token数。

redis中每一项的配置字段说明。

配置项

数据类型

必填

默认值

说明

service_name

string

必填

-

Redis 服务名称,带服务类型的完整 FQDN 名称,例如 my-redis.dns、redis.my-ns.svc.cluster.local。

service_port

int

服务类型为固定地址(static service)默认值为80,其他为6379。

输入Redis服务的服务端口。

username

string

-

Redis 用户名。

password

string

-

Redis 密码。

timeout

int

1000

Redis 连接超时时间,单位毫秒。

配置示例

识别请求参数 apikey,进行区别限流。

rule_name: default_rule
rule_items:
  - limit_by_param: apikey
    limit_keys:
      - key: 9a342114-ba8a-11ec-b1bf-00163e1250b5
        token_per_minute: 10
      - key: a6a6d7f2-ba8a-11ec-bec2-00163e1250b5
        token_per_hour: 100
  - limit_by_per_param: apikey
    limit_keys:
      # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10tps
      - key: "regexp: ^a.*"
           token_per_second: 10
      # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100tpm
      - key: "regexp: ^b.*"
        token_per_minute: 100
      # 兜底用,匹配所有请求,每个apikey对应的请求1000tph
      - key: "*"
        token_per_hour: 1000
redis:
  service_name: redis.static

识别请求头 x-ca-key,进行区别限流。

rule_name: default_rule
rule_items:
  - limit_by_header: x-ca-key
    limit_keys:
        - key: 102234
        token_per_minute: 10
      - key: 308239
        token_per_hour: 10
  - limit_by_per_header: x-ca-key
    limit_keys:
      # 正则表达式,匹配以a开头的所有字符串,每个apikey对应的请求10tps
      - key: "regexp: ^a.*"
        token_per_second: 10
      # 正则表达式,匹配以b开头的所有字符串,每个apikey对应的请求100tpm
      - key: "regexp: ^b.*"
        token_per_minute: 100
      # 兜底用,匹配所有请求,每个apikey对应的请求1000tph
      - key: "*"
        token_per_hour: 1000

redis:
  service_name: redis.static

根据请求头 x-forwarded-for,获取对端IP,进行区别限流。

rule_name: default_rule
rule_items:
  - limit_by_per_ip: from-header-x-forwarded-for
    limit_keys:
      # 精确ip
      - key: 1.1.1.1
        token_per_day: 10
      # ip段,符合这个ip段的ip,每个ip 100tpd
      - key: 1.1.1.0/24
        token_per_day: 100
      # 兜底用,即默认每个ip 1000tpd
      - key: 0.0.0.0/0
        token_per_day: 1000
redis:
  service_name: redis.static

识别consumer,进行区别限流。

rule_name: default_rule
rule_items:
  - limit_by_consumer: ''
    limit_keys:
      - key: consumer1
        token_per_second: 10
      - key: consumer2
        token_per_hour: 100
  - limit_by_per_consumer: ''
    limit_keys:
      # 正则表达式,匹配以a开头的所有字符串,每个consumer对应的请求10tps
      - key: "regexp: ^a.*"
        token_per_second: 10
      # 正则表达式,匹配以b开头的所有字符串,每个consumer对应的请求100tpm
      - key: "regexp: ^b.*"
        token_per_minute: 100
      # 兜底用,匹配所有请求,每个consumer对应的请求1000tph
      - key: "*"
        token_per_hour: 1000   

redis:
  service_name: redis.static

识别cookie中的键值对,进行区别限流。

rule_name: default_rule
rule_items:
  - limit_by_cookie: key1
    limit_keys:
      - key: value1
        token_per_minute: 10
      - key: value2
        token_per_hour: 100
  - limit_by_per_cookie: key1
    limit_keys:
      # 正则表达式,匹配以a开头的所有字符串,每个cookie中的value对应的请求10tps
      - key: "regexp: ^a.*"
        token_per_second: 10
      # 正则表达式,匹配以b开头的所有字符串,每个cookie中的value对应的请求100tpm
      - key: "regexp: ^b.*"
        token_per_minute: 100
      # 兜底用,匹配所有请求,每个cookie中的value对应的请求1000tph
      - key: "*"
        token_per_hour: 1000 
rejected_code: 200
rejected_msg: '{"code":-1,"msg":"Too many requests"}'
redis:
  service_name: redis.static

限流示例

rule_name: default_rule
rule_items:
  - limit_by_per_ip: from-remote-addr
    limit_keys:
      - key: 0.0.0.0/0
        token_per_minute: 100
redis:
  service_name: redis.static
  service_port: 6379
  username: default
  password: '123456'
rejected_code: 429
rejected_msg: "您的请求频率过高,请稍后再试。"

以上配置限制了每个IP一分钟内最多使用100个token,当触发限流时,网关会返回用户自定义的限流消息,示例如下:

image