本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
概览
配额是 API 代理在某个时间段(例如分钟、小时、天、周或月)内接受的请求配额。配额政策将维护计数器,记录 API 代理收到的请求数量。借助此功能,API 提供商可以在某个时间段内应用执行的 API 调用数量强制执行限制。例如,您可以通过配额政策,将应用限制为每分钟 1 个请求,或者每月 10,000 个请求。
此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型。
当 API 代理达到其配额限制时,Apigee 会拒绝后续的 API 调用并返回错误消息,直到配额计数器在指定时间间隔结束时自动重置,或者直到使用 ResetQuota 政策明确重置配额。
例如,如果将配额定义为每月 10,000 条消息,则速率限制会在第 10,000 条消息之后开始。无论是在当月的第一天还是最后一天达到 1 万条消息,都无关紧要。
借助 Apigee,您可以动态设置每次 API 调用的权重。例如,借助大语言模型 (LLM) API,您可以根据请求或响应中的令牌数量(或两者)强制执行速率限制。此外,配额限制本身可以是动态的,这意味着您可以在系统繁忙时强制执行更严格的配额,或在非高峰时段放宽配额。
配额政策(即 SpikeArrest 政策)的变异可防止因使用量的突然增加、错误客户端或恶意攻击而出现流量高峰(或爆发)。
您可以为所有访问 API 代理的应用设置相同的配额,也可以根据以下项设置不同的配额限制:
- 包含 API 代理的产品
- 请求 API 的应用
- 应用开发者
- 上游服务
- 许多其他条件
- 任意可用条件的组合
请勿使用配额政策防范总体流量峰值。为此,请使用 SparkeArrest 政策。
视频
以下视频介绍如何使用配额政策管理配额:
简介
动态配额
分布式与同步
消息权重
日历
滚动窗口
Flexi
条件配额
流变量
错误处理
配额政策类型
配额政策支持使用多种不同的方法来启动和重置配额计数器。您可以在 <Quota>
元素中使用 type
属性来定义要使用的方法,如以下示例所示:
<Quota name="QuotaPolicy" type="calendar"> ... </Quota>
type
的有效值包括:
calendar
:根据显式开始时间配置配额。系统会根据您设置的<StartTime>
、<Interval>
和<TimeUnit>
值刷新每个应用的配额计数器。rollingwindow
:配置使用“滚动窗口”确定配额用量的配额。借助rollingwindow
,您可以使用<Interval>
和<TimeUnit>
元素确定窗口的大小;例如,1 天。收到请求时,Apigee 会查看请求的确切时间(例如:下午 5:01),并计算自那时到前一天(第一天) 5:01 的请求数量,并确定在该时间段内是否已超出配额。flexi
:配置配额,使计数器在从应用收到第一个请求消息时开始,并根据<Interval>
和<TimeUnit>
值重置。
下表介绍了每种类型的配额重置时间:
时间单位 | 类型 | ||
---|---|---|---|
default (或 null) |
calendar |
flexi |
|
分钟 | 下一分钟开始 | 比 <StartTime> 晚一分钟 |
发出第一个请求后的 1 分钟 |
小时 | 下一小时的顶部 | <StartTime> 后一小时 |
发出第一个请求后的一小时 |
天 | 当天午夜 (GMT) | 比 <StartTime> 晚 24 小时 |
发出第一次请求后的 24 小时 |
周 | 当周结束时的 GMT 周日午夜 | 比 <StartTime> 晚一周 |
发出第一次请求后的一周 |
月 | 当月最后一天的午夜 (GMT) | <StartTime> 之后的一个月(28 天) |
第一个请求之后的一个月(28 天) |
对于 type="calendar"
,您必须指定 <StartTime>
的值。
该表未说明 rollingwindow
类型的计数的重置时间。
这是因为滚动窗口配额的运作方式略有不同,它基于回溯期(例如一小时或一天)。对于 rollingwindow
类型,计数器从不重置,但是会在每个请求重新计算。收到新请求时,政策会确定配额在过去的时间窗口内是否超出配额。
例如,您定义了允许 1000 个请求的两小时窗口。下午 4:45 收到新请求。该政策计算过去两小时窗口的配额计数,即自下午 2:45 以来的请求数量。如果在两小时窗口内未超过配额限制,则系统会允许该请求。
1 分钟后,即在下午 4:46 收到另一个请求。现在,该政策从下午 2:46 开始计算配额,以确定是否超出限制。
了解配额计数器
配额政策在 API 代理流中执行时,配额计数器会递减。当计数器达到其限制时,将无法再进行与该计数器关联的任何 API 调用。配额政策可以采用一个或多个计数器,具体取决于您的配置。请务必了解何时采用多个计数器以及这些计数器的运作方式。
API 产品的配额计算方式
如果 API 代理包含在 API 产品中,则可以将配额政策配置为使用该产品中定义的配额规则。API 产品可以在产品级别或个别操作级别指定配额规则。
系统会为 API 产品中定义的每项操作维护单独的配额计数器,并遵循以下规则:
- 如果操作定义有配额,则操作的配额规则优先于在产品级别定义的配额规则。系统会为每项操作创建单独的配额计数器。对操作路径的任何 API 调用都会使其计数器递增。
- 如果操作没有定义配额,则系统会应用产品级别配额规则。但是,系统仍会为操作维护单独的配额计数器。请务必知悉,在这种情况下,即使配额规则来自产品级别定义,但系统仍会为操作维护自己的计数器。
- 如果 API 产品不包含任何配额定义(无论是在产品级别还是操作级别),则系统会应用政策中指定的配额规则;但是,在这种情况下,系统还是会为 API 产品中的每项操作维护单独的配额计数器。
以下各部分会进一步介绍计数器的选项和行为。
配置 API 代理级别计数器
可以将 API 产品配置为在 API 代理级别维护配额计数。在这种情况下,API 产品级别指定的配额配置会由未指定配额的所有操作共享。此配置会在 API 代理级别为此 API 产品创建一个全局计数器。
如需实现这种配置,您必须使用 /apiproducts Apigee API 创建或更新产品,并在创建或更新请求中将 quotaCountScope
属性设置为 PROXY
。使用 PROXY
配置时,对于为 API 产品定义的与同一代理关联的所有操作,如果它们没有自己的计数器,则会共享在 API 产品级别设置的同一配额计数器。
在图 1 中,操作 1 和 2 与 Proxy1 关联,操作 4 和 5 与 Proxy3 关联。由于在 API 产品中设置了 quotaCounterScope=PROXY
,因此每项操作都会共享 API 产品级别的配额设置。请注意,虽然这些操作共享相同的配额配置,但系统会根据其代理关联对其使用单独的计数器。另一方面,由于操作 3 设置有自己的配额配置,因此不受 quotaCounterScope
标志的影响。
图 1:quotaCounterScope 标志的使用
默认情况下,如果操作没有定义配额,则系统会应用产品级别配额规则。但是,系统仍会为操作维护单独的配额计数器。
如果未使用 API 产品,如何计算配额
如果没有与 API 代理关联的 API 产品,则配额政策会维护单个计数器,无论您在 API 代理中对其引用多少次。配额计数器的名称基于政策的 name
属性。
例如,您创建一个名为 MyQuotaPolicy
的配额政策,限制 5 个请求,并将其放在 API 代理中的多个流(流 A、B 和 C)中。即使它用于多个流中,也会维护一个由该政策的所有实例更新的单个计数器:
- 执行流 A -> 执行 MyQuotaPolicy,其计数器 = 1
- 执行流 B -> 执行 MyQuotaPolicy,其计数器 = 2
- 执行流 A -> 执行 MyQuotaPolicy,其计数器 = 3
- 执行流 C -> 执行 MyQuotaPolicy,其计数器 = 4
- 执行流 A -> 执行 MyQuotaPolicy,其计数器 = 5
对其中任何三个流的下一个请求都会被拒绝,因为配额计数器已达到其限制。
在 API 代理流中的多个位置使用同一配额政策,从而可能意外导致配额的运行速度超出您的预期,在反模式简介中对这种反模式进行了说明。
或者,您也可以在 API 代理中定义多个配额政策,并在每个流中使用不同的政策。每个配额政策都根据政策的 name
属性维护自己的计数器。
通过政策配置创建多个计数器
您可以使用配额政策中的 <Class>
或 <Identifier>
元素在单个政策中定义多个唯一计数器。通过使用这些元素,单个政策可以根据发出请求的应用、发出请求的应用开发者、客户端 ID 或其他客户端标识符等,维护不同的计数器。如需详细了解如何使用 <Class>
或 <Identifier>
元素,请参阅上面的示例。
时间表示法
所有配额时间均设置为世界协调时间 (UTC) 时区。
配额时间表示法遵循国际标准 ISO 8601 中定义的国际标准日期表示法。
日期采用以下格式定义为年、月和天:YYYY-MM-DD。例如,2021-02-04
表示 2021 年 2 月 4 日。
时间采用以下格式定义为小时、分钟和秒:hours:minutes:seconds
。例如,23:59:59
表示午夜前 1 秒的时间。
请注意,您可以使用 00:00:00
和 24:00:00
两种表示法来区分可与一个日期相关联的两个午夜。因此,2021-02-04
24:00:00
是与 2021-02-05 00:00:00
相同的日期和时间。后者通常是首选表示法。
从 API 产品配置获取配额设置
您可以在 API 产品配置中设置配额限制。这些限制不会自动强制执行配额。您可以在配额政策中引用产品配额设置。在产品上设置配额以供配额政策应用具有以下优势:
- 配额政策可以对 API 产品中的所有 API 代理使用统一设置。
- 您可以对 API 产品的配额设置进行运行时更改,并且引用该值的配额政策会自动更新配额值。
如需详细了解如何使用 API 产品中的配额设置,请参阅上面的“动态配额”示例。
如需了解如何使用配额限制配置 API 产品,请参阅管理 API 产品。
配置共享配额计数器
在简单情况下,配额政策会在初始请求处理期间,针对发送到 API 代理的每个请求将计数器递增一次。在某些情况下,您可能希望在初始处理传入请求时检查是否超出配额,但仅在处理响应期间递增计数器。只有在上游或目标系统响应后才能知道 API 调用的费用或权重时,这种做法才有意义。对于 LLM API,响应的令牌大小可能会决定费用。对于 BigQuery API,响应中的 total_slot_ms
可能会决定费用。
将三个配额政策元素(<SharedName>
、<CountOnly>
和 <EnforceOnly>
)一起使用时,您可以自定义配额政策,以强制执行传入请求的配额,并根据从目标响应中获取的信息累积配额计数。
例如,假设您有一个使用 LLM 作为目标的 API 代理,并且希望强制执行每小时 10 万个令牌的配额。LLM 回答提供 totalTokenCount
值。如需实现这一点,请执行以下操作:
- 将配额政策附加到 ProxyEndpoint 请求流,其中
<SharedName>
元素设置名称值,<EnforceOnly>
元素设置为true
。 - 将 ExtractVariables 政策附加到 ProxyEndpoint 响应流,以从 LLM 目标收到的回答中提取
totalTokenCount
值。 - 将第二个配额政策附加到 ProxyEndpoint 响应流程,其中
<SharedName>
元素设置的名称值与第一个配额政策相同,<CountOnly>
元素设置为true
。设置<MessageWeight>
元素以使用提取的totalTokenCount
值。
有关如何使用共享计数器的示例,请参阅示例部分中的共享计数器。
示例
以下政策代码示例说明了如何通过以下项开始和结束配额周期:
更动态的配额
<Quota name="CheckQuota"> <Interval ref="verifyapikey.verify-api-key.apiproduct.developer.quota.interval">1</Interval> <TimeUnit ref="verifyapikey.verify-api-key.apiproduct.developer.quota.timeunit">hour</TimeUnit> <Allow count="200" countRef="verifyapikey.verify-api-key.apiproduct.developer.quota.limit"/> </Quota>
借助动态配额,您可以配置单个配额政策,以便根据传递给配额政策的信息强制执行不同的配额设置。此上下文中配额设置的另一个术语是“服务计划”。动态配额会检查应用的“服务计划”,然后强制执行这些设置。
例如,在创建 API 产品时,您可以选择设置允许的配额限制、时间单位和时间间隔。但是,在 API 产品上设置这些值不会强制在 API 代理中使用它们。此外,您还必须向读取这些值的 API 代理添加配额政策。如需了解详情,请参阅创建 API 产品。
在上面的示例中,包含配额政策的 API 代理使用名为 verify-api-key
的 VerifyAPIKey 政策来验证请求中传递的 API 密钥。接着,配额政策会从 VerifyAPIKey 政策访问流变量,以读取 API 产品上设置的配额值。
另一个选项是为各个开发者或应用设置自定义属性,然后在配额政策中读取这些值。例如,要为每个开发者设置不同的配额值,您可以为开发者设置限制、时间单位和间隔等自定义属性。然后,您可以在配额政策中引用这些值,如下所示:
<Quota name="DeveloperQuota"> <Identifier ref="verifyapikey.verify-api-key.client_id"/> <Interval ref="verifyapikey.verify-api-key.developer.timeInterval"/> <TimeUnit ref="verifyapikey.verify-api-key.developer.timeUnit"/> <Allow countRef="verifyapikey.verify-api-key.developer.limit"/> </Quota>
此示例还使用 VerifyAPIKey 流变量来引用在开发者上设置的自定义属性。
您可以使用任意变量来设置配额政策的参数。这些变量可以来自:
- 流变量
- 关于 API 产品、应用或开发者的属性
- 键值对映射 (KVM)
- 标头、查询参数、表单参数等等
对于每个 API 代理,您可以添加一个配额政策来引用与所有其他代理的所有其他配额政策相同的变量,或者配额政策可以引用该政策和代理的唯一变量。
开始时间
<Quota name="QuotaPolicy" type="calendar"> <StartTime>2021-02-18 10:30:00</StartTime> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>
对于 type
设置为 calendar
的配额,您必须定义一个明确的 <StartTime>
值。时间值为 GMT 时间,而不是本地时间。如果您未为 calendar
类型的政策提供 <StartTime>
值,则 Apigee 会发出错误。
每个应用的配额计数器都将根据 <StartTime>
、<Interval>
和 <TimeUnit>
值刷新。在本示例中,配额从 GMT 2021 年 2 月 18 日上午 10:30 开始计算,每 5 小时刷新一次。因此,下次刷新时间为 GMT 2021 年 2 月 18 日下午 3:30。
访问计数器
<Quota name="QuotaPolicy"> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>
API 代理可以访问由配额政策设置的流变量。您可以在 API 代理中访问这些流变量以执行条件处理,在接近配额限制时监控政策,将当前配额计数器返回给应用,或出于其他原因。
由于对政策的流变量的访问基于政策 name
属性,因此对于上述名为 <Quota>
的政策,您可以通过以下格式访问其流变量:
ratelimit.QuotaPolicy.allowed.count
:允许的计数。ratelimit.QuotaPolicy.used.count
:当前计数器值。ratelimit.QuotaPolicy.expiry.time
:计数器重置的 UTC 时间。
您还可以访问许多其他流变量,如下所述。
例如,您可以使用以下 AssignMessage 政策,将配额流变量的值作为响应标头返回:
<AssignMessage continueOnError="false" enabled="true" name="ReturnQuotaVars"> <AssignTo createNew="false" type="response"/> <Set> <Headers> <Header name="QuotaLimit">{ratelimit.QuotaPolicy.allowed.count}</Header> <Header name="QuotaUsed">{ratelimit.QuotaPolicy.used.count}</Header> <Header name="QuotaResetUTC">{ratelimit.QuotaPolicy.expiry.time}</Header> </Headers> </Set> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> </AssignMessage>
共享计数器
以下示例说明了如何为 API 代理配置共享计数器,其中目标响应为 HTTP 状态 200
时,配额计数器也会递增。由于两个配额政策使用相同的 <SharedName>
值,因此两个配额政策将共享同一个配额计数器。如需了解详情,请参阅配置共享配额计数器。
ProxyEndpoint 配置示例:
<ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Quota-Enforce-Only</Name> </Step> </Request> <Response> <Step> <Name>EV-Token-Count</Name> </Step> <Step> <Name>Quota-Count-Only</Name> </Step> </Response> <Response/> </PreFlow> <Flows/> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <HTTPProxyConnection> <BasePath>/quota-shared-name</BasePath> </HTTPProxyConnection> <RouteRule name="noroute"/> </ProxyEndpoint>
第一个配额政策示例:
<Quota name="Quota-Enforce-Only" type="rollingwindow"> <SharedName>common-counter</SharedName> <EnforceOnly>true</EnforceOnly> <Allow count="15000"/> <Interval>30</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> </Quota>
ExtractVariable 政策示例:
<ExtractVariables name='EV-Token-Count'> <Source>response</Source> <VariablePrefix>extracted</VariablePrefix> <JSONPayload> <Variable name='tokenCount'> <JSONPath>$[1].usageMetadata.totalTokenCount</JSONPath> </Variable> </JSONPayload> </ExtractVariables>
第二个配额政策示例:
<Quota name="Quota-Count-Only" type="rollingwindow"> <SharedName>common-counter</SharedName> <!-- Same name as the first Quota policy --> <CountOnly>true</CountOnly> <Allow count="15000"/> <Interval>30</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <MessageWeight ref="extracted.tokenCount"/> </Quota>
第一个请求
<Quota name="MyQuota"> <Interval>1</Interval> <TimeUnit>hour</TimeUnit> <Allow count="10000"/> </Quota>
使用此示例代码,强制执行每小时 10,000 次调用的配额。该政策会在每个小时的顶部重置配额计数器。如果计数器在一小时结束之前达到 10,000 次调用配额,则超出 10,000 次的调用将被拒绝。
例如,如果计数器在 2021-07-08 07:00:00
开始,则会在 2021-07-08 08:00:00
(从开始时间算起 1 小时)重置为 0。如果在 2021-07-08 07:35:28
收到第一个消息,且消息计数在 2021-07-08 08:00:00
之前达到 10,000,则超出该计数的调用将被拒绝,直到计数在小时的顶部重置为止。
计数器重置时间基于 <Interval>
和 <TimeUnit>
的组合。例如,如果将 <Interval>
设置为 12(对于小时的 <TimeUnit>
),则计数器会每 12 小时重置一次。您可以将 <TimeUnit>
设置为分钟、小时、天、周或月。
您可以在 API 代理中的多个位置引用此政策。例如,您可以将其放在代理 PreFlow 上,使其针对每个请求执行。或者,您可以将其放在 API 代理的多个流中。如果您在代理的多个位置使用此政策,则该政策会维护一个由该政策的所有实例更新的单个计数器。
或者,您可以在 API 代理中定义多个配额政策。每个配额政策都根据政策的 name
属性维护自己的计数器。
设置标识符
<Quota name="QuotaPolicy" type="calendar"> <Identifier ref="request.header.clientId"/> <StartTime>2021-02-18 10:00:00</StartTime> <Interval>5</Interval> <TimeUnit>hour</TimeUnit> <Allow count="99"/> </Quota>
默认情况下,无论请求的来源如何,配额政策都会为 API 代理定义一个计数器。或者,您也可以将 <Identifier>
属性与配额政策搭配使用,根据 <Identifier>
属性的值来维护单独的计数器。
例如,使用 <Identifier>
标记为每个客户端 ID 定义单独的计数器。然后,客户端应用会向您的代理请求传递一个包含 clientID
的标头,如上例所示。
您可以为 <Identifier>
属性指定任何流变量。例如,您可以指定名为 id
的查询参数包含唯一标识符:
<Identifier ref="request.queryparam.id"/>
如果您使用 VerifyAPIKey 政策来验证 API 密钥,或将 OAuthV2 政策与 OAuth 令牌搭配使用,则可以使用 API 密钥或令牌中的信息为同一配额政策定义单个计数器。例如,以下 <Identifier>
元素使用名为 verify-api-key
的 VerifyAPIKey 政策的 client_id
流变量:
<Identifier ref="verifyapikey.verify-api-key.client_id"></Identifier>
现在,每个唯一 client_id
值都会在配额政策中定义自己的计数器。
类
<Quota name="QuotaPolicy"> <Interval>1</Interval> <TimeUnit>day</TimeUnit> <Allow> <Class ref="request.header.developer_segment"> <Allow class="platinum" count="10000"/> <Allow class="silver" count="1000" /> </Class> </Allow> </Quota>
您可以使用基于类的配额计数来动态设置配额限制。在此示例中,配额限制由随每个请求传递的 developer_segment
标头的值决定。该变量的值可以是 platinum
或 silver
。如果标头具有无效值,则该政策会返回配额违规错误。
<Quota>
元素
以下是 <Quota>
的特性和子元素。请注意,某些元素组合相互排斥或不需要。查看特定用法的示例。
使用名为 my-verify-key-policy
的 VerifyAPIKey 政策检查请求中的应用 API 密钥时,默认情况下可以使用以下 verifyapikey.my-verify-key-policy.apiproduct.*
变量。变量值来自与密钥关联的 API 产品的配额设置,如从 API 产品配置获取配额设置中所述。
<Quota continueOnError="false" enabled="true" name="Quota-3" type="calendar"> <DisplayName>Quota 3</DisplayName> <Allow count="UPPER_REQUEST_LIMIT" countRef="verifyapikey.my-verify-key-policy.apiproduct.developer.quota.limit"/> <Allow> <Class ref="request.queryparam.time_variable"> <Allow class="peak_time" count="UPPER_LIMIT_DURING_PEAK"/> <Allow class="off_peak_time" count="UPPER_LIMIT_DURING_OFFPEAK"/> </Class> </Allow> <Interval ref="verifyapikey.my-verify-key-policy.apiproduct.developer.quota.interval">1</Interval> <TimeUnit ref="verifyapikey.my-verify-key-policy.apiproduct.developer.quota.timeunit">month</TimeUnit> <StartTime>2021-7-16 12:00:00</StartTime> <Distributed>false</Distributed> <Synchronous>false</ Synchronous> <AsynchronousConfiguration> <SyncIntervalInSeconds>20</ SyncIntervalInSeconds> <SyncMessageCount>5</ SyncMessageCount> </AsynchronousConfiguration> <Identifier/> <MessageWeight/> <UseQuotaConfigInAPIProduct> <DefaultConfig> <Allow> <Class ref="request.queryparam.time_variable"> <Allow class="peak_time" count="5000"/> <Allow class="off_peak_time" count="1000"/> </Class> </Allow> <Interval ref="verifyapikey.my-verify-key-policy.apiproduct.developer.quota.interval">1</Interval> <TimeUnit ref="verifyapikey.my-verify-key-policy.apiproduct.developer.quota.timeunit">month</TimeUnit> </DefaultConfig> </UseQuotaConfigInAPIProduct> </SharedName> </CountOnly> </EnforceOnly> </Quota>
以下属性特定于此政策:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
type |
设置配额政策类型,用于确定配额计数器检查配额使用量的时间和方式,以及配额的重置方式。 如果未设置 有效值包括:
如需查看每种类型的完整说明,请参阅配额政策类型。 |
不适用 | 可选 |
The following table describes attributes that are common to all policy parent elements:
Attribute | Description | Default | Presence |
---|---|---|---|
name |
The internal name of the policy. The value of the Optionally, use the |
N/A | Required |
continueOnError |
Set to Set to |
false | Optional |
enabled |
Set to Set to |
true | Optional |
async |
This attribute is deprecated. |
false | Deprecated |
<DisplayName> element
Use in addition to the name
attribute to label the policy in the
management UI proxy editor with a different, natural-language name.
<DisplayName>Policy Display Name</DisplayName>
Default |
N/A If you omit this element, the value of the policy's |
---|---|
Presence | Optional |
Type | String |
<Allow>
指定配额的计数限制。如果政策的计数器达到此限制值,则后续调用将被拒绝,直到计数器重置。
还可以包含 <Class>
元素,该元素可根据流变量对 <Allow>
元素设置条件。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 整数或复杂类型 |
父元素 |
<Quota>
|
子元素 |
<Class> |
下面显示了设置 <Allow>
元素的三种方法:
<Allow count="2000"/>
<Allow countRef="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.limit"/>
<Allow count="2000" countRef="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.limit"/>
如果您同时指定 count
和 countRef
,则 countRef
优先。如果 countRef
在运行时未解析,则使用 count
的值。
您还可以指定 <Class>
元素作为 <Allow>
的子元素,以根据流变量确定政策的允许计数。Apigee 将流变量的值与 <Allow>
元素的 class
属性进行匹配,如下所示:
<Allow> <Class ref="request.queryparam.time_variable"> <Allow class="peak_time" count="5000"/> <Allow class="off_peak_time" count="1000"/> </Class> </Allow>
下表列出了 <Allow>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
计数 |
用于指定配额的消息计数。 例如, |
2000 | 可选 |
countRef |
用于指定包含配额的消息计数的流变量。 |
无 | 可选 |
<Class>
可让您根据流变量的值对 <Allow>
元素设置条件。对于 <Class>
的每个不同 <Allow>
子标记,该政策会维护不同的计数器。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<Allow>
|
子元素 |
<Allow> (<Class> 的子项) |
如需使用 <Class>
元素,请使用 <Class>
元素的 ref
属性指定流变量。然后,Apigee 会使用流变量的值选择一个 <Allow>
子元素,以确定政策的允许数量。Apigee 将流变量的值与 <Allow>
元素的 class
属性进行匹配,如下所示:
<Allow> <Class ref="request.queryparam.time_variable"> <Allow class="peak_time" count="5000"/> <Allow class="off_peak_time" count="1000"/> </Class> </Allow>
在此示例中,当前配额计数器由随每个请求传递的 time_variable
查询参数的值决定。该变量的值可以是 peak_time
或 off_peak_time
。如果查询参数包含无效值,则该政策将返回配额违规错误。
下表列出了 <Class>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
ref | 用于指定包含配额的配额类的流变量。 | 无 | 需要 |
<Allow>
(<Class>
的子项)
指定 <Class>
元素定义的配额计数器的限制。对于每个 <Class>
不同的 <Allow>
子标记,该政策会维护不同的计数器。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<Class>
|
子元素 |
无 |
例如:
<Allow> <Class ref="request.queryparam.time_variable"> <Allow count="5000"/> <Allow count="1000"/> </Class> </Allow>
在此示例中,配额政策维护名为 peak_time
和 off_peak_time
的两个配额计数器。所使用的计数器取决于传递的查询参数,如 <Class>
示例所示。
下表列出了 <Allow>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
class | 定义配额计数器的名称。 | 无 | 需要 |
计数 | 指定计数器的配额限制。 | 无 | 需要 |
<Interval>
指定计算配额的时间段数量。
默认值 | 不适用 |
是否必需? | 需要 |
类型 | 整数 |
父元素 |
<Quota>
|
子元素 |
无 |
用于指定将与您指定的 <TimeUnit>
(分钟、小时、天、周或月)配对的整数(例如 1、2、5、60 等),以确定 Apigee 计算配额用量的时间段。
例如,含 hour
的 <TimeUnit>
的间隔 24
表示配额将在 24 小时内计算。
<Interval ref="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.interval">1</Interval>
下表列出了 <Interval>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
ref |
用于指定包含配额间隔的流变量。 |
无 | 可选 |
<TimeUnit>
指定配额适用的时间单位。
默认值 | 不适用 |
是否必需? | 需要 |
类型 | 字符串 |
父元素 |
<Quota>
|
子元素 |
无 |
从 minute
、hour
、day
、week
、month
或 year
中选择。
例如,含 hour
的 TimeUnit
的 24
的Interval
表示配额将在 24 小时内计算。
<TimeUnit ref="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.timeunit">month</TimeUnit>
默认: | 无 |
状态: | 需要 |
类型: | 字符串 |
下表列出了 <TimeUnit>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
ref | 指定包含配额时间单位的流变量。ref 优先于显式间隔值。如果 ref 在运行时未解析,则使用此间隔值。 |
无 | 可选 |
<StartTime>
将 type
设置为 calendar
时,会指定配额计数器开始计数的日期和时间,而不管是否从任何应用收到任何请求。
默认值 | 不适用 |
是否必需? | 可选(当 type 设为 calendar 时必需) |
类型 | 采用 ISO 8601 日期和时间格式的字符串 |
父元素 |
<Quota>
|
子元素 |
无 |
例如:
<StartTime>2021-7-16 12:00:00</StartTime>
<Distributed>
确定 Apigee 使用一个节点还是多个节点来处理请求。
默认值 | false |
是否必需? | 可选 |
类型 | Boolean |
父元素 |
<Quota>
|
子元素 |
无 |
设置为 true
指定政策应保留一个中心计数器,并在所有节点中持续对其进行同步。这些节点可以分布在各个可用区和/或区域中。
如果使用 false
的默认值,则您可能会超出配额,因为不共享每个节点的计数:
<Distributed>false</Distributed>
如需保证计数器已同步,并且对每个请求进行更新,请将 <Distributed>
和 <Synchronous>
设置为 true
:
<Distributed>true</Distributed> <Synchronous>true</Synchronous>
<Synchronous>
确定是否同步更新分布式配额计数器。
默认值 | false |
是否必需? | 可选 |
类型 | Boolean |
父元素 |
<Quota>
|
子元素 |
无 |
设置为 true
可同步更新分布式配额计数器。这意味着对计数器的更新与对 API 的请求检查配额同时进行。如果不允许您通过该配额进行任何 API 调用,则设置为 true
。
设置为 false
可异步更新配额计数器。这意味着,某些超出配额的 API 调用可能会进行,具体取决于何时异步更新中央存储库中的配额计数器。但是,您不会面临与同步更新关联的潜在性能影响。
默认的异步更新间隔为 10 秒。使用 <AsynchronousConfiguration>
元素配置此异步行为。
<Synchronous>false</Synchronous>
<AsynchronousConfiguration>
当政策配置元素 <Synchronous>
不存在或存在并设置为 false
时,在分布式配额计数器之间配置同步间隔。当 <Synchronous>
设置为 true
时,Apigee 会忽略此元素。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<Quota>
|
子元素 |
<SyncIntervalInSeconds> <SyncMessageCount> |
您可以使用 <SyncIntervalInSeconds>
或 <SyncMessageCount>
子元素指定同步行为。使用其中一个或两个元素。例如,
<AsynchronousConfiguration> <SyncIntervalInSeconds>20</SyncIntervalInSeconds> </AsynchronousConfiguration>
或
<AsynchronousConfiguration> <SyncIntervalInSeconds>20</SyncIntervalInSeconds> <SyncMessageCount>5</SyncMessageCount> </AsynchronousConfiguration>
- 如果仅存在
<SyncIntervalInSeconds>
,则无论已处理多少条消息,配额都会每 N 秒同步一次,其中 N 是元素中指定的值。 - 如果仅存在
<SyncMessageCount>
,则配额每 M 条消息同步一次(其中 M 是元素中指定的值),或者每 10 秒同步一次(以先到者为准)。 - 如果这两个元素都存在,则配额每 M 条消息或每 N 秒同步一次(以先到者为准)。
- 如果不存在
<AsynchronousConfiguration>
或两个子元素都不存在,则无论已处理多少条消息,配额都会每 10 秒同步一次。
<SyncIntervalInSeconds>
替换在 10 秒间隔之后执行异步更新的默认行为。
默认值 | 10 秒 |
是否必需? | 可选 |
类型 | 整数 |
父元素 |
<AsynchronousConfiguration>
|
子元素 |
无 |
<AsynchronousConfiguration> <SyncIntervalInSeconds>20</SyncIntervalInSeconds> </AsynchronousConfiguration>
按照限制中的说明,同步间隔必须大于或等于 10 秒。
<SyncMessageCount>
指定在同步配额计数器之前要处理的请求数。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 整数 |
父元素 |
<AsynchronousConfiguration>
|
子元素 |
无 |
<AsynchronousConfiguration> <SyncMessageCount>5</SyncMessageCount> </AsynchronousConfiguration>
使用此示例中的配置,在每个节点上,配额计数将在每 5 个请求后或每 10 秒后(以先到者为准)同步一次。
<Identifier>
配置政策,以便根据流变量创建唯一计数器。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 字符串 |
父元素 |
<Quota>
|
子元素 |
无 |
通过标识符元素,您可以将调用计数分配给由流变量中的值定义的不同存储桶。例如,您可以使用在 VerifyAPIKey 政策后填充的 developer.id
变量,以针对每个特定开发者创建的所有实例强制执行一个配额限制,也可以使用 client_id
针对每个特定应用强制执行配额限制。后者的配置如下所示:
<Identifier ref="client_id"/>
您可以通过引用 AssignMessage 政策或 JavaScript 政策设置的自定义变量,也可以引用隐式设置的变量,例如那些由 VerifyAPIKey 政策或 VerifyJWT 政策设置的变量。如需详细了解变量,请参阅使用流变量;如需查看 Apigee 定义的知名变量列表,请参阅流变量参考文档。
如果您不使用此元素,则政策会将特定调用政策的所有调用计数分配到一个计数器。
未指定标识符时配额政策是如何运作?中也介绍了此元素
下表介绍 <Identifier>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
ref |
指定一个流变量来标识要用于请求的计数器。此变量可以引用 HTTP 标头、查询参数、表单参数或消息内容的元素,或某个其他值来标识如何分配调用计数的值。
|
不适用 | 可选 |
<MessageWeight>
指定为配额目的分配给每条消息的费用。使用此元素可根据 API 请求的内容或调用的值为 API 请求分配不同的影响。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 整数 |
父元素 |
<Quota>
|
子元素 |
无 |
例如,当 Apigee 管理大语言模型 (LLM) API 时,您可以使用请求或响应中的令牌数量(或同时使用两者)作为 <MessageWeight>
。
或者,如果您希望将 POST
消息的开销视为 GET
消息的两倍,则可以将 <MessageWeight>
设置为 2(对于 POST
) 和 1(对于 GET
)。假设配额为每分钟 10 条消息,并且代理在前 35 秒内处理 5 个 POST
请求。在计数器重置之前,代理会拒绝任何额外的请求(POST
或 GET
)。
表示 <MessageWeight>
的值必须使用流变量指定,并且可从 HTTP 标头、查询参数、XML 或 JSON 请求载荷或任何其他流变量中提取。例如,您可以从响应载荷中提取值到名为 extracted.message_weight
的变量中,然后将其用于 <MessageWeight>
:
<MessageWeight ref="extracted.message_weight"/>
如果流变量解析为 0,则请求不会影响计数器。
<UseQuotaConfigInAPIProduct>
定义 API 产品的配额设置,例如时间单位、时间间隔和允许的最大值。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<Quota>
|
子元素 |
<DefaultConfig> |
如果您在配额政策中添加 <UseQuotaConfigInAPIProduct>
元素,那么 Apigee 会忽略 <Quota>
的 <Allow>
、<Interval>
和 <TimeUnit>
子元素中的任何一个。
<UseQuotaConfigInAPIProduct>
元素只是一个使用 <DefaultConfig>
元素定义的默认设置的容器,如以下示例所示:
<UseQuotaConfigInAPIProduct stepName="POLICY_NAME"> <DefaultConfig>...</DefaultConfig> </UseQuotaConfigInAPIProduct>
您可以使用 stepName
属性引用流中的 VerifyAPIKey 政策或 OAuthv2 政策的 ValidateToken
政策操作。
下表介绍 <UseQuotaConfigInAPIProduct>
的特性:
属性 | 说明 | 默认值 | 状态 |
---|---|---|---|
stepName | 标识流中身份验证政策的名称。目标可以是 VerifyAPIKey 政策,也可以是 OAuthv2 政策。 | 不适用 | 需要 |
详情请参阅以下内容:
<DefaultConfig>
包含 API 产品的配额的默认值。在您定义 <DefaultConfig>
时,这三个子元素都是必需的。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<UseQuotaConfigInAPIProduct>
|
子元素 |
<Allow> <Interval> <TimeUnit> |
您可以对 API 产品的操作定义这些值(使用界面或 API 产品 API 定义以及在配额政策中定义)。但是,如果您这么做,则 API 产品上的设置的优先级更高,配额政策中的设置将被忽略。
该元素的语法如下:
<UseQuotaConfigInAPIProduct stepName="POLICY_NAME"> <DefaultConfig> <Allow>allow_count</Allow> <Interval>interval</Interval> <TimeUnit>[minute|hour|day|week|month]</TimeUnit> </DefaultConfig> </UseQuotaConfigInAPIProduct>
以下示例指定了每周的配额为 10000:
<DefaultConfig> <Allow>10000</Allow> <Interval>1</Interval> <TimeUnit>week</TimeUnit> </DefaultConfig>
详情请参阅以下内容:
<SharedName>
将此配额政策标识为共享。API 代理中具有相同 <SharedName>
值的所有配额政策共享相同的底层配额计数器。如果存在此元素,则还必须存在 <EnforceOnly>
或 <CountOnly>
元素。
如需了解详情和示例,请参阅配置共享配额计数器。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 字符串 |
父元素 |
<Quota>
|
子元素 |
无 |
<CountOnly>
在 ProxyEndpoint 响应流中的某个步骤中放置一个此元素设置为 true
的配额政策,以在超出配额限制时增加底层配额计数器,而不会向客户端发回错误。如果存在此元素,则还必须存在 <SharedName>
元素,并且不得存在 <EnforceOnly>
元素。
如需了解详情和示例,请参阅配置共享配额计数器。
默认值 | false |
是否必需? | 可选 |
类型 | Boolean |
父元素 |
<Quota>
|
子元素 |
无 |
<EnforceOnly>
在 API 代理的请求流中放置一个此元素设置为 true
的配额政策,以强制执行配额而不增加配额计数器。此配置允许根据仅在响应流中才能知道的消息权重来延迟强制执行速率限制。如果存在此元素,则还必须存在 <SharedName>
,并且不得存在 <CountOnly>
元素。
如需了解详情和示例,请参阅配置共享配额计数器。
默认值 | false |
是否必需? | 可选 |
类型 | Boolean |
父元素 |
<Quota>
|
子元素 |
无 |
流变量
当执行配额政策时,会自动填充以下预定义的流变量。如需了解详情,请参阅流变量参考文档。
变量 | 类型 | 权限 | 说明 |
---|---|---|---|
ratelimit.{policy_name}.allowed.count | 长 | 只读 | 返回允许的配额计数。 |
ratelimit.{policy_name}.used.count | 长 | 只读 | 返回配额间隔内使用的当前配额。 |
ratelimit.{policy_name}.available.count | 长 | 只读 | 返回配额间隔内的可用配额计数。 |
ratelimit.{policy_name}.exceed.count | 长 | 只读 | 在超出配额后返回 1。 |
ratelimit.{policy_name}.total.exceed.count | 长 | 只读 | 在超出配额后返回 1。 |
ratelimit.{policy_name}.expiry.time | 长 | 只读 |
返回以毫秒为单位的 UTC 时间,该时间决定了配额何时失效,以及新的配额间隔何时开始。 如果配额政策的类型为 |
ratelimit.{policy_name}.identifier | 字符串 | 只读 | 返回附加到政策的(客户端)标识符引用 |
ratelimit.{policy_name}.class | 字符串 | 只读 | 返回与客户端标识符关联的类 |
ratelimit.{policy_name}.class.allowed.count | 长 | 只读 | 返回类中定义的允许配额计数 |
ratelimit.{policy_name}.class.used.count | 长 | 只读 | 返回类中使用的配额 |
ratelimit.{policy_name}.class.available.count | 长 | 只读 | 返回类中的可用配额计数 |
ratelimit.{policy_name}.class.exceed.count | 长 | 只读 | 返回超出当前配额间隔中类限制的请求计数 |
ratelimit.{policy_name}.class.total.exceed.count | 长 | 只读 | 返回超出所有配额间隔内类限制的请求总计数,因此它是所有配额间隔的 class.exceed.count 总和。 |
ratelimit.{policy_name}.failed | Boolean | 只读 |
指明政策是否失败(true 或 false)。 |
错误参考信息
This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.
Runtime errors
These errors can occur when the policy executes.
Fault code | HTTP status | Cause | Fix |
---|---|---|---|
policies.ratelimit.FailedToResolveQuotaIntervalReference |
500 |
Occurs if the <Interval> element is not defined within the Quota policy. This element
is mandatory and used to specify the interval of time applicable to the quota. The time interval
can be minutes, hours, days, weeks, or months as defined with the <TimeUnit> element. |
build |
policies.ratelimit.FailedToResolveQuotaIntervalTimeUnitReference |
500 |
Occurs if the <TimeUnit> element is not defined within the Quota policy. This element
is mandatory and used to specify the unit of time applicable to the quota. The time interval
can be in minutes, hours, days, weeks, or months. |
build |
policies.ratelimit.InvalidMessageWeight |
500 |
Occurs if the value of the <MessageWeight> element specified through a flow variable
is invalid (a non-integer value). |
build |
policies.ratelimit.QuotaViolation |
500 |
The quota limit was exceeded. | N/A |
Deployment errors
Error name | Cause | Fix |
---|---|---|
InvalidQuotaInterval |
If the quota interval specified in the <Interval> element is not
an integer, then the deployment of the API proxy fails. For example, if the quota interval
specified is 0.1 in the <Interval> element, then the deployment of the
API proxy fails.
|
build |
InvalidQuotaTimeUnit |
If the time unit specified in the <TimeUnit> element is unsupported,
then the deployment of the API proxy fails. The supported time units are minute ,
hour , day , week , and month .
|
build |
InvalidQuotaType |
If the type of the quota specified by the type attribute in the <Quota>
element is invalid, then the deployment of the API proxy fails. The
supported quota types are default , calendar , flexi , and rollingwindow .
|
build |
InvalidStartTime |
If the format of the time specified in the <StartTime> element is
invalid, then the deployment of the API proxy fails. The valid format is yyyy-MM-dd HH:mm:ss ,
which is the ISO 8601 date and time format. For
example, if the time specified in the <StartTime> element is
7-16-2017 12:00:00 then the deployment of the API proxy fails.
|
build |
StartTimeNotSupported |
If the <StartTime> element is specified whose quota type is not
calendar type, then the deployment of the API proxy fails. The <StartTime> element is
supported only for the calendar quota type. For example, if the type attribute is set
to flexi or rolling window in the <Quota> element, then the
deployment of the API proxy fails.
|
build |
InvalidSynchronizeIntervalForAsyncConfiguration |
If the value specified for the <SyncIntervalInSeconds> element within the
<AsynchronousConfiguration> element in a Quota policy is less than zero, then the
deployment of the API proxy fails. |
build |
InvalidAsynchronizeConfigurationForSynchronousQuota |
If the value of the <AsynchronousConfiguration> element is set to true in a Quota policy, which also
has asynchronous configuration defined using the <AsynchronousConfiguration> element, then
the deployment of the API proxy fails. |
build |
Fault variables
These variables are set when this policy triggers an error. For more information, see What you need to know about policy errors.
Variables | Where | Example |
---|---|---|
fault.name="fault_name" |
fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. | fault.name Matches "QuotaViolation" |
ratelimit.policy_name.failed |
policy_name is the user-specified name of the policy that threw the fault. | ratelimit.QT-QuotaPolicy.failed = true |
Example error response
{ "fault":{ "detail":{ "errorcode":"policies.ratelimit.QuotaViolation" }, "faultstring":"Rate limit quota violation. Quota limit exceeded. Identifier : _default" } }
Example fault rule
<FaultRules> <FaultRule name="Quota Errors"> <Step> <Name>JavaScript-1</Name> <Condition>(fault.name Matches "QuotaViolation") </Condition> </Step> <Condition>ratelimit.Quota-1.failed=true</Condition> </FaultRule> </FaultRules>