Antipatrón: Vuelve a usar una política de cuotas

Estás consultando la documentación de Apigee Edge.
Consulta la documentación de Apigee X.
Información

Apigee Edge proporciona la capacidad de configurar la cantidad de solicitudes permitidas para un proxy de API durante un período específico mediante la política de cuotas.

Antipatrón

Si se vuelve a usar una política de cuotas, el contador de cuotas se reducirá cada vez que se ejecute la política de cuotas, sin importar dónde se use. Es decir, si se vuelve a usar una política de cuotas en las siguientes situaciones:

  • Dentro del mismo flujo o en flujos diferentes de un proxy de API
  • En extremos de destino diferentes de un proxy de API

Luego, el contador de cuotas se reduce cada vez que se ejecuta y dará como resultado errores de incumplimiento de cuota mucho antes de lo esperado para el intervalo especificado.

Usemos el siguiente ejemplo para explicar cómo funciona.

Proxy de API

Supongamos que tenemos un proxy de API llamado "TestTargetServerQuota", que enruta el tráfico a dos servidores de destino diferentes según la ruta de acceso del recurso. Queremos restringir el tráfico de la API a 10 solicitudes por minuto para cada uno de los servidores de destino. En esta tabla, se muestra esta situación:

Ruta de acceso a recursos Servidor de destino Cuota
/target-us target-US.somedomain.com 10 solicitudes por minuto
/target-eu target-EU.somedomain.com 10 solicitudes por minuto

Política de cuotas

Dado que la cuota de tráfico es la misma para ambos servidores de destino, definimos una sola política de cuotas denominada "Quota-Minute-Target-Server", como se muestra a continuación:

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

Extremos de destino

Usemos la política de cuotas "Quota-Minute-Target-Server" en el flujo previo del extremo de destino "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>

Además, vuelve a usar la misma política de cuotas, "Quota-Minute-Target-Server", en el flujo previo del otro extremo de destino, "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>

Patrón de tráfico entrante

Supongamos que obtenemos un total de 10 solicitudes a la API para este proxy de API en los primeros 30 segundos en el siguiente patrón:

Ruta de acceso a recursos /target-us /target-eu All
# Solicitudes 4 6 10

Un poco más tarde, obtenemos la 11a solicitud a la API con la ruta de acceso al recurso como /target-us, digamos que después de 32 segundos.

Esperamos que la solicitud se realice correctamente, siempre y cuando haya 6 solicitudes a la API para el extremo de destino target-us, según la cuota permitida.

Sin embargo, en realidad, obtenemos un Quota violation error.

Motivo: Debido a que usamos la misma política de cuotas en ambos extremos de destino, un único contador de cuotas se usa para realizar un seguimiento de las solicitudes a la API que llegan a ambos extremos de destino. Por lo tanto, agotamos la cuota de 10 solicitudes por minuto de forma colectiva en lugar de hacerlo en el extremo de destino individual.

Impacto

Este antipatrón puede dar como resultado una falta de coincidencia fundamental de las expectativas, lo que genera una percepción de que los límites de la cuota se agotaron antes de tiempo.

Práctica recomendada

  • Usa los elementos <Class> o <Identifier> para garantizar que varios contadores únicos se mantienen mediante la definición de una sola política de cuotas. Volvamos a definir la política de cuotas "Quota-Minute-Target-Server", que explicamos en la sección anterior, con el encabezado target_id como <Identifier>, como se muestra a continuación:
    <!-- /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>
    
    • Seguiremos usando esta política de cuotas en los extremos de destino "Target-US" y "Target-EU" como antes.
    • Ahora, supongamos que si el encabezado target_id tiene un valor "US", las solicitudes se enrutan al extremo de destino "Target-US".
    • Del mismo modo, si el encabezado target_id tiene el valor "EU", las solicitudes se enrutan al extremo de destino "Target-EU".
    • Por lo tanto, incluso si usamos la misma política de cuotas en ambos extremos de destino, los contadores de cuotas independientes se mantienen según el valor <Identifier>.
    • Por lo tanto, si usamos el elemento <Identifier>, podemos garantizar que cada extremo de destino obtiene la cuota permitida de 10 solicitudes.
  • Usa políticas de cuotas independientes en cada flujo, extremo de destino o proxy de API para garantizar que siempre obtengas el recuento permitido de solicitudes a la API. Ahora, veamos el mismo ejemplo que se usó en la sección anterior para ver cómo podemos alcanzar la cuota permitida de 10 solicitudes para cada extremo de destino.
    • Define una política de cuotas independiente, una para los extremos de destino "Target-US" y "Target-EU"

      Política de cuotas para el extremo de destino “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>
      

      Política de cuotas para el extremo de destino “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>
      
    • Usa la política de cuotas correspondiente en la definición de los extremos de destino como se muestra a continuación:

      Extremo de destino “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>
      

      Extremo de destino "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>
      
    • Como usamos una política de cuotas independiente en los extremos de destino "Target-US" y "Target-EU", se mantendrá un contador independiente. Esto garantiza que se obtendrá la cuota permitida de 10 solicitudes a la API por minuto para cada uno de los extremos de destino.
  • Usa los elementos <Class> o <Identifier> para garantizar que se mantienen varios contadores únicos.