Antimodèle : réutiliser une règle de quota

Vous consultez la documentation d'Apigee Edge.
Consultez la documentation Apigee X.
en savoir plus

Apigee Edge permet de configurer le nombre de requêtes autorisées pour un proxy d'API pendant une période spécifique à l'aide de la règle de quota.

Antimodèle

Si une règle de quota est réutilisée, le compteur de quotas est diminué chaque fois que la règle de quota est exécutée indépendamment de son emplacement. Autrement dit, si une règle de quota est réutilisée :

  • Dans le même flux ou dans des flux différents d'un proxy d'API
  • Dans différents points de terminaison cibles d'un proxy d'API

Le compteur de quota diminue ensuite chaque fois que la règle est exécutée, et des erreurs de violation du quota sont envoyées bien plus tôt que prévu pour l'intervalle de temps spécifié.

Prenons l'exemple suivant pour comprendre comment cela fonctionne.

Proxy d'API

Imaginons que nous ayons un proxy d'API nommé "TestTargetServerQuota", qui achemine le trafic vers deux serveurs cibles différents en fonction du chemin d'accès à la ressource. Nous aimerions limiter le trafic de l'API à 10 requêtes par minute pour chacun de ces serveurs cibles. Le tableau ci-dessous illustre ce scénario:

Chemin d'accès à la ressource Serveur cible Quota
/target-us target-US.somedomain.com 10 requêtes par minute
/target-eu target-EU.somedomain.com 10 requêtes par minute

Règles de quotas

Étant donné que le quota de trafic est le même pour les deux serveurs cibles, nous définissons une seule règle de quota nommée "Quota-Minute-Target-Server", comme indiqué ci-dessous:

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

Points de terminaison cibles

Utilisons la règle de quota "Quota-Minute-Target-Server" dans le pré-flux du point de terminaison cible "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>

Réutilisez également la même règle de quota "Quota-Minute-Target-Server" dans le pré-flux de l'autre point de terminaison cible "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>

Modèle de trafic entrant

Imaginons que nous obtenions un total de 10 requêtes API pour ce proxy d'API dans les 30 premières secondes, selon le schéma suivant:

Chemin d'accès à la ressource /target-us /target-eu Toutes
Nombre de requêtes 4 6 10

Un peu plus tard, nous obtenons la 11e requête API avec le chemin d'accès à la ressource /target-us, disons après 32 secondes.

La requête devrait aboutir, car il reste six requêtes API pour le point de terminaison cible target-us, conformément au quota autorisé.

Cependant, nous recevons l'erreur Quota violation error.

Motif : Comme nous utilisons la même règle de quota pour les deux points de terminaison cibles, un compteur de quota unique est utilisé pour effectuer le suivi des requêtes API qu'ils reçoivent. Ainsi, le quota de 10 requêtes par minute est épuisé par les deux points de terminaison cibles, et non par un seul.

Impact

Cet antimodèle peut être la cause d'une différence importante entre les attentes de l'utilisateur et le nombre de requêtes réellement traitées, et donner l'impression que les limites de quota ont été atteintes trop tôt.

Bonne pratique

  • Utilisez les éléments <Class> ou <Identifier> pour vous assurer que plusieurs compteurs uniques sont utilisés pour une règle de quota donnée. Redéfinissons la règle de quota "Quota-Minute-Target-Server" que nous venons de voir en utilisant l'en-tête target_id comme <Identifier> pour, comme indiqué ci-dessous :
    <!-- /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>
    
    • Nous continuerons à utiliser cette règle de quota dans les points de terminaison cibles "Target-US" et "Target-EU".
    • Supposons maintenant que les requêtes soient acheminées vers le point de terminaison cible "Target-US" si l'en-tête target_id comporte la valeur "US".
    • De même, si l'en-tête target_id comporte la valeur "EU", les requêtes sont acheminées vers le point de terminaison cible "Target-EU".
    • Ainsi, même si nous utilisons la même règle de quota pour les deux points de terminaison cibles, des compteurs de quota distincts sont utilisés en fonction de la valeur <Identifier>.
    • Par conséquent, en utilisant l'élément <Identifier>, nous pouvons nous assurer que chacun des points de terminaison cibles obtient le quota autorisé de 10 requêtes.
  • Utilisez une règle de quota distincte pour chacun des flux, points de terminaison cibles ou proxys d'API pour vous assurer de toujours disposer du nombre autorisé de requêtes API. Examinons maintenant le même exemple que dans la section ci-dessus pour voir comment atteindre le quota autorisé de 10 requêtes pour chacun des points de terminaison cibles.
    • Définissez des règles de quota distinctes, une pour chaque point de terminaison cible "Target-US" et "Target-EU".

      Règle de quota pour le point de terminaison cible "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>
      

      Règle de quota pour le point de terminaison cible "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>
      
    • Utilisez la règle de quota correspondante dans la définition des points de terminaison cibles, comme indiqué ci-dessous:

      Point de terminaison cible "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>
      

      Point de terminaison cible "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>
      
    • Étant donné que nous utilisons des règles de quota distinctes dans les points de terminaison cibles "Target-US" et "Target-EU", un compteur distinct sera conservé. Ainsi, nous disposons du quota autorisé de 10 requêtes API par minute pour chacun des points de terminaison cibles.
  • Utilisez les éléments <Class> ou <Identifier> pour vous assurer que plusieurs compteurs uniques sont utilisés.