Antipattern: riutilizzare un criterio per le quote

Stai visualizzando la documentazione di Apigee e Apigee hybrid.
Visualizza la documentazione di Apigee Edge.

Apigee offre la possibilità di configurare il numero di richieste consentite a un proxy API per un periodo di tempo specifico utilizzando i criteri per le quote.

Antipattern

Se un criterio per le quote viene riutilizzato, il contatore delle quote viene ridotto ogni volta che il criterio viene eseguito, indipendentemente da dove viene utilizzato. Ovvero, se un criterio per le quote viene riutilizzato:

  • All'interno dello stesso flusso o in flussi diversi di un proxy API
  • In diversi endpoint di destinazione di un proxy API

Il contatore delle quote viene ridotto ogni volta che viene eseguito e finiremo per ricevere errori di violazione delle quote molto prima di quanto previsto per l'intervallo di tempo specificato.

Prendiamo l'esempio seguente per spiegare come funziona.

Proxy API

Supponiamo di avere un proxy API denominato "TestTargetServerQuota", che indirizza il traffico a due diversi server di destinazione in base al percorso della risorsa. Inoltre, vorremmo limitare il traffico API a 10 richieste al minuto per ciascuno di questi server di destinazione. Ecco la tabella che illustra questo scenario:

Percorso della risorsa Server di destinazione Quota
/target-us target-US.somedomain.com 10 richieste al minuto
/target-eu target-EU.somedomain.com 10 richieste al minuto

Criteri per le quote

Poiché la quota di traffico è la stessa per entrambi i server di destinazione, viene definito un singolo criterio per le quote denominato "Quota-Minute-Target-Server", come illustrato di seguito:

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

Endpoint di destinazione

Utilizziamo il criterio per le quote "Quota-Minute-Target-Server" nel pre-flusso dell'endpoint di destinazione "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>

E riutilizziamo lo stesso criterio per le quote "Quota-Minute-Target-Server" anche nel pre-flusso dell'altro endpoint di destinazione "Target-UE".

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

Pattern del traffico in entrata

Supponiamo di avere un totale di 10 richieste API per questo proxy API entro i primi 30 secondi nel seguente pattern:

Percorso della risorsa /target-us /target-eu Tutti
N. richieste 4 6 10

Poco dopo, riceviamo l'undicesima richiesta API con percorso della risorsa /target-us, ad esempio dopo 32 secondi.

Prevediamo che la richiesta vada a buon fine, presumendo di avere ancora sei richieste API per l'endpoint di destinazione target-us, come previsto dalla quota consentita.

Ma, in realtà, riceviamo un Quota violation error.

Motivo: poiché viene utilizzato lo stesso criterio per le quote in entrambi gli endpoint di destinazione, viene utilizzato un unico contatore di quote per monitorare le richieste API che raggiungono entrambi gli endpoint di destinazione. Pertanto, esauriamo la quota di 10 richieste al minuto con la somma delle richieste anziché con quelle del singolo endpoint di destinazione.

Impatto

Questo antipattern può causare una fondamentale mancata corrispondenza delle aspettative, portando a pensare che i limiti di quota si siano esauriti in anticipo.

Best practice

  • Utilizza gli elementi <Class> o <Identifier> per garantire che più contatori unici vengano mantenuti definendo un singolo criterio per le quote. Ridefiniamo il criterio per le quote "Quota-Minute-Target-Server" che abbiamo appena illustrato nella sezione precedente utilizzando l'intestazione target_id come <Identifier>, come mostrato di seguito:
    <!-- /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>
    
    • Continueremo a utilizzare questo criterio per le quote in entrambi gli endpoint di destinazione "Target-US" e "Target-EU", come prima.
    • Ora supponiamo che se l'intestazione target_id abbia il valore "US", le richieste vengono instradate all'endpoint di destinazione "Target-US".
    • Allo stesso modo, se l'intestazione target_id ha il valore "EU", le richieste vengono instradate all'endpoint di destinazione "Target-EU".
    • Quindi, anche se viene utilizzato lo stesso criterio per le quote in entrambi gli endpoint di destinazione, vengono mantenuti contatori delle quote separati in base al valore <Identifier>.
    • Pertanto, utilizzando l'elemento <Identifier> possiamo garantire che ciascuno degli endpoint di destinazione riceva la quota consentita di 10 richieste.
  • Utilizza criteri per le quote separati in ciascuno dei flussi/endpoint di destinazione/proxy API in modo da poter ottenere sempre il conteggio consentito di richieste API. Analizziamo lo stesso esempio utilizzato nella sezione precedente per capire come ottenere la quota consentita di 10 richieste per ciascuno degli endpoint di destinazione.
    • Definisci un criterio per le quote separato, uno ciascuno per gli endpoint di destinazione "Target-US" e "Target-UE"

      Criterio per le quote per l'endpoint di destinazione "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>
      

      Criterio per le quote per l'endpoint di destinazione "Target-UE":

      <!-- /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>
      
    • Utilizza il rispettivo criterio per le quote nella definizione degli endpoint di destinazione, come illustrato di seguito:

      Endpoint di destinazione "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>
      

      Endpoint di destinazione "Target-UE":

      <!-- /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>
      
    • Poiché utilizziamo criteri per le quote separati negli endpoint di destinazione "Target-US" e "Target-UE", verrà mantenuto un contatore separato. Questo assicura di ottenere la quota consentita di 10 richieste API al minuto per ciascuno degli endpoint di destinazione.
  • Utilizza gli elementi <Class> o <Identifier> per garantire che vengano mantenuti più contatori unici.