Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Tip
É novo na limitação? Aprende o que é o throttling e como lidar com isso.
De relance
Objetivo: Testar como a sua aplicação lida com os limites de taxa da API REST do GitHub
Tempo: 15 minutos
Plugins:RateLimitingPlugin, GenericRandomErrorPlugin, RetryAfterPlugin
Pré-requisitos:Configurar o Proxy de Desenvolvimento
A sua aplicação faz chamadas à API do GitHub. Funciona na sua máquina, depois um trabalho de CI, uma grande organização ou um dia de muito movimento ultrapassa o limite de taxa e começa a falhar. Para testar contra a API real, terias de esgotar a tua quota de pedidos e depois esperar até uma hora antes de poderes tentar novamente. O Dev Proxy simula os limites de taxa do GitHub localmente, com um limite e uma janela de tempo que escolhes.
Saiba o que o GitHub devolve
O GitHub tem dois tipos de limites de frequência para a API REST.
Os limites de taxa primária limitam o número de pedidos que efetua por hora. Por exemplo, 60 para pedidos não autenticados e 5.000 para pedidos com um token de acesso pessoal. Cada resposta inclui cabeçalhos que mostram onde está:
| Header | Meaning |
|---|---|
x-ratelimit-limit |
O número máximo de solicitações por hora |
x-ratelimit-remaining |
O número de solicitações restantes na janela atual |
x-ratelimit-reset |
O momento em que a janela é reinicializada, em segundos epoch UTC |
Quando ultrapassa o limite primário, o GitHub retorna 403 ou 429 com x-ratelimit-remaining definido para 0. Não volte a tentar até à hora em x-ratelimit-reset.
Os limites de taxa secundários protegem o GitHub de picos, como demasiados pedidos em simultâneo ou criação de conteúdo demasiado rápida. Quando ultrapassa um, o GitHub devolve 403 ou 429, com uma mensagem sobre um limite secundário de taxa. Se a resposta tiver um retry-after cabeçalho, espere esse número de segundos. Caso contrário, espere pelo menos um minuto e aumente o tempo de espera se o pedido continuar a falhar.
O GitHub pode bloquear integrações que continuam a enviar pedidos enquanto têm o limite de pedidos atingido. Para mais informações, consulte Limites de taxa para a API REST na documentação do GitHub.
Simule o limite de taxa primária
Use o RateLimitingPlugin para contar pedidos HTTP e devolver os cabeçalhos do limite de taxa do GitHub. Para testar sem esperar uma hora, use um pequeno limite e uma janela curta.
Ficheiro: devproxyrc.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "RetryAfterPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "RateLimitingPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "githubRateLimit"
}
],
"urlsToWatch": [
"https://api.github.com/*"
],
"githubRateLimit": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/ratelimitingplugin.schema.json",
"headerLimit": "x-ratelimit-limit",
"headerRemaining": "x-ratelimit-remaining",
"headerReset": "x-ratelimit-reset",
"resetFormat": "UtcEpochSeconds",
"costPerRequest": 1,
"rateLimit": 5,
"resetTimeWindowSeconds": 60,
"warningThresholdPercent": 0,
"whenLimitExceeded": "Custom",
"customResponseFile": "github-rate-limit-exceeded.json"
}
}
Caution
Adicione o RetryAfterPlugin antes do RateLimitingPlugin no seu arquivo de configuração. Se adicionares isso depois, o RateLimitingPlugin trata do pedido antes de o RetryAfterPlugin o poder verificar.
No ficheiro de resposta personalizado, defina a resposta que o GitHub devolve quando ultrapassa o limite de taxa principal.
Ficheiro: github-rate-limit-exceeded.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/ratelimitingplugin.customresponsefile.schema.json",
"statusCode": 429,
"headers": [
{
"name": "content-type",
"value": "application/json; charset=utf-8"
}
],
"body": {
"message": "API rate limit exceeded for user ID 1.",
"documentation_url": "https://docs.github.com/rest/overview/rate-limits-for-the-rest-api"
}
}
Inicia o Dev Proxy e executa a tua aplicação.
devproxy --config-file devproxyrc.json
O Dev Proxy encaminha os primeiros 5 pedidos de cada minuto para o GitHub e define os x-ratelimit-* cabeçalhos nas respostas. A partir do 6.º pedido, o Proxy de Desenvolvimento devolve a resposta do limite de taxa com x-ratelimit-remaining definido para 0 e x-ratelimit-reset definido para o final da janela. Se a tua app chamar a API novamente antes da janela reiniciar, o RetryAfterPlugin comunica isso e limita a taxa do pedido.
Verifique se a sua aplicação:
- Lê
x-ratelimit-remaininge abranda antes de chegar a0. - Deixa de chamar a API após uma resposta de limite de pedidos e espera até
x-ratelimit-reset. - Informa o utilizador do que está a acontecer, por exemplo "Limite de taxa do GitHub atingido, a tentar novamente às 14:05", em vez de falhar silenciosamente.
Note
O GitHub devolve ou 403 ou 429 quando ultrapassar um limite de taxa. Para testar se a tua aplicação também lida com 403, muda statusCode para 403. O RetryAfterPlugin só regista respostas 429, por isso não reporta tentativas antecipadas após um 403.
Tip
O Dev Proxy encaminha os pedidos para o GitHub até que o limite simulado seja atingido. Estes pedidos também contam para o seu limite real de pedidos do GitHub.
Simular limites de taxa secundária
Os limites de taxa secundários aparecem em ráfagas e incluem um retry-after cabeçalho. Utilize o GenericRandomErrorPlugin para os devolver aleatoriamente.
Ficheiro: devproxyrc.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "RetryAfterPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll"
},
{
"name": "GenericRandomErrorPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "githubSecondaryRateLimit"
}
],
"urlsToWatch": [
"https://api.github.com/*"
],
"githubSecondaryRateLimit": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.schema.json",
"errorsFile": "github-secondary-rate-limit.json",
"rate": 50,
"retryAfterInSeconds": 60
}
}
Ficheiro: github-secondary-rate-limit.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.errorsfile.schema.json",
"errors": [
{
"request": {
"url": "https://api.github.com/*"
},
"responses": [
{
"statusCode": 429,
"headers": [
{
"name": "content-type",
"value": "application/json; charset=utf-8"
},
{
"name": "retry-after",
"value": "@dynamic"
}
],
"body": {
"message": "You have exceeded a secondary rate limit. Please wait a few minutes before you try again.",
"documentation_url": "https://docs.github.com/rest/overview/rate-limits-for-the-rest-api#about-secondary-rate-limits"
}
}
]
}
]
}
Inicia o Dev Proxy e executa a tua aplicação. Verifica se a tua aplicação espera o número de segundos indicados no cabeçalho retry-after antes de voltar a chamar a API. Se não o fizer, o RetryAfterPlugin comunica isso.
Se usares o Octokit com o plugin de limitação, verifica se os teus handlers onRateLimit e onSecondaryRateLimit funcionam e se eles devolvem o resultado que esperas.
Passo seguinte
Saiba mais sobre o RateLimitingPlugin.
Ver também
- Simular respostas da API com limite de taxa - Limites de taxa em qualquer API
- Teste se a minha aplicação lida corretamente com o throttling - Throttling em qualquer API
- RetryAfterPlugin - Verificar o comportamento de nova tentativa
- Utilize o Dev Proxy em CI/CD - Automatize os testes de resiliência no pipeline