Антипаттерн: повторное использование политики квот

Вы просматриваете документацию Apigee Edge .
Перейдите к документации Apigee X.
информация

Apigee Edge предоставляет возможность настроить количество разрешенных запросов к API-прокси за определенный период времени с помощью политики квот .

Антипаттерн

Если политика квот используется повторно, счетчик квот будет уменьшаться каждый раз при выполнении политики квот, независимо от того, где она используется. То есть, если политика квот используется повторно:

  • В одном и том же потоке или в разных потоках прокси-сервера API.
  • В разных целевых конечных точках прокси-сервера API

Тогда счетчик квоты будет уменьшаться при каждом выполнении, и в конечном итоге мы будем получать ошибки нарушения квоты гораздо раньше, чем ожидалось, в течение указанного интервала времени.

Давайте воспользуемся следующим примером, чтобы объяснить, как это работает.

API-прокси

Допустим, у нас есть прокси-сервер API с именем «TestTargetServerQuota», который направляет трафик на два разных целевых сервера в зависимости от пути к ресурсу. И мы хотели бы ограничить трафик API до 10 запросов в минуту для каждого из этих целевых серверов. Вот таблица, описывающая этот сценарий:

Путь к ресурсу Целевой сервер Квота
/target-us target-US.somedomain.com 10 запросов в минуту
/target-eu target-EU.somedomain.com 10 запросов в минуту

Политика квот

Поскольку квота трафика одинакова для обоих целевых серверов, мы определяем единую политику квот под названием «Quota-Minute-Target-Server», как показано ниже:

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

Целевые конечные точки

Давайте используем политику квот «Quota-Minute-Target-Server» в предварительном потоке целевой конечной точки «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>

И повторно используйте ту же политику квот «Quota-Minute-Target-Server» в предварительной обработке другой целевой конечной точки «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>

Схема входящего трафика

Допустим, мы получили в общей сложности 10 запросов API для этого прокси-сервера API в течение первых 30 секунд по следующему шаблону:

Путь к ресурсу /target-us /target-eu Все
# запросов 4 6 10

Чуть позже мы получаем 11-й запрос API с путем к ресурсу как /target-us , скажем, через 32 секунды.

Мы ожидаем, что запрос пройдет успешно, предполагая, что у нас все еще есть 6 запросов API для целевой конечной точки target-us в соответствии с разрешенной квотой.

Однако на самом деле мы получаем Quota violation error .

Причина. Поскольку мы используем одну и ту же политику квот в обеих целевых конечных точках, для отслеживания запросов API, попадающих в обе целевые конечные точки, используется один счетчик квот. Таким образом, мы исчерпаем квоту в 10 запросов в минуту коллективно, а не для отдельной целевой конечной точки.

Влияние

Этот антипаттерн может привести к фундаментальному несоответствию ожиданий, что приведет к восприятию того, что лимиты квот исчерпаны раньше времени.

Лучшая практика

  • Используйте элементы <Class> или <Identifier> чтобы обеспечить поддержку нескольких уникальных счетчиков, определив единую политику квот . Давайте переопределим политику квот «Quota-Minute-Target-Server», которую мы только что объяснили в предыдущем разделе, используя заголовок target_id в качестве <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>
    
    • Мы продолжим использовать эту политику квот в обеих целевых конечных точках «Цель-США» и «Цель-ЕС», как и раньше.
    • Теперь предположим, что если заголовок target_id имеет значение «US», то запросы направляются в целевую конечную точку «Target-US».
    • Аналогично, если заголовок target_id имеет значение «EU», тогда запросы направляются в целевую конечную точку «Target-EU».
    • Таким образом, даже если мы используем одну и ту же политику квот в обеих целевых конечных точках, отдельные счетчики квот поддерживаются на основе значения <Identifier> .
    • Таким образом, используя элемент <Identifier> мы можем гарантировать, что каждая из целевых конечных точек получит разрешенную квоту в 10 запросов.
  • Используйте отдельную политику квот в каждом из потоков/целевых конечных точек/прокси-серверов API, чтобы всегда получать разрешенное количество запросов API. Давайте теперь рассмотрим тот же пример, который использовался в приведенном выше разделе, чтобы увидеть, как мы можем достичь разрешенной квоты в 10 запросов для каждой из целевых конечных точек.
    • Определите отдельную политику квот, по одной для целевых конечных точек «Цель-США» и «Цель-ЕС».

      Политика квот для целевой конечной точки «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>
      

      Политика квот для целевой конечной точки «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>
      
    • Используйте соответствующую политику квот в определении целевых конечных точек, как показано ниже:

      Целевая конечная точка «Цель-США»:

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

      Целевая конечная точка «Цель-ЕС»:

      <!-- /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>
      
    • Поскольку мы используем отдельную политику квот в целевых конечных точках «Цель-США» и «Цель-ЕС», будет поддерживаться отдельный счетчик. Это гарантирует, что мы получим разрешенную квоту в 10 запросов API в минуту для каждой из целевых конечных точек.
  • Используйте элементы <Class> или <Identifier> , чтобы обеспечить поддержку нескольких уникальных счетчиков.