Antywzór: ponowne wykorzystywanie zasad dotyczących limitów

Przeglądasz dokumentację Apigee Edge.
Przejdź do Dokumentacja Apigee X.
informacje.

Apigee Edge umożliwia skonfigurowanie liczby dozwolonych żądań dla serwera proxy interfejsu API dla w wybranym okresie za pomocą zasad dotyczących limitów.

Antywzór

Jeśli ponownie użyjesz zasady dotyczącej limitu, licznik limitu będzie zmniejszany za każdym razem, gdy Zasada dotycząca limitów jest wykonywana niezależnie od tego, gdzie jest używana. Oznacza to, że jeśli zasada dotycząca limitów jest ponownie wykorzystane:

  • w ramach tego samego procesu lub różnych przepływów na serwerze proxy interfejsu API;
  • W różnych docelowych punktach końcowych serwera proxy interfejsu API

Przy każdym wykonaniu licznika limitu jest on zmniejszany, dzięki czemu Błędy związane z naruszeniem limitu znacznie wcześniej niż oczekiwano w określonym przedziale czasu.

Wyjaśnimy to na przykładzie poniżej.

Serwer proxy interfejsu API

Załóżmy, że mamy serwer proxy API o nazwie „TestTargetServerLimit”, który kieruje ruch do dwóch różnych serwerów docelowych na podstawie ścieżki zasobu. Chcielibyśmy też ograniczyć ruch generowany przez interfejs API, do 10 żądań na minutę dla każdego z tych serwerów docelowych. Oto tabela, która to przedstawia scenariusz:

Ścieżka zasobu Serwer docelowy Limit
/target-us target-US.somedomain.com 10 żądań na minutę
/target-eu target-EU.somedomain.com 10 żądań na minutę

Zasady dotyczące limitów

Ponieważ limit ruchu jest taki sam dla obu serwerów docelowych, definiujemy jedną zasadę limitu o nazwie „Limit-Minute-Target-Server”, jak pokazano poniżej:

<!-- /antipatterns/examples/1-8.xml -->
<Quota name="Quota-Minute-Target-Server">
  <Interval>1</Interval>
  <TimeUnit>minute</TimeUnit>
  <Distributed>true</Distributed>
  <Allow count="10"/>
</Quota>

Docelowe punkty końcowe

Użyjmy zasady limitów „Limit-Minute-Target-Server” we wstępnym przepływie docelowego punktu końcowego „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>

I ponownie użyj tej samej zasady limitów „Limit-Minute-Target-Server” we wstępnym przepływie drugiego celu. oraz punkt końcowy „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>

Wzorzec ruchu przychodzącego

Załóżmy, że w ciągu pierwszych 30 sekund otrzymujemy łącznie 10 żądań do interfejsu API dla tego serwera proxy następujący wzorzec:

Ścieżka zasobu /target-us /target-eu Wszystko
# żądań 4 6 10

Nieco później otrzymujemy 11. żądanie do interfejsu API ze ścieżką zasobu /target-us, powiedzmy po 32 sekundach.

Oczekujemy, że żądanie zostanie zrealizowane, zakładając, że nadal mamy 6 żądań do interfejsu API docelowy punkt końcowy target-us zgodnie z dozwolonym limitem.

Jednak w rzeczywistości otrzymujemy Quota violation error.

Przyczyna: w obu punktach końcowych używamy tej samej zasady dotyczącej limitów, więc licznik pojedynczego limitu służy do śledzenia żądań API docierających do obu docelowych punktów końcowych. Dlatego wyczerpają łącznie limit 10 żądań na minutę, a nie dla poszczególnych wartości docelowych punktu końcowego.

Wpływ

Ten antywzorzec może prowadzić do fundamentalnej niezgodności oczekiwań i wprowadzania w błąd. że limity zostały wcześniej wyczerpane.

Sprawdzona metoda

  • Użyj elementów <Class> lub <Identifier>, aby zapewnić ich kilka; liczniki unikalnych użytkowników są utrzymywane przez zdefiniowanie jednej zasady limitów. Zdefiniujmy ponownie zasadę limitów „Limit-Minute-Target-Server”, który omówiliśmy w poprzedniej sekcji za pomocą nagłówka target_id jako <Identifier> dla jak w poniższym przykładzie:
    <!-- /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>
    
    • Będziemy nadal stosować tę zasadę dotyczącą limitów zarówno w docelowych punktach końcowych „Target-US”, jak „Target-EU”, tak jak wcześniej.
    • Jeśli nagłówek target_id ma wartość „US”, żądania są kierowane do w docelowym punkcie końcowym „Target-US”.
    • I podobnie, jeśli nagłówek target_id ma wartość „EU”, żądania są kierowane do środowiska docelowego. punktu końcowego „Target-EU”.
    • Dlatego nawet jeśli użyjemy tej samej zasady dotyczącej limitu w obu docelowych punktach końcowych, oddzielne liczniki limitów są utrzymywane na podstawie wartości <Identifier>.
    • Dlatego za pomocą elementu <Identifier> możemy mieć pewność, że każdy z docelowych punktów końcowych uzyskać dozwolony limit 10 żądań.
  • Użyj osobnej zasady dotyczącej limitów w każdym przepływie/docelowym punkcie końcowym/proxy interfejsu API, aby mieć pewność, że zawsze pobierać dozwoloną liczbę żądań do interfejsu API. Spójrzmy teraz na ten sam przykład użyty w powyżej, aby zobaczyć, jak osiągnąć limit 10 żądań dla każdego celu i punktów końcowych.
    • Zdefiniuj osobną zasadę dotyczącą limitów, po jednej dla docelowych punktów końcowych „Target-US” oraz „Target-EU” (Docelowa UE)

      Zasady dotyczące limitów dla docelowego punktu końcowego „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>
      

      Zasady dotyczące limitów dla docelowego punktu końcowego „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>
      
    • Użyj odpowiedniej zasady limitów w definicji docelowych punktów końcowych, jak pokazano poniżej:

      Docelowy punkt końcowy „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>
      

      Docelowy punkt końcowy „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>
      
    • Ponieważ stosujemy osobną zasadę dotyczącą limitów w docelowych punktach końcowych „Target-US” oraz „Target-EU”, zostanie zarejestrowany osobny licznik. Dzięki temu będziemy mogli uzyskać 10 żądań do interfejsu API na minutę dla każdego docelowego punktu końcowego.
  • Użyj elementów <Class> lub <Identifier>, by mieć pewność, gdy jest kilka liczników unikalnych użytkowników.