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

Vous consultez la documentation d'Apigee et d'Apigee hybrid.
Consultez la documentation d'Apigee Edge.

Apigee permet de configurer le nombre de requêtes autorisées pour un proxy d'API pour une période spécifique à l'aide d'une 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 différents flux d'un proxy d'API ;
  • sur 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é.

Pour mieux comprendre ce fonctionnement, prenons l'exemple suivant :

Proxy d'API

Supposons que nous avons 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 suivant 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 règle de quota unique appelée "Quota-Minute-Target-Server", comme illustré 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

Nous allons utiliser la règle de quota "Quota-Minute-Target-Server" dans le PreFlow 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>

Et réutiliser la même règle de quota "Quota-Minute-Target-Server" dans le PreFlow 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

Supposons que nous recevons un total de 10 requêtes API pour ce proxy d'API au cours des 30 premières secondes, réparties ainsi :

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

Quelques instants plus tard, nous recevons une 11e requête API sur le chemin d'accès à la ressource /target-us, par exemple au bout de 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 maintenant la règle de quota "Quota-Minute-Target-Server", que nous venons de vous présenter, en utilisant l'en-tête target_id en tant que <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>
    • Nous allons continuer à utiliser cette règle de quota pour les points de terminaison cibles "Target-US" et "Target-EU".
    • Si l'en-tête target_id comporte la valeur "US", les requêtes sont acheminées vers le point de terminaison cible "Target-US".
    • 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, utiliser l'élément <Identifier> garantit que chacun des points de terminaison cibles dispose du 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 l'exemple utilisé dans la section ci-dessus pour découvrir comment atteindre le quota autorisé de 10 requêtes pour chacun des points de terminaison cibles.
    • Définissez deux règles de quota distinctes, une pour chacun des points de terminaison cibles "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 montré 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 une règle de quota distincte pour chacun des points de terminaison cibles "Target-US" et "Target-EU", un compteur distinct est utilisé. 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.