跳到主要内容

限流

限流可以保护上游服务提供方,避免单个调用方、模型、团队或成员消耗过多共享网关容量。当多个应用共享同一个模型别名、服务提供方密钥或服务提供方配额时,限流尤其有用。

本指南将添加一个面向调用方的请求限制,通过网关发送流量,并确认配额超出后 AISIX 会拒绝请求。你也可以在模型别名上使用类似限制。在 AISIX Cloud 中,还可以配置更宽范围的团队和成员策略。

准备工作

请先准备以下内容:

  • 一个 Admin 和代理监听器都可用的自托管 AISIX 网关。
  • 网关 config.yaml 中的 Admin Key。
  • 一个可以处理代理请求的模型别名。如果还没有创建,请先配置服务提供方凭证模型别名

选择限流作用位置

AISIX 可以在三个位置应用限流。请根据要保护的配额选择最小适用范围:

  • 调用方 API Key:当某个应用或租户需要独立配额时使用。
  • 模型:当多个调用方 API Key 共享同一个成本较高或较脆弱的模型别名时使用。
  • 共享限流策略:当 AISIX Cloud 需要更宽范围的配额桶时使用,例如团队、成员,或团队中每个成员一个配额桶。

在 AISIX 向上游服务提供方发送请求之前,它会检查所有匹配的已配置限制。只要其中任一限制没有剩余额度,AISIX 就会用 429 拒绝请求。

下面的示例用于保护一个应用,因此将限制应用到该应用的调用方 API Key。

配置调用方限流

对应用限流最直接的方式,是把限制挂到调用方 API Key 上。在本示例中,该 API Key 每分钟只能向配置的模型别名发送一个请求。

选择一个明文调用方 API Key,设置模型别名,并在创建 Admin 资源前计算密钥哈希:

export AISIX_ADMIN_KEY="admin-local-only-change-me"
export AISIX_API_KEY="sk-rate-limit-caller"
export AISIX_MODEL="gpt-4o-prod"

AISIX_API_KEY_HASH=$(printf '%s' "${AISIX_API_KEY}" | shasum -a 256 | awk '{print $1}')

创建一个每分钟一个请求限制的调用方 API Key 资源。请求会发送到调用方 API Key 的 Admin 路由,请求体中的 rate_limit 字段定义限制;rpm 表示每分钟请求数。

curl -sS -X POST "http://127.0.0.1:3001/admin/v1/apikeys" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
-d '{
"key_hash": "'"${AISIX_API_KEY_HASH}"'",
"allowed_models": ["'"${AISIX_MODEL}"'"],
"rate_limit": {
"rpm": 1
}
}'

你应该会看到类似下面的响应:

{
"id": "4ae2b1b8-5e2c-4f44-8d8a-2f6a6f5ef7f8",
"value": {
"key_hash": "4b4f91305bd7f14a04ef6c850b3f4d0a8ce9ac67bc63f8b342ccdfd0d2f5b8f8",
"allowed_models": [
"gpt-4o-prod"
],
"rate_limit": {
"rpm": 1
}
},
"revision": 1
}

验证限流

使用受限的调用方 API Key 发送三次请求:

for i in 1 2 3; do
printf "request %s: " "${i}"
curl -sS -o /dev/null -w "%{http_code}\n" -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer ${AISIX_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "'"${AISIX_MODEL}"'",
"messages": [
{"role": "user", "content": "Hello from AISIX."}
]
}'
done

第一次请求应该会到达上游模型,后续请求则会超出每分钟一个请求的限制:

request 1: 200
request 2: 429
request 3: 429

当 AISIX 拒绝请求时,响应会使用代理错误格式;如果限流器能够计算重试窗口,还会包含 Retry-After

HTTP/1.1 429 Too Many Requests
retry-after: 60

{
"error": {
"message": "request limit exceeded (requests)",
"type": "rate_limit_exceeded"
}
}

其他限流类型

上面的示例限制的是请求数量。AISIX 也可以限制 token 用量和进行中的请求数:

  • 请求限制用于限制某个时间窗口内可发送的请求数,例如每分钟请求数。
  • token 限制用于限制某个时间窗口内的 prompt 和 completion token,例如每分钟 token 数。AISIX 会在上游响应返回服务提供方报告的用量后记录 token 用量,因此一次大响应可能消耗剩余 token 容量,并导致后续请求被拒绝。
  • 并发限制用于限制同一时间可进行中的请求数量。

在内联 rate_limit 对象中,请求数字段使用 rpsrpmrphrpd;token 字段使用 tpmtpd;并发使用 concurrency

默认情况下,内联限流计数器只在各自网关进程内生效。在使用默认内存后端的多实例自托管部署中,设置上限时需要考虑实例数量;如果配额必须更严格,应将同一租户、调用方 API Key 或模型别名路由到固定网关组。

当某个模型别名的所有调用方需要共享同一限制时,可以把相同的 rate_limit 对象挂到模型上。通过 /admin/v1/models 创建或更新模型时添加即可。下面的示例允许每分钟最多 300 个请求和 20 个并发请求:

{
"display_name": "gpt-4o-prod",
"provider": "openai",
"model_name": "gpt-4o",
"provider_key_id": "YOUR_PROVIDER_KEY_ID",
"rate_limit": {
"rpm": 300,
"concurrency": 20
}
}

团队或成员级限制请使用共享策略。

信息

共享策略在 AISIX Cloud 中配置。Admin API 不支持创建共享策略。

下面的示例展示了一个共享策略,将某个团队配额桶限制为每分钟 1,000,000 个 token:

{
"name": "team-acme-tpm",
"scope": "team",
"scope_ref": "team-uuid-acme",
"window": "minute",
"max_tokens": 1000000
}

对于共享策略,token 限制使用分钟窗口。请求数限制可以使用秒、分钟或小时窗口。

选择计数器存储

自托管网关通过启动配置决定限流计数器保存在哪里。

默认内存后端会把计数器保存在每个网关进程中。对于单网关实例,这是精确的。在负载均衡器后面的多实例部署中,每个实例只统计自己处理的流量,因此实际集群级上限可能高于配置的单进程限制。

当多个网关实例必须执行同一个共享配额窗口时,请使用 Redis 后端:

config.yaml
ratelimit:
backend: redis
redis:
mode: single
url: redis://127.0.0.1:6379/

使用 Redis 后端时,请求、token 和并发计数器会在使用同一个 Redis 后端的多个网关实例之间共享。选择 Redis 后端时,网关要求配置 ratelimit.redis 块。并发槽位会在 concurrency_ttl_secs 后回收,默认值为 300 秒。

Redis 连接模式

ratelimit.redis.mode 字段用于选择 AISIX 连接 Redis 的方式。

单个 Redis 端点使用 single

config.yaml
ratelimit:
backend: redis
redis:
mode: single
url: redis://127.0.0.1:6379/

Redis Cluster 种子节点使用 cluster

config.yaml
ratelimit:
backend: redis
redis:
mode: cluster
nodes:
- redis://10.0.0.1:6379/
- redis://10.0.0.2:6379/

由 Sentinel 管理的主节点使用 sentinel

config.yaml
ratelimit:
backend: redis
redis:
mode: sentinel
sentinels:
- redis://10.0.0.1:26379/
- redis://10.0.0.2:26379/
master_name: mymaster

对于 cluster 和 sentinel 模式,如果 Redis 数据节点需要 ACL 认证,请设置 usernamepassword。在 sentinel 模式中,Sentinel 节点凭证应放在 sentinel URL 中,而 usernamepassworddatabase 会作用于发现到的 Redis 主节点。

下一步

你已经配置了面向调用方的限流,并了解了配额超出后 AISIX 如何拒绝流量。接下来继续阅读缓存,复用符合条件的 Chat Completion 响应。