Anti-Pattern: Kontingentrichtlinie wiederverwenden

<ph type="x-smartling-placeholder"></ph> Sie sehen die Dokumentation zu Apigee Edge.
Gehen Sie zur Apigee X-Dokumentation.
Weitere Informationen

Apigee Edge bietet die Möglichkeit, die Anzahl der zulässigen Anfragen für einen API-Proxy für für einen bestimmten Zeitraum mithilfe der Kontingentrichtlinie.

Anti-Pattern

Beim Wiederverwenden einer Kontingentrichtlinie wird der Kontingentzähler bei jeder Ausführung der Kontingentrichtlinie verringert, unabhängig davon, wo Kontingent verbraucht wird. Wird also eine Kontingentrichtlinie wiederverwendet:

  • Innerhalb desselben Ablaufs oder verschiedener Abläufe eines API-Proxys
  • In verschiedenen Zielendpunkten eines API-Proxys

wird der Kontingentzähler bei jeder Ausführung verringert und es kommt viel früher als für die bestimmte Zeitspanne angenommen zu Fehlern infolge eines Kontingentverstoßes.

Das folgende Beispiel veranschaulicht, wie das funktioniert.

API-Proxy

Nehmen wir an, wir haben einen API-Proxy namens „TestTargetServerQuota“, der Traffic an zwei je nach Ressourcenpfad unterschiedliche Zielserver. Außerdem möchten wir den API-Traffic auf 10 Anfragen pro Minute pro Zielserver beschränken. In der Tabelle unten sehen Sie, Szenario:

Ressourcenpfad Zielserver Kontingent
/target-us target-US.somedomain.com 10 Anfragen pro Minute
/target-eu target-EU.somedomain.com 10 Anfragen pro Minute

Kontingentrichtlinie

Da das Traffic-Kontingent für beide Zielserver identisch ist, definieren wir eine Kontingentrichtlinie. und nennen Sie sie „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>

Zielendpunkte

Verwenden wir die Kontingentrichtlinie „Quota-Minute-Target-Server“ im Preflow des Zielendpunkts. „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>

Und verwenden Sie dieselbe Kontingentrichtlinie „Quota-Minute-Target-Server“ im Preflow des anderen Zielservers. Endpunkt „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>

Muster für eingehenden Traffic

Angenommen, wir erhalten insgesamt 10 API-Anfragen für diesen API-Proxy innerhalb der ersten 30 Sekunden in folgendes Muster:

Ressourcenpfad /target-us /target-eu Alle
Anzahl der Anfragen 4 6 10

Etwas später erhalten wir die elfte API-Anfrage mit dem Ressourcenpfad /target-us. nach 32 Sekunden.

Wir gehen unter der Annahme, dass wir nach zulässigem Kontingent noch sechs API-Anfragen für den Zielendpunkt target-us haben, davon aus, dass die Anfrage erfolgreich ausgeführt wird.

Tatsächlich erhalten wir jedoch diesen Fehler: Quota violation error.

Grund: Weil wir für beide Zielendpunkte dieselbe Kontingentrichtlinie verwenden, dient zum Erfassen der API-Anfragen an beiden Zielendpunkten ein einzelner Kontingentzähler. Entsprechend erschöpfen wir das Kontingent von 10 Anfragen pro Minute aggregiert und nicht für den einzelnen Zielendpunkt aus.

Auswirkungen

Dieses Anti-Pattern kann zu einer bedeutenden Abweichung führen und zu der Annahme, dass die Kontingentlimits zu schnell aufgebraucht wurden.

Best Practice

  • Verwenden Sie das Element <Class> oder <Identifier>, um mehrere eindeutige Zähler durch die Definition einer einzigen Kontingentrichtlinie zu verwalten. Die Kontingentrichtlinie neu definieren "Kontingent-Minute-Zielserver", das wir im vorherigen Abschnitt unter Verwendung des Headers target_id als <Identifier> für (siehe unten):
    <!-- /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>
    
    • Wir werden diese Kontingentrichtlinie weiterhin sowohl für die Zielendpunkte „Target-US“ als auch für „Target-EU“ verwendet.
    • Wenn der Header target_id den Wert „US“ hat, werden die Anfragen an den Zielendpunkt „Target-US“.
    • Hat der Header „target_id“ den Wert „EU“, werden die Anfragen an das Ziel Endpunkt „Target-EU“.
    • Auch wenn wir für beide Zielendpunkte dieselbe Kontingentrichtlinie verwenden, werden separate Kontingentzähler auf Grundlage des Werts <Identifier> verwaltet.
    • Mit dem Element <Identifier> können wir entsprechend dafür sorgen, dass jeder der Zielendpunkte das zulässige Kontingent von 10 Anfragen erhält.
  • Verwenden Sie in jedem der Abläufe/Zielendpunkte/API-Proxys separate Kontingentrichtlinien, um immer die zulässige Anzahl von API-Anfragen zu erhalten. Sehen wir uns nun das gleiche Beispiel aus der oben, um zu erfahren, wie wir das zulässige Kontingent von 10 Anfragen pro Endpunkten.
    • Definieren Sie eine separate Kontingentrichtlinie, jeweils eine für die Zielendpunkte „Target-US“ und „Ziel-EU“

      Kontingentrichtlinie für den Zielendpunkt „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>
      

      Kontingentrichtlinie für den Zielendpunkt „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>
      
    • Verwenden Sie die entsprechende Kontingentrichtlinie in der Definition der Zielendpunkte, wie unten dargestellt:

      Zielendpunkt „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>
      

      Zielendpunkt „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>
      
    • Da wir für die Zielendpunkte „Target-US“ eine separate Kontingentrichtlinie „Target-EU“, wird ein separater Zähler verwaltet. Dadurch wird sichergestellt, dass wir für jeden der Zielendpunkte das zulässige Kontingent von 10 API-Anfragen pro Minute erhalten.
  • Verwenden Sie das Element <Class> oder <Identifier>, um mehrere eindeutige Zähler zu verwalten.