反模式:重複使用配額政策

查看 Apigee Edge 說明文件。
前往 Apigee X說明文件
資訊

Apigee Edge 可讓您為 「配額政策」達到特定一段時間或特定時間範圍的資料。

反模式

如果重複使用配額政策,則每次執行該配額政策時 (無論用於何處),配額計數器都會遞減。也就是說,如果在下列位置重複使用配額政策:

  • 在 API Proxy 的相同流程或不同流程中
  • 在 API Proxy 的不同目標端點

那麼每次執行配額政策時,配額計數器都會遞減,而且在指定的時間間隔內,最終都會比預期更早收到配額違規錯誤。

讓我們透過以下範例來說明運作方式。

API Proxy

假設有一個名為「TestTargetServerQuota」的 API Proxy,用於將流量轉送至兩個 建立不同的目標伺服器我們希望將每個目標伺服器的 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>

目標端點

在目標端點的預流中使用配額政策「Quota-Minute-Target-Server」 「Target-US」:

<!-- /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>

並在另一個目標的預流中重複使用相同的配額政策「Quota-Minute-Target-Server」 端點「Target-EU」

<!-- /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 Proxy 總共收到 10 個 API 要求 以下模式:

資源路徑 /target-us /target-eu 全部
# 個要求 4 6 10

稍後,我們收到第 11 個 API 要求,其資源路徑為 /target-us。 以 32 秒的廣告為例

如果按照允許的配額計算,目標端點 target-us 仍會收到 6 個 API 要求,因此我們預計此要求可成功送達。

但實際上,我們卻收到 Quota violation error

原因:兩個目標端點採用相同的配額政策,所以系統會透過單一配額計數器同時追蹤送達這兩個目標端點的 API 要求。因此,我們每分鐘總共用掉全部的配額 (10 個要求),而不是依據個別目標端點來計算。

影響

這種反模式可能會導致結果不符合基本的認知,所以感覺配額似乎提前用完了。

最佳做法

  • 請使用 <Class><Identifier> 元素,藉由定義單一的配額政策來確保維護多個不重複的計數器。重新定義配額政策 先前章節中我們剛才使用 標頭說明的「Quota-Minute-Target-Server」 target_id 做為 <Identifier>,如下所示:
    <!-- /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 Proxy 中分別使用不同的配額政策,確保您能隨時取得允許的 API 要求數量。現在我們來看看 一節,瞭解如何為每個目標達成 10 個要求的配額。 端點。
    • 分別定義配額政策,並分別定義目標端點「Target-US」並 目標歐盟地區

      目標端點「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 要求。
  • 請使用 <Class><Identifier> 元素來維護多個不重複的計數器。