You need to enable JavaScript to run this app.
文档中心
API 网关

API 网关

复制全文
下载 pdf
最佳实践
基于 API 网关实现多时间窗口的 Token 限流
复制全文
下载 pdf
基于 API 网关实现多时间窗口的 Token 限流
当 API 网关承接大语言模型调用时,单个调用方可能在短时间内消耗大量 Token。通过 Token 限流插件,可以在指定的时间窗口内,基于路由、服务级别,按消费者分配 Token 配额,更稳妥地控制资源使用与成本。本文为您说明 AI 场景下的 Token 限流配置方法和示例。​
操作场景​
如果同一套 AI 能力需要面向多个调用方开放,且不同调用方的调用频率、预算或优先级不同,建议使用 Token 限流插件进行配额控制。该插件属于流量管控类插件,可绑定在服务或路由上,支持多时间窗口的复合限流策略,针对不同消费者配置独立的 Token 配额,实现差异化的流量管控。​
前提条件​
  • 已创建标准型网关实例,详情请参见 创建实例。​
操作步骤​
创建 AI Token 限流插件仅支持通过使用 API 接口的方式,以下为您提供 Go 语言 SDK 方式进行创建。相关 API 接口说明和 SDK 示例如下:​
​
API 文档链接​
功能说明​
首次为作用对象(服务或路由)创建插件绑定,将 Token 限流插件关联到指定的服务或路由上。​
修改已有插件绑定的配置,如调整 Token 配额、消费者规则等。也可通过将Enable字段设置为false来停用插件,而无需删除绑定。​
查询指定作用对象(服务或路由)的插件绑定详情,包括当前配置、启用状态和消费者配额等信息。​
​
​
package main​
​
import (​
"encoding/json"​
"fmt"​
​
"github.com/volcengine/volcengine-go-sdk/service/apig"​
"github.com/volcengine/volcengine-go-sdk/volcengine"​
"github.com/volcengine/volcengine-go-sdk/volcengine/credentials"​
"github.com/volcengine/volcengine-go-sdk/volcengine/session"​
)​
​
const (​
accessKey = "TODO_AK" // 火山引擎 AccessKey,访问密钥 ID​
secretKey = "TODO_SK" // 火山引擎 SecretKey,私有访问密钥​
region = "cn-beijing" // API 网关实例所在地域​
routeID = "TODO_ROUTE_ID" // 需要绑定插件的路由 ID​
)​
​
func main() {​
// 初始化 volcengine SDK 会话,配置地域与静态密钥凭证​
sess, err := session.NewSession(volcengine.NewConfig().​
WithRegion(region).​
WithCredentials(credentials.NewStaticCredentials(accessKey, secretKey, "")))​
if err != nil {​
panic(fmt.Sprintf("创建session失败: %v", err))​
}​
​
// 创建 APIG (API 网关)服务客户端​
svc := apig.New(sess)​
​
// wasm‑rate‑limit 插件配置​
pluginConfig := map[string]any{​
"Rules": []any{​
map[string]any{​
"Name": "tokens", // 规则名称​
"Key": map[string]any{​
"Position": "Consumer", //限流键的定位方式,仅支持按消费则维度​
},​
"Value": "PromptTokenAndCompletionToken",//表示同时统计输入(Prompt)和输出(Completion)Token​
"Matches": []any{​
map[string]any{​
"Mode": "Exact", //匹配模式,当前取值为精确匹配​
"Exact": "user-a", //精确匹配的目标值,填写消费者名称​
"Limits": []any{​
map[string]any{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 10000000,// 阈值:1000 万 token​
},​
map[string]any{​
"TimeWindow": 604800, // 时间窗口:一周,单位秒​
"Threshold": 50000000,// 阈值:5000 万 token​
},​
},​
},​
},​
},​
},​
}​
​
// 将插件配置 map 序列化为 JSON 字符串,APIG 接口要求 PluginConfig 传入 JSON 字符串​
bytes, err := json.Marshal(pluginConfig)​
if err != nil {​
panic(fmt.Sprintf("序列化插件配置失败: %v", err))​
}​
fmt.Printf("插件配置JSON:\n%s\n", string(bytes))​
​
// 创建插件绑定:将 wasm‑rate‑limit 绑定到指定路由​
_, err = svc.CreatePluginBinding(&apig.CreatePluginBindingInput{​
PluginName: volcengine.String("wasm-rate-limit"), // 插件名称:Token 限流插件​
Scope: volcengine.String("ROUTE"), // 绑定范围:ROUTE 路由级别,可选 API/GATEWAY 等​
Target: volcengine.String(routeID), // 绑定目标 ID,这里填入路由 ID​
Enable: volcengine.Bool(true), // 是否开启插件绑定,true 启用​
PluginConfig: volcengine.String(string(bytes)), // 插件自定义配置,JSON 格式字符串​
})​
if err != nil {​
panic(fmt.Sprintf("创建插件绑定失败: %v", err))​
}​
​
// 查询已创建的插件绑定,根据插件名、作用域、目标路由 ID 获取绑定详情​
res, err := svc.GetPluginBinding(&apig.GetPluginBindingInput{​
PluginName: volcengine.String("wasm-rate-limit"),​
Scope: volcengine.String("ROUTE"),​
Target: volcengine.String(routeID),​
})​
if err != nil {​
panic(fmt.Sprintf("查询插件绑定失败: %v", err))​
}​
​
// 打印返回的插件配置内容​
fmt.Printf("查询返回PluginConfig:\n%s\n", *res.PluginConfig)​
}​
​
Token 限流插件配置​
Token 限流插件的配置以规则(Rules)为核心,支持为不同的消费者设置差异化的 Token 配额。当配置多个规则时,规则同时生效,规则中的匹配规则按从上到下的顺序匹配,第一个命中的匹配规则生效并执行限流。​
规则(Rule)​
​
字段​
说明​
Name​
规则名称,仅用于识别与日志展示,同一插件下可重复。​
Key​
限流键的定位方式,目前仅支持Consumer,即按消费者维度进行限流。​
Value​
限流计量的 Token 类型,配置为PromptTokenAndCompletionToken表示同时统计输入(Prompt)和输出(Completion)Token。​
Matches​
一组匹配规则,用于判断当前请求是否命中该规则。​
​
匹配规则(Match)​
​
字段​
说明​
Mode​
匹配模式。取值:​
  • Any:表示任意匹配,所有请求均命中。​
  • Exact:表示精确匹配,需配合Exact字段指定目标值。​
