您正在查看 Apigee 和 Apigee Hybrid 文档。
查看 Apigee Edge 文档。
借助 Apigee,您能够使用配额政策配置在特定时间段内 API 代理允许的请求的数量。
反模式
如果重复使用配额政策,每次执行配额政策时,配额计数器都将递减,而无论配额政策在何处使用。也就是说,如果在以下位置重复使用了配额政策:
- 在 API 代理的同一流或不同流中
- 在 API 代理的不同目标端点中
那么,每次执行配额政策时配额计数器都会递减,我们收到配额违规错误的时间将比预期的指定时间间隔早得多。
下面我们通过一个例子来说明这种情况的原理。
API 代理
假设我们有一个名为“TestTargetServerQuota”的 API 代理,它根据资源路径将流量路由到两个不同的目标服务器。我们希望将每个目标服务器的 API 流量限制为每分钟 10 个请求。以下表格描述了此情况:
资源路径 | 目标服务器 | 配额 |
---|---|---|
/target-us |
target-US.somedomain.com |
每分钟 10 个请求 |
/target-eu |
target-EU.somedomain.com |
每分钟 10 个请求 |
配额政策
由于两个目标服务器的流量配额相同,我们定义一条名为“Quota-Minute-Target-Server”配额政策,如下所示:
<!-- /antipatterns/examples/1-8.xml --> <Quota name="Quota-Minute-Target-Server"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Allow count="10"/> </Quota>
目标端点
我们在目标端点“Target-US”的前流 (preflow) 中使用配额政策“Quota-Minute-Target-Server”:
<!-- /antipatterns/examples/1-9.xml --> <TargetEndpoint name="Target-US"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Quota-Minute-Target-Server</Name> </Step> </Request> </PreFlow> <HTTPTargetConnection> <URL>http://target-us.somedomain.com</URL> </HTTPTargetConnection> </TargetEndpoint>
在另一目标端点“Target-EU”的前流中重复使用同一配额政策“Quota-Minute-Target-Server”:
<!-- /antipatterns/examples/1-10.xml --> <TargetEndpoint name="Target-EU"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Quota-Minute-Target-Server</Name> </Step> </Request> <Response/> </PreFlow> <HTTPTargetConnection> <URL>http://target-us.somedomain.com</URL> </HTTPTargetConnection> </TargetEndpoint>
传入流量模式
假设在以下模式下,我们在前 30 秒内共收到针对此 API 代理的 10 个 API 请求:
资源路径 | /target-us |
/target-eu |
全部 |
---|---|---|---|
请求数 | 4 | 6 | 10 |
假设在 32 秒后,我们收到资源路径为 /target-us
的第 11 个 API 请求。
我们认为,根据允许的配额,目标端点 target-us
还可以接受 6 个 API 请求,因此该请求能够成功通过。
但实际上,我们得到了 Quota violation error
。
原因:因为我们在两个目标端点中使用同一配额政策,因此系统使用单个配额计数器跟踪到达两个目标端点的 API 请求。因此,我们用光了每分钟总共(而不是单个目标端点)10 个请求的配额。
影响
这种反模式可能导致与预期根本不匹配的情况,使人们认为配额限制被提前用尽。
最佳做法
- 通过定义单个配额政策,使用
<Class>
或<Identifier>
元素来确保维护多个不同的计数器。我们将标头target_id
用作<Identifier>
来重新定义上一部分介绍的配额政策“Quota-Minute-Target-Server”,如下所示:<!-- /antipatterns/examples/1-11.xml --> <Quota name="Quota-Minute-Target-Server"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Allow count="10"/> <Identifier ref="request.header.target_id"/> <Distributed>true</Distributed> </Quota>
- 与之前一样,我们将继续在目标端点“Target-US”和“Target-EU”中使用此配额政策。
- 现在,假设标头
target_id
的值为“US”,则请求将路由到目标端点“Target-US”。 - 同样,如果标头
target_id
的值为“EU”,则请求会被路由到目标端点“Target-EU”。 - 因此,即使我们在两个目标端点中使用同一配额政策,系统也会根据
<Identifier>
值维护单独的配额计数器。 - 因此,通过使用
<Identifier>
元素,我们可以确保每个目标端点都获得 10 个请求的允许配额。
- 在每个流/目标端点/API 代理中使用单独的配额政策,以确保始终获得允许的 API 请求数量。现在,我们来看看上一部分中使用的示例,了解如何为每个目标端点实现 10 个请求的允许配额。
- 为每个目标端点(“Target-US”和“Target-EU”)定义单独的配额政策
目标端点“Target-US”的配额政策:
<!-- /antipatterns/examples/1-12.xml --> <Quota name="Quota-Minute-Target-Server-US"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Allow count="10"/> </Quota>
目标端点“Target-EU”的配额政策:
<!-- /antipatterns/examples/1-13.xml --> <Quota name="Quota-Minute-Target-Server-EU"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Allow count="10"/> </Quota>
- 使用目标端点定义中各自的配额政策,如下所示:
目标端点“Target-US”:
<!-- /antipatterns/examples/1-14.xml --> <TargetEndpoint name="Target-US"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Quota-Minute-Target-Server-US</Name> </Step> </Request> <Response/> </PreFlow> <HTTPTargetConnection> <URL>http://target-us.somedomain.com</URL> </HTTPTargetConnection> </TargetEndpoint>
目标端点“Target-EU”:
<!-- /antipatterns/examples/1-15.xml --> <TargetEndpoint name="Target-EU"> <PreFlow name="PreFlow"> <Request> <Step> <Name>Quota-Minute-Target-Server-EU</Name> </Step> </Request> <Response/> </PreFlow> <HTTPTargetConnection> <URL>http://target-eu.somedomain.com</URL> </HTTPTargetConnection> </TargetEndpoint>
- 由于我们在目标端点“Target-US”和“Target-EU”中使用了单独的配额政策,因此系统将维护单独的计数器。这可确保为每个目标端点获得允许的配额(每分钟 10 个 API 请求)。
- 为每个目标端点(“Target-US”和“Target-EU”)定义单独的配额政策
- 使用
<Class>
或<Identifier>
元素确保维护多个不同的计数器。