限流
限流可以保护上游服务提供方,避免单个调用方或模型别名消耗过多共享网关容量。当多个应用共享同一个模型别名、上游凭证或服务提供方配额时,限流尤其有用。
本指南将向自托 管网关添加一个面向调用方的请求限制。你将通过网关发送流量,并确认配额超出后 AISIX 会拒绝请求。你也可以在模型别名上使用类似限制。
准备工作
请先准备以下内容:
- 一个 Admin 和代理监听器都可用的自托管 AISIX 网关。
- 网关
config.yaml中的 Admin Key。 - 一个可以处理代理请求的模型别名。如果还没有创建,请先配置服务提供方凭证和模型别名。
选择限流作用位置
在自托管网关中,可以在调用方 API Key 或模型上配置限流。请根据要保护的配额选择最小适用范围:
- 调用方 API Key:当某个应用或租户需要独立配额时使用。
- 模型:当多个调用方 API Key 共享同一个成本较高或容量受限的模型别名时使用。
下面的示例用于保护一个应用,因此将限制应用到该应用的调用方 API Key。
配置调用方限流
选择应用将发送的调用方 API Key 值,设置模型别名,并在创建 Admin 资源前计算密钥哈希。本示例允许该 Key 每分钟向配置的模型别名发送一个请 求:
export AISIX_ADMIN_KEY="YOUR_ADMIN_KEY"
export AISIX_API_KEY="YOUR_CALLER_API_KEY"
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
}
验证限流
在 AISIX 向上游服务提供方发送请求之前,它会检查所有匹配的已配置限制。只要其中任一限制没有剩余额度,AISIX 就会用 429 拒绝请求。
使用受限的调用方 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 拒绝请求时,响应以 HTTP/1.1 429 Too Many Requests 开头。它使用代理错误格式;如果限流器能够计算重试窗口,还会包含 Retry-After:
{
"error": {
"message": "request limit exceeded (requests)",
"type": "rate_limit_exceeded"
}
}
限流字段
上面的示例限制的是请求数量。挂在调用方 API Key 和模型别名上的限流还可以限制 token 用量和进行中的请求数。每个字段都是可选的。当某个字段被省略时,AISIX 不会强制该项限制。
| 字段 | 含义 | 窗口 |
|---|---|---|
rps | 每秒请求数 | 1 秒 |
rpm | 每 分钟请求数 | 60 秒 |
rph | 每小时请求数 | 3,600 秒 |
rpd | 每天请求数 | 86,400 秒 |
tpm | 每分钟 Token 数 | 60 秒 |
tpd | 每天 Token 数 | 86,400 秒 |
concurrency | 进行中的请求数 | 不设窗口 |
请求字段会在 AISIX 将请求发送到上游之前统计请求数。Token 字段限制服务提供方报告的 Token 总量,包括提示词和补全 Token,以及 Anthropic 单独报告的提示词缓存创建和读取 Token。OpenAI 的缓存 Token 已包含在提示词 Token 中,因此不会重复计算。AISIX 会在上游响应返回、获得服务提供方报告的用量后记录 Token 用量,因此一次大响应可能消耗剩余 Token 容量,并导致后续请求被拒绝。并发限制同一时间可进行中的请求数量。
Token 限制仅支持分钟和天窗口。
默认情况下,限流计数器只在各自网关进程内生效。在使用默认内存后端的多实例自托管部署中,设置上限时需要考虑实例数量。如果配额必须更严格,应将同一租户、调用方 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
}
}
为自托管网关选择计数器存储
自托管网关通过启动配置决定限流计数器保存在哪里。
默认内存后端会把计数器保存在每个网关进程中。对于单网关实例,这是精确的。在负载均衡器后面的多实例部署中,每个实例只统计自己处理的流量。因此,实际集群级上限可能高于配置的单进程限制。
当多个网关实例 必须执行同一个共享配额窗口时,请使用 Redis 后端:
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:
ratelimit:
backend: redis
redis:
mode: single
url: redis://127.0.0.1:6379/
Redis Cluster 种子节点使用 cluster:
ratelimit:
backend: redis
redis:
mode: cluster
nodes:
- redis://10.0.0.1:6379/
- redis://10.0.0.2:6379/
由 Sentinel 管理的主节点使用 sentinel:
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 认证,请设置 username 和 password。在 sentinel 模式中,Sentinel 节点凭证应放在 sentinel URL 中,而 username、password 和 database 会作用于发现到的 Redis 主节点。
托管限流策略
AISIX 托管控制面支持上面描述的调用方 API Key 和模型限制。它还为 API Key、模型、团队、成员,以及团队中每个成员的默认值提供共享限流策略。
当你需要秒或小时级请求数窗口,或配额需要作用于团队或成员作用域时,请使用共享策略。共享策略使用 window 搭配 max_requests、max_tokens 或两者。请求数限制可以使用秒、分钟或小时窗口。token 限制应使用分钟窗口。
下面的示例展示了一个共享策略,将某个团队配额桶限制为每分钟 1,000,000 个 token:
{
"name": "team-acme-tpm",
"scope": "team",
"scope_ref": "team-uuid-acme",
"window": "minute",
"max_tokens": 1000000
}
当共享策略同时包含请求和 token 上限时,请使用分钟窗口,让两个上限由同一策略强制执行。
下一步
你已经配置了面向调用方的限流,并了解了配额超出后 AISIX 如何拒绝流量。接下来继续阅读缓存,复用符合条件的 Chat Completion 响应。