Exact​
精确匹配的目标值,仅在Mode为Exact时使用。按消费者维度限流时填写消费者名称。​
Limits​
一组限流策略,定义特定时间窗口内的限额。​
​
限流策略(Limit)​
注意​
  • 同一匹配规则下可配置多条限流策略,任一策略触发限流,请求即被拒绝并返回 HTTP 429。​
  • 时间窗口计算时会默认带上一定的偏移值,使得按天或按周限流能够在每周一北京时间 0 点统一重置。​
  • 您可以通过TimeWindow或Period参数配置时间窗口的大小,两个参数不可同时配置。​
  • 通过TimeWindow参数配置月度限流时,需要配置具体天数所对应的秒数,例如:30 天所对应的秒数为 2592000 秒。为方便您更便捷的配置月度限流,可以通过配置参数Period按自然月限流。配置示例如下:​
  • 您在 9 月 2 日 12 时 00 分 00 秒通过TimeWindow参数配置了 30 天的秒数时间窗口(2592000 秒),那么本次限流的截止日期为 10 月 2 日 11 时 59 分 59 秒,为期 30 天。​
  • 您在 9 月 2 日 12 时 00 分 00 秒通过Period参数配置月度限流,那么本次限流的截止日期为 9 月 30 日 23 时 59 分 59 秒。​
​
字段​
说明​
是否必填​
TimeWindow​
时间窗口大小,单位为秒。​
否​
Period​
周期类型,配置为Monthly表示按自然月限流。​
否​
Threshold​
限流阈值,即时间窗口内允许的最大 Token 数量。​
是​
​
限流插件配置示例​
示例一:单消费者多时间窗口限流​
为消费者user-a配置限流:每天 10,000,000 Token,每周 50,000,000 Token。​
​
{​
"Rules": [​
{​
"Name": "tokens",​
"Key": {​
"Position": "Consumer"​
},​
"Value": "PromptTokenAndCompletionToken",​
"Matches": [​
{​
"Mode": "Exact",​
"Exact": "user-a",​
"Limits": [​
{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 10000000 // 阈值:1000 万 token​
},​
{​
"TimeWindow": 604800, // 时间窗口:一周,单位秒​
"Threshold": 50000000 // 阈值:5000 万 token​
}​
]​
}​
]​
}​
]​
}​
​
示例二:多消费者分组月度限流​
为消费者user-a、user-b配置每月 100,000,000 Token 限流;为消费者user-c配置每月 200,000,000 Token 限流。同一规则内通过多条 Match 实现分组,按从上到下顺序匹配,第一个命中的 Match 生效。​
​
{​
"Rules": [​
{​
"Name": "tokens",​
"Key": {​
"Position": "Consumer"​
},​
"Value": "PromptTokenAndCompletionToken",​
"Matches": [​
{​
"Mode": "Exact",​
"Exact": "user-a",​
"Limits": [​
{​
"Period": "Monthly", // 周期类型:一个自然月​
"Threshold": 100000000 // 阈值:1 亿 token​
}​
]​
},​
{​
"Mode": "Exact",​
"Exact": "user-b",​
"Limits": [​
{​
"Period": "Monthly", // 周期类型:一个自然月​
"Threshold": 100000000 // 阈值:1 亿 token​
}​
]​
},​
{​
"Mode": "Exact",​
"Exact": "user-c",​
"Limits": [​
{​
"Period": "Monthly", // 周期类型:一个自然月​
"Threshold": 200000000 // 阈值:2 亿 token​
}​
]​
}​
]​
}​
]​
}​
​
示例三:特定消费者和默认兜底限流​
为消费者user-a配置每天 10,000,000 Token 限流;其他所有消费者默认每天 20,000,000 Token。通过两条 Match 实现:第一条精确匹配user-a,第二条使用Any模式作为兜底。规则按从上到下顺序匹配,第一个命中的 Match 生效。​
​
{​
"Rules": [​
{​
"Name": "tokens",​
"Key": {​
"Position": "Consumer"​
},​
"Value": "PromptTokenAndCompletionToken",​
"Matches": [​
{​
"Mode": "Exact",​
"Exact": "user-a",​
"Limits": [​
{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 10000000 // 阈值:1000 万 token​
}​
]​
},​
{​
"Mode": "Any",​
"Limits": [​
{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 20000000 // 阈值:2000 万 token​
}​
]​
}​
]​
}​
]​
}​
​
高级用法​
命名空间(Namespace)​
配置 Namespace 后,限流值将在同一网关内、相同命名空间下的所有服务和路由之间共享。多个绑定了相同 Namespace 的插件实例会共同消耗同一个限流配额,适用于需要跨服务或跨路由统一限流的场景。以下示例配置了名为shared-quota的命名空间,该命名空间下所有服务和路由的消费者将共享每天 50,000,000 Token 的限流配额。​
​
{​
"Rules": [​
{​
"Name": "tokens",​
"Key": {​
"Position": "Consumer"​
},​
"Value": "PromptTokenAndCompletionToken",​
"Matches": [​
{​
"Mode": "Any",​
"Limits": [​
{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 50000000 // 阈值:5000 万 token​
}​
]​
}​
]​
}​
],​
"Namespace": "shared-quota"​
}​
​
自定义限流响应(RateLimitedResponseOverride)​
默认情况下,请求触发限流时网关返回Rate limited.。如需给调用方返回更清晰的提示,可以配置 RateLimitedResponseOverride。该配置支持以下优先级,优先级从高到低依次为:Limit.RateLimitedResponseOverride、Match.RateLimitedResponseOverride、Rule.RateLimitedResponseOverride。​
说明​
优先使用 Limit 层配置的响应;如果 Limit 层未配置,再使用 Match 层;Match 层也未配置时,再使用 Rule 层;都未配置时使用默认响应。​
模版中支持以下两个字段:​
​
变量​
说明​
{retry_after}​
可重试的等待时间,单位为秒。​
{retry_after_date}​
可重试的日期时间,使用 GMT 格式返回。​
​
​
​
{​
"Rules": [​
{​
"Name": "tokens",​
"Key": {​
"Position": "Consumer"​
},​
"Value": "PromptTokenAndCompletionToken",​
"Matches": [​
{​
"Mode": "Any",​
"Limits": [​
{​
"TimeWindow": 86400, // 时间窗口:一天,单位秒​
"Threshold": 1000000 // 阈值:100 万 token​
}​
]​
}​
],​
"RateLimitedResponseOverride": "You are rate limited, try again in {retry_after} seconds after {retry_after_date}."​
}​
]​
}​
​
​
最近更新时间:2026.09.01 17:19:26
这个页面对您有帮助吗?
有用
有用
无用
无用