Está a ver a documentação do Apigee e do Apigee Hybrid.
Ver documentação do
Apigee Edge.
O Apigee permite configurar o número de pedidos permitidos para um proxy de API durante um período específico através da política de quotas.
Antipattern
Se uma política de quotas for reutilizada, o contador de quotas é decrementado sempre que a política de quotas é executada, independentemente do local onde é usada. Ou seja, se uma política de quotas for reutilizada:
- Dentro do mesmo fluxo ou de fluxos diferentes de um proxy de API
- Em diferentes pontos finais de destino de um proxy de API
Em seguida, o contador de quotas é decrementado sempre que é executado e acabamos por receber erros de violação de quotas muito antes do esperado para o intervalo de tempo especificado.
Vamos usar o seguinte exemplo para explicar como funciona.
API proxy
Suponhamos que temos um proxy de API denominado "TestTargetServerQuota", que encaminha o tráfego para dois servidores de destino diferentes com base no caminho do recurso. Além disso, gostaríamos de restringir o tráfego da API a 10 pedidos por minuto para cada um destes servidores de destino. Segue-se a tabela que representa este cenário:
Caminho do recurso | Servidor de destino | Quota |
---|---|---|
/target-us |
target-US.somedomain.com |
10 pedidos por minuto |
/target-eu |
target-EU.somedomain.com |
10 pedidos por minuto |
Política de quotas
Uma vez que a quota de tráfego é a mesma para ambos os servidores de destino, definimos uma única política de quotas denominada "Quota-Minute-Target-Server", conforme mostrado abaixo:
<!-- /antipatterns/examples/1-8.xml --> <Quota name="Quota-Minute-Target-Server"> <Interval>1</Interval> <TimeUnit>minute</TimeUnit> <Distributed>true</Distributed> <Allow count="10"/> </Quota>
Pontos finais de destino
Vamos usar a política de quotas "Quota-Minute-Target-Server" no preflow do ponto final 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>
E reutilize a mesma política de quotas "Quota-Minute-Target-Server" no fluxo prévio do outro ponto final "Target-EU" também:
<!-- /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>
Padrão de tráfego recebido
Suponhamos que recebemos um total de 10 pedidos de API para este proxy de API nos primeiros 30 segundos no seguinte padrão:
Caminho do recurso | /target-us |
/target-eu |
Tudo |
---|---|---|---|
# Requests | 4 | 6 | 10 |
Um pouco mais tarde, recebemos o 11.º pedido de API com o caminho do recurso como /target-us
, digamos, após 32 segundos.
Esperamos que o pedido seja processado com êxito, assumindo que ainda temos 6 pedidos de API para o ponto final de destino target-us
, de acordo com a quota permitida.
No entanto, na realidade, recebemos um Quota violation error
.
Motivo: uma vez que estamos a usar a mesma política de quotas em ambos os pontos finais de destino, é usado um contador de quotas único para acompanhar os pedidos de API que atingem ambos os pontos finais de destino. Assim, esgotamos a quota de 10 pedidos por minuto coletivamente, em vez de para o ponto final de destino individual.
Impacto
Este antipadrão pode resultar numa incompatibilidade fundamental de expetativas, o que leva à perceção de que os limites de quota se esgotaram antes do tempo.
Prática recomendada
- Use os elementos
<Class>
ou<Identifier>
para garantir que são mantidos vários contadores únicos definindo uma única política de quotas. Vamos redefinir a política de quotas "Quota-Minute-Target-Server" que acabámos de explicar na secção anterior usando o cabeçalhotarget_id
como o<Identifier>
, conforme mostrado abaixo:<!-- /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>
- Vamos continuar a usar esta política de quotas nos pontos finais de destino "Target-US" e "Target-EU" como antes.
- Agora, suponhamos que, se o cabeçalho
target_id
tiver o valor "US", os pedidos são encaminhados para o ponto final de destino "Target-US". - Da mesma forma, se o cabeçalho
target_id
tiver o valor "EU", os pedidos são encaminhados para o ponto final de destino "Target-EU". - Assim, mesmo que usemos a mesma política de quotas nos dois pontos finais de destino, são mantidos contadores de quotas separados com base no valor
<Identifier>
. - Por conseguinte, ao usar o elemento
<Identifier>
, podemos garantir que cada um dos pontos finais de destino recebe a quota permitida de 10 pedidos.
- Use uma política de quotas separada em cada um dos fluxos/pontos finais de destino/proxies de API para garantir que
obtém sempre a quantidade permitida de pedidos API. Vejamos agora o mesmo exemplo usado na secção acima para ver como podemos alcançar a quota permitida de 10 pedidos para cada um dos pontos finais de destino.
- Defina uma política de quotas separada, uma para cada um dos pontos finais de destino "Target-US" e "Target-EU"
Política de quotas para o ponto final 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 quotas para o ponto final 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>
- Use a política de quotas respetiva na definição dos pontos finais de destino, conforme mostrado abaixo:
Ponto final 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>
Ponto final 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>
- Uma vez que estamos a usar uma política de quotas separada nos pontos finais de destino "Target-US" e "Target-EU", é mantido um contador separado. Isto garante que recebemos a quota permitida de 10 pedidos da API por minuto para cada um dos pontos finais de destino.
- Defina uma política de quotas separada, uma para cada um dos pontos finais de destino "Target-US" e "Target-EU"
- Use os elementos
<Class>
ou<Identifier>
para garantir a manutenção de vários contadores únicos.