本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
概览
配额是 API 代理可以在某个时间段(例如分钟、小时、天、周或月)内处理的请求消息配额。配额政策将维护计数器,记录 API 代理收到的请求数量。借助此功能,API 提供商可以在某个时间段内应用执行的 API 调用数量强制执行限制。例如,您可以通过配额政策,将应用限制为每分钟 1 个请求,或者每月 10,000 个请求。
此政策是一项可扩展政策,使用此政策可能会影响费用或使用情况,具体取决于您的 Apigee 许可。如需了解政策类型和使用情况影响,请参阅政策类型。
例如,如果将配额定义为每月 10,000 条消息,则速率限制会在第 10,000 条消息之后开始。不管在该时期的第一天还是最后一天计数到 1 万条信息,都无关紧要;除非在指定的时间间隔结束时自动重置配额,或者除非使用 ResetQuota 政策明确重置配额,否则没有其他请求。
配额政策(即 SpikeArrest 政策)的变异可防止因使用量的突然增加、错误客户端或恶意攻击而出现流量高峰(或爆发)。
使用配额政策配置 API 代理在一段时间(例如分钟、小时、日、周或月)内允许的请求消息数量。您可以将所有访问 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
类型的值。滚动窗口配额的工作原理是设置配额“窗口”的大小,例如一小时或一天的窗口。收到新请求时,政策会确定配额在过去的时间窗口内是否超出配额。
例如,您定义了允许 1000 个请求的两小时窗口。下午 4:45 收到新请求。该政策计算过去两小时窗口的配额计数,即自下午 2:45 以来的请求数量。如果在两小时窗口内未超过配额限制,则系统会允许该请求。
1 分钟后,即在下午 4:46 收到另一个请求。现在,该政策从下午 2:46 开始计算配额,以确定是否超出限制。
对于 rollingwindow
类型,计数器从不重置,但是会在每个请求重新计算。
了解配额计数器
配额政策在 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 代理的所有请求。在某些使用场景中,您可能希望实施传入请求配额计数,但也会递增满足指定条件的目标响应的配额计数。将三个配额政策元素一起使用时,<SharedName>
、<CountOnly>
和 <EnforceOnly>
可用于自定义配额政策以强制执行传入请求配额并根据您指定的条件。
例如,假设您希望递增来自后端目标的响应具有 200
HTTP 状态代码的 API 代理的配额计数器。如需实现这种专用计数,请执行以下操作:
- 将代理政策请求添加到 ProxyEndpoint 请求流,并将
<SharedName>
元素设置为名称值,将<EnforceOnly>
元素设置为true
。 - 将另一个配额政策添加到 ProxyEndpoint 响应流程,
<SharedName>
元素设置的名称值与第一个政策相同,<CountOnly>
元素设置为true
。 - 将第二个配额政策(包含
<CountOnly>
的政策)放入一个有条件的步骤,以便设置在哪个条件下递增配额计数器。
有关如何使用共享计数器的示例,请参阅示例部分中的共享计数器。
示例
以下政策代码示例说明了如何通过以下项开始和结束配额周期:
更动态的配额
<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>Enforce-Only</Name> <!--First quota policy enforces quota count --> </Step> </Request> <Response> <Step> <Name>Count-Only</Name> <!-- Second quota policy counts quota if call is successful --> <Condition>response.status.code = 200</Condition> </Step> </Response> <Response/> </PreFlow> <Flows/> <PostFlow name="PostFlow"> <Request/> <Response/> </PostFlow> <HTTPProxyConnection> <BasePath>/quota-shared-name</BasePath> </HTTPProxyConnection> <RouteRule name="noroute"/> </ProxyEndpoint>
第一个配额政策示例:
<Quota continueOnError="false" enabled="true" name="Enforce-Only" type="rollingwindow"> <DisplayName>Enforce-Only</DisplayName> <Properties/> <Allow count="5"/> <Interval>2</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Synchronous>true</Synchronous> <EnforceOnly>true</EnforceOnly> <SharedName>common-proxy</SharedName> <!-- Notice that SharedName value is the same for both Quota policies --> </Quota>
第二个配额政策示例:
<Quota continueOnError="false" enabled="true" name="Count-Only" type="rollingwindow"> <DisplayName>Count-Only</DisplayName> <Properties/> <Allow count="5"/> <Interval>2</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Synchronous>true</Synchronous> <CountOnly>true</CountOnly> <SharedName>common-proxy</SharedName> <!-- Same name as the first policy --> </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>
以下属性特定于此政策:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
type |
设置配额政策类型,用于确定配额计数器检查配额使用量的时间和方式,以及配额的重置方式。 如果未设置 有效值包括:
如需查看每种类型的完整说明,请参阅配额政策类型。 |
不适用 | 可选 |
下表介绍了所有政策父元素通用的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
name |
政策的内部名称。 (可选)使用 |
不适用 | 必需 |
continueOnError |
设置为 设置为 |
false | 可选 |
enabled |
设置为 设为 |
true | 可选 |
async |
此特性已弃用。 |
false | 已弃用 |
<DisplayName> 元素
用于在 name
属性之外在管理界面代理编辑器中给政策添加不同的自然语言名称标签。
<DisplayName>Policy Display Name</DisplayName>
默认 |
不适用 如果省略此元素,则会使用政策的 |
---|---|
Presence | 可选 |
类型 | 字符串 |
<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>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
计数 |
用于指定配额的消息计数。 例如, |
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>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
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>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
class | 定义配额计数器的名称。 | 无 | 必需 |
计数 | 指定计数器的配额限制。 | 无 | 必需 |
<Interval>
指定计算配额的时间段数量。
默认值 | 不适用 |
是否必需? | 必需 |
类型 | 整数 |
父元素 |
<Quota>
|
子元素 |
无 |
用于指定将与您指定的 <TimeUnit>
(分钟、小时、天、周或月)配对的整数(例如 1、2、5、60 等),以确定 Apigee 计算配额用量的时间段。
例如,含 hour
的 <TimeUnit>
的间隔 24
表示配额将在 24 小时内计算。
<Interval ref="verifyapikey.VerifyAPIKey.apiproduct.developer.quota.interval">1</Interval>
下表列出了 <Interval>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
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>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
ref | 指定包含配额时间单位的流变量。ref 优先于显式间隔值。如果 ref 在运行时未解析,则使用此间隔值。 |
无 | 可选 |
<StartTime>
将 type
设置为 calendar
时,会指定配额计数器开始计数的日期和时间,而不管是否从任何应用收到任何请求。
默认值 | 不适用 |
是否必需? | 可选(当 type 设为 calendar 时必需) |
类型 | 采用 ISO 8601 日期和时间格式的字符串 |
父元素 |
<Quota>
|
子元素 |
无 |
将 type
设置为 calendar
时,您必须提供显式 <StartTime>
。您不能使用流变量的引用。如果在未设置 type
值时指定 <StartTime>
值,则 Apigee 会返回错误。
例如:
<StartTime>2021-7-16 12:00:00</StartTime>
<Distributed>
确定 Apigee 使用一个节点还是多个节点来处理请求。
默认值 | false |
是否必需? | 可选 |
类型 | 布尔值 |
父元素 |
<Quota>
|
子元素 |
无 |
设置为 true
指定政策应保留一个中心计数器,并在所有节点中持续对其进行同步。这些节点可以分布在各个可用区和/或区域中。
如果使用 false
的默认值,则您可能会超出配额,因为不共享每个节点的计数:
<Distributed>false</Distributed>
如需保证计数器已同步,并且对每个请求进行更新,请将 <Distributed>
和 <Synchronous>
设置为 true
:
<Distributed>true</Distributed> <Synchronous>true</Synchronous>
<Synchronous>
确定是否同步更新分布式配额计数器。
默认值 | false |
是否必需? | 可选 |
类型 | 布尔值 |
父元素 |
<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>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
ref |
指定一个流变量来标识要用于请求的计数器。此变量可以引用 HTTP 标头、查询参数、表单参数或消息内容的元素,或某个其他值来标识如何分配调用计数的值。
|
不适用 | 可选 |
<MessageWeight>
指定为配额目的分配给每条消息的费用。使用此元素可提高请求消息的影响,例如,比其他消息消耗更多计算资源的请求消息。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 整数 |
父元素 |
<Quota>
|
子元素 |
无 |
例如,您希望将 POST
消息计为 GET
消息的两倍。因此,您可以将 <MessageWeight>
的 POST
设置为 2,将 GET
设置为 1。您甚至可以将 <MessageWeight>
设置为 0,以使请求不会影响计数器。
在本示例中,如果配额为每分钟 10 条消息,并且 POST
请求的 <MessageWeight>
为 2
,则配额在任何 10 分钟间隔内允许 5 个 POST
请求。计数器重置前的所有额外请求(POST
或 GET
)都将被拒绝。
表示 <MessageWeight>
的值必须由流变量指定,并且可从 HTTP 标头、查询参数、XML 或 JSON 请求载荷或任何其他流变量中提取。例如,您可以在名为 weight
的标头中对其进行设置:
<MessageWeight ref="message_weight"/>
<UseQuotaConfigInAPIProduct>
定义 API 产品的配额设置,例如时间单位、时间间隔和允许的最大值。
默认值 | 不适用 |
是否必需? | 可选 |
类型 | 复杂类型 |
父元素 |
<Quota>
|
子元素 |
<DefaultConfig> |
如果您在配额政策中添加 <UseQuotaConfigInAPIProduct>
元素,那么 Apigee 会忽略 <Quota>
的 <Allow>
、<Interval>
和 <TimeUnit>
子元素中的任何一个。
<UseQuotaConfigInAPIProduct>
元素只是一个使用 <DefaultConfig>
元素定义的默认设置的容器,如以下示例所示:
<UseQuotaConfigInAPIProduct stepName="POLICY_NAME"> <DefaultConfig>...</DefaultConfig> </UseQuotaConfigInAPIProduct>
您可以使用 stepName
属性引用流中的 VerifyAPIKey 政策或 OAuthv2 政策的 ValidateToken
政策操作。
下表介绍 <UseQuotaConfigInAPIProduct>
的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
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 |
是否必需? | 可选 |
类型 | 布尔值 |
父元素 |
<Quota>
|
子元素 |
无 |
<EnforceOnly>
在 API 代理的请求流中将此元素设置为 true
的配额政策。此配置允许 API 代理中的任何配额政策共享具有相同 <SharedName>
值的配额计数。如果存在此元素,则还必须存在 <SharedName>
和 <CountOnly>
元素。
如需了解详情和示例,请参阅配置共享配额计数器。
默认值 | false |
是否必需? | 可选 |
类型 | 布尔值 |
父元素 |
<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 | 布尔值 | 只读 |
指明政策是否失败(true 或 false)。 |
错误参考信息
本部分介绍当此政策触发错误时返回的故障代码和错误消息,以及由 Apigee 设置的故障变量。在开发故障规则以处理故障时,请务必了解此信息。如需了解详情,请参阅您需要了解的有关政策错误的信息和处理故障。
运行时错误
政策执行时可能会发生这些错误。
故障代码 | HTTP 状态 | 原因 | 修复 |
---|---|---|---|
policies.ratelimit.FailedToResolveQuotaIntervalReference |
500 |
如果未在 Quota 政策中定义 <Interval> 元素,就会出现此错误。此元素是必需的,用于指定配额所适用的时间间隔。时间间隔可以是使用 <TimeUnit> 元素定义的分钟、小时、天、周或月。 |
build |
policies.ratelimit.FailedToResolveQuotaIntervalTimeUnitReference |
500 |
如果未在 Quota 政策中定义 <TimeUnit> 元素,就会出现此错误。此元素是必需的,用于指定配额所适用的时间单位。时间间隔可以是分钟、小时、天、周或月。 |
build |
policies.ratelimit.InvalidMessageWeight |
500 |
如果通过流变量指定的 <MessageWeight> 元素的值无效(非整数值),就会出现此错误。 |
build |
policies.ratelimit.QuotaViolation |
500 |
超过配额限制。 | 不适用 |
部署错误
错误名称 | 原因 | 修复 |
---|---|---|
InvalidQuotaInterval |
如果 <Interval> 元素中指定的配额间隔不是整数,则 API 代理的部署将失败。例如,如果在 <Interval> 元素中指定的配额间隔为 0.1,则 API 代理的部署将失败。 |
build |
InvalidQuotaTimeUnit |
如果 <TimeUnit> 元素中指定的时间单位不受支持,则 API 代理的部署将失败。支持的时间单位包括 minute 、hour 、day 、week 和 month 。 |
build |
InvalidQuotaType |
如果 <Quota> 元素中的 type 属性指定的配额类型无效,则 API 代理的部署将失败。支持的配额类型包括 default 、calendar 、flexi 和 rollingwindow 。 |
build |
InvalidStartTime |
如果 <StartTime> 元素中指定的时间格式无效,则 API 代理的部署将失败。有效格式为 yyyy-MM-dd HH:mm:ss ,这是 ISO 8601 日期和时间格式。例如,如果在 <StartTime> 元素中指定的时间为 7-16-2017 12:00:00 ,则 API 代理的部署将失败。 |
build |
StartTimeNotSupported |
如果指定的 <StartTime> 元素的配额类型不是 calendar 类型,则 API 代理的部署将失败。仅 calendar 配额类型支持 <StartTime> 元素。例如,如果在 <Quota> 元素中将 type 属性设置为 flexi 或 rolling window ,则 API 代理的部署将失败。 |
build |
InvalidTimeUnitForDistributedQuota |
如果将 <Distributed> 元素设置为 true 且将 <TimeUnit> 元素设置为 second ,则 API 代理的部署将失败。时间单位 second 对于分配的配额无效。 |
build |
InvalidSynchronizeIntervalForAsyncConfiguration |
如果在 Quota 政策的 <AsynchronousConfiguration> 元素中为 <SyncIntervalInSeconds> 元素指定的值小于零,则 API 代理的部署将会失败。 |
build |
InvalidAsynchronizeConfigurationForSynchronousQuota |
如果将 Quota 政策中 <AsynchronousConfiguration> 元素的值设置为 true ,该元素还具有使用 <AsynchronousConfiguration> 元素定义的异步配置,则 API 代理的部署将会失败。 |
build |
故障变量
此政策触发错误时设置这些变量。如需了解详情,请参阅您需要了解的有关政策错误的信息。
变量 | 地点 | 示例 |
---|---|---|
fault.name="fault_name" |
fault_name 是故障名称,如上面的运行时错误表中所列。故障名称是故障代码的最后一部分。 | fault.name Matches "QuotaViolation" |
ratelimit.policy_name.failed |
policy_name 是抛出故障的政策的用户指定名称。 | ratelimit.QT-QuotaPolicy.failed = true |
错误响应示例
{ "fault":{ "detail":{ "errorcode":"policies.ratelimit.QuotaViolation" }, "faultstring":"Rate limit quota violation. Quota limit exceeded. Identifier : _default" } }
故障规则示例
<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>