限流
限流可以保护服务提供方的处理能力,并防止某个调用方、模型、团队或成员耗尽共享配额。AISIX 会检查与请求匹配的每项限制。如果任一匹配的限制已耗尽,网关会在调用服务提供方之前返回 429。
自托管网关将限制直接附加到调用方 API Key 或模型别名上。托管部署既支持这些限制,也支持面向 API Key、模型、团队、成员以及团队内每个成员的策略。
选择限流作用域
在自托管网关中,可以将内联限流配置附加到调用方 API Key 或模型上。请选择能够表示待控流量的最小作用域:
- 如果某个应用或租户需要独立配额,请使用调用方 API Key。
- 如果模型别名的所有调用方需要共享一个配额,请使用模型。
托管部署支持这些内联限制,以及具有额外作用域的独立策略。有关这些选项,请参阅托管限流策略。
以下自托管操作会将限制附加到某个应用的调用方 API Key 上,以保护该应用。
配置调用方限制
本示例创建一个自托管调用方 API Key,它每分钟可向某个模型别名发送一个请求。
前置条件
请准备以下资源和访问权限:
- Admin 和代理监听器均可用的自托管 AISIX 网关。
- 网关
config.yaml中的 Admin Key。 - 能够处理代理请求的模型别名。如果还没有创建,请先配置服务提供方凭证和模型别名。
设置示例值
设置 Admin Key、明文调用方 API Key 和模型别名。将调用方 API 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
通过 AISIX Admin API 创建调用方 API Key 资源。rate_limit 对象将每分钟请求数限制为 1:
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/api_keys" \
-H "Authorization: Bearer ${AISIX_ADMIN_KEY}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"key_hash": "${AISIX_API_KEY_HASH}",
"allowed_models": ["${AISIX_MODEL}"],
"rate_limit": {
"rpm": 1
}
}
EOF
响应包含已存储的资源 ID、Key 哈希值、配置的限制和资源修订版本:
{
"id": "4ae2b1b8-5e2c-4f44-8d8a-2f6a6f5ef7f8",
"value": {
"key_hash": "4b4f91305bd7f14a04ef6c850b3f4d0a8ce9ac67bc63f8b342ccdfd0d2f5b8f8",
"allowed_models": [
"gpt-4o-prod"
],
"rate_limit": {
"rpm": 1
}
},
"revision": 1
}
本示例仅展示完成此任务所需的字段。有关完整的调用方 API Key 模式,请参阅 AISIX Admin API。
验证限流
使用受限的调用方 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" \
--data-binary @- <<EOF
{
"model": "${AISIX_MODEL}",
"messages": [
{
"role": "user",
"content": "Hello from AISIX."
}
]
}
EOF
done
第一个请求应会到达上游模型。在同一个固定窗口内,其余请求应会超出限制:
request 1: 200
request 2: 429
request 3: 429
与 OpenAI 兼容的限流拒绝响应会返回 429 Too Many Requests,并使用代理错误格式:
{
"error": {
"message": "request limit exceeded (requests)",
"type": "rate_limit_exceeded"
}
}
请求数和 Token 限制的拒绝响应会包含 Retry-After,因为它们的固定窗口可以提供重置时间。并发限制的拒绝响应 没有基于窗口的重试提示。成功的 Chat Completions 响应还可以包含调用方 API Key 的限流状态;请参阅请求头和错误码。
限流字段
调用方 API Key 和模型别名使用相同的 rate_limit 字段。每个字段都是可选的。省略某个字段时,AISIX 不会对该维度强制执行限制。
| 字段 | 限制 | 固定窗口 |
|---|---|---|
rps | 每秒请求数 | 1 秒 |
rpm | 每分钟请求数 | 60 秒 |
rph | 每小时请求数 | 3,600 秒 |
rpd | 每天请求数 | 86,400 秒 |
tpm | 每分钟 Token 数 | 60 秒 |
tpd | 每天 Token 数 | 86,400 秒 |
concurrency | 进行中的请求数 | 不使用窗口 |
这三个限制维度会在请求路径的不同阶段计数:
| 维度 | AISIX 检查时机 | AISIX 记录用量时机 |
|---|---|---|
| 请求数 | 调用服务提供方之前 | 在调用服务提供方之前的检查期间;较早匹配的层可能已增加计数,然后请求才被较后的层拒绝 |
| Token | 调用服务提供方之前,使用当前窗口中已记录的 Token 数 | 上游响应报告用量之后 |
| 并发数 | 调用服务提供方之前 | 一直占用到响应或流完成,然后释放 |
Token 限制包括提示词和补全 Token。 对于 Anthropic 流量,还包括提示词缓存创建和缓存读取 Token,Anthropic 会将它们与输入 Token 分开报告。OpenAI 缓存 Token 已包含在提示词 Token 中,因此 AISIX 不会重复计数。
由于服务提供方会在生成响应后才报告用量,导致 Token 数超过限制的请求可能仍会成功完成。该请求的 Token 用量可能耗尽当前窗口的剩余容量,并使后续请求被拒绝。
Token 限制仅支持分钟和天窗口。直接附加到调用方 API Key 或模型的限制不提供每秒或每小时 Token 字段。
配置模型限制
如果某个模型别名的所有调用方需要共享限制,请将相同的 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 会在两个桶中预留容量。任一桶耗尽都会拒绝请求。
直接模型作为路由模型或语义路由器的目标时,模型限制同样适用。路由分发会跳过已超出自身限制的目标,并继续尝试其余目标;当所有目标都超出限制时,请求返回 429。语义分发会执行所选目标的限制,并在该目标没有剩余容量时返回 429。对同一模型的直接请求和路由请求共享其限制桶。
当模型服务提供方透传请求正文通过别名或模型服务提供方原生名称指定模型时,模型限制同样适用。透传与建模路由共享同一限制桶,但只有请求计数字段会累积:透传会原样转发正文,不解析模型服务提供方报告的 Token 用量,因此 tpm 和 tpd 永远不会统计透传流量。已耗尽的 Token 窗口在重置前仍 会拒绝透传请求。
为自托管网关选择计数器存储
网关启动配置决定限流计数器是仅存在于单个进程,还是由多个网关实例共享。该设置适用于该网关强制执行的内联限制和托管策略。
| 后端 | 计数器作用域 | 适用场景 |
|---|---|---|
| 默认的内存后端 | 单个网关进程 | 由单个实例强制执行限制,或可以接受每实例配额。 |
| Redis | 使用同一 Redis 后端的所有网关实例 | 部署必须强制执行一个共享的请求数、Token 数或并发数配额。 |
使用内存后端时,每个网关实例只统计它处理的流量。因此,在流量均匀分布到多个实例的部署中,一个窗口内实际允许的流量总量可能超过配置的单进程限制。一致性路由可以降低某个调用方或租户的这种差异,但 Redis 才是共享计数器方案。
当多个网关实例必须强制执行同一配额时,请配置 Redis:
ratelimit:
backend: redis
redis:
mode: single
url: redis://127.0.0.1:6379/
当 ratelimit.backend 为 redis 时,网关要求配置 ratelimit.redis 块。如果缺少选定的 Redis 配置,或无法连接 Redis,网关将启动失败。
网关成功启动后,如果 Redis 随后中断,限流会降级为进程本地计数器。请求仍受每进程限制的保护,但中断期间部署无法强制执行单一的集群级配额。中断期间的计数不会回写 Redis,因此恢复后,计数器可能仍不一致,直到当前活动窗口结束。
请求完成时,Redis 支持的并发槽位会被释放。concurrency_ttl_secs 会回收由实例崩溃或请求中断遗留的槽位,默认值为 300 秒。
Redis 连接模式
ratelimit.redis.mode 字段用于选择 Redis 部署类型,并决定必填的连接字段。前一个示例使用 single 模式和单个 url。
对 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
必填字段如下:
| 模式 | 必填连接字段 |
|---|---|
single | url |
cluster | 一个或多个 nodes 条目 |
sentinel | 一个或多个 sentinels 条目和 master_name |
对于 cluster 和 sentinel 模式,如果 Redis 数据节点需要 ACL 身份认证,请设置 username 和 password。在 sentinel 模式中,Sentinel 节点凭证应位于 Sentinel URL 中,而 username、password 和 database 应用于发现到的 Redis 主节点。
托管限流策略
AISIX 托管控制面支持上述调用方 API Key 和模型限制。它还会下发面向 API Key、模型、团队、成员以及团队内每个成员的共享限流策略。
一个托管请求可能同时匹配多项限制。这些限制可能包括内联调用方 API Key 和模型限制,以及针对其 API Key、模型、团队或成员的策略。每项匹配的限制都必须有剩余容量,请求才能继续。
这些策略作用域的计数方式如下:
| 策略作用域 | 匹配的流量 | 桶行为 |
|---|---|---|
| API Key | 使用选定 Key 通过身份认证的请求 | 该 Key 使用一个桶 |
| 模型 | 解析到选定模型的请求 | 该模型的调用方共享一个桶 |
| 团队 | 调用方 API Key 绑定到选定团队的请求 | 一个共享团队桶 |
| 成员 | 调用方 API Key 绑定到选定成员的请求 | 该成员的所有 Key 共享一个成员桶 |
| 团队中的每个成员 | 调用方 API Key 同时绑定到选定团队和某个成员的请求 | 该团队的每个成员各自使用一个独立桶 |
团队策略为整个团队提供一个共享桶。团队内的每成员限制为每个成员提供相同大小的独立桶,因此某个成员无法消耗其他成员的配额。只有团队成员身份并不会选中任一策略;匹配取决于调用方 API Key 携带的团队和成员绑定。
当需要秒或小时级请求数窗口,或配额应用于团队或成员作用域时,请使用共享策略。共享策略使用 window 与 max_requests、max_tokens 或两者的组合。请求数限制可以使用秒、分钟或小时窗口。Token 上限必须使用分钟窗口。
在控制台中配置策略
在需要控制网关流量的环境中创建策略:
- 打开环境,然后选择 Rate limits。
- 选择 New policy。
- 输入 Name,选择 Scope,然后选择目标资源。
- 选择 Window,然后输入 Max requests、Max tokens 或两者。
- 选择 Create policy。
至少需要配置一个上限。一个环境只能包含一项针对同一作用域和目标的策略。创建后不能更改作用域和目标;要针对其他资源,请删除并重新创建策略。
调用方 API Key 和模型页面还会提供前文所述七个 rate_limit 字段的内联限制编辑器。这些限制属于资源本身。Rate limits 页面管理本节介绍的独立策略。
使用 Cloud Admin API
要通过自动化创建策略,请使用具有写入作用域的组织 Admin Token。设置控制面基础 URL、环境 ID 和目标资源 ID:
export AISIX_CP_API="https://<your-cp-api-host>/api"
export AISIX_ADMIN_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="11111111-1111-4111-8111-111111111111"
export TEAM_ID="22222222-2222-4222-8222-222222222222"
创建一项策略,将选定团队的配额精确限制为每分钟 1,000,000 个 Token:
curl -sS -X POST "${AISIX_CP_API}/environments/${ENV_ID}/rate_limits" \
-H "Authorization: Bearer ${AISIX_ADMIN_TOKEN}" \
-H "Content-Type: application/json" \
--data-binary @- <<EOF
{
"name": "team-acme-tpm",
"scope": "team",
"scope_ref": "${TEAM_ID}",
"window": "minute",
"max_tokens": 1000000
}
EOF
请求成功时会返回 201 Created 以及新策略:
{
"rate_limit_policy": {
"id": "33333333-3333-4333-8333-333333333333",
"env_id": "11111111-1111-4111-8111-111111111111",
"name": "team-acme-tpm",
"scope": "team",
"scope_ref": "22222222-2222-4222-8222-222222222222",
"window": "minute",
"max_requests": null,
"max_tokens": 1000000,
"created_at": "2026-07-16T08:00:00Z",
"updated_at": "2026-07-16T08:00:00Z"
}
}
如果环境中已有针对同一作用域和目标的策略,API 会返回 409 Conflict。有关列出、获取、更新和删除操作,请参阅 Cloud Admin API 参考。
当共享策略同时包含请求数和 Token 上限时,请选择分钟窗口,以便 AISIX 强制执行两个上限。秒和小时策略仅接受 max_requests。
共享策略是托管控制面资源。自托管 AISIX Admin API 不提供它们的 CRUD 路由。