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.
Retry-After é um cabeçalho de resposta HTTP que indica à sua aplicação quanto tempo deve esperar antes de enviar o próximo pedido. O valor é ou um número de segundos ou uma data HTTP. Quando uma API o envia, é a resposta mais fiável para "quando podes tentar novamente?" porque vem do servidor que recusou o teu pedido. Para mais informações, consulte o RFC 9110, secção 10.2.3.
Como é Retry-After
O cabeçalho tem 2 formatos. A tua aplicação tem de tratar de ambos.
| Format | Example | O que significa |
|---|---|---|
| Seconds | Retry-After: 120 |
Aguarda 120 segundos (2 minutos) desde que recebeste a resposta. O valor é um número inteiro não negativo. |
| data HTTP | Retry-After: Fri, 31 Dec 1999 23:59:59 GMT |
Não envie o pedido novamente antes desta altura. A data está sempre em GMT. |
Os servidores enviam Retry-After com estes códigos de estado:
| Status | O que Retry-After significa |
Source |
|---|---|---|
429 Too Many Requests |
Quanto tempo esperar antes de enviar um novo pedido? O servidor pode incluí-lo. | RFC 6585, secção 4 |
503 Service Unavailable |
Quanto tempo se espera que o serviço esteja indisponível. O servidor pode incluí-lo. | RFC 9110, secção 15.6.4 |
413 Content Too Large |
Se a condição for temporária, o servidor deve informar depois de quanto tempo deixará de se verificar. | RFC 9110, secção 15.5.14 |
Qualquer 3xx redirecionamento |
O tempo mínimo para esperar antes de seguir o redirecionamento. | RFC 9110, secção 10.2.3 |
O cabeçalho é opcional. Algumas APIs usam os seus próprios cabeçalhos. Por exemplo, o GitHub indica-te através de x-ratelimit-reset quando o teu limite é reiniciado. Para mais informações, veja Limite de pedidos da API do GitHub excedido.
Como lidar com Retry-After
- Leia ambos os formatos. Se o valor for um número, é em segundos. Caso contrário, analise-o como uma data e subtraia a hora atual. Se a data já tiver passado, pode tentar novamente imediatamente.
- Espere pelo menos o tempo que o cabeçalho indicar. Tentar novamente mais cedo normalmente resulta em outro
429ou503. Algumas APIs continuam a contar os teus pedidos enquanto aplicam limitação de taxa, por isso tentativas antecipadas podem aumentar o tempo de espera. Por exemplo, veja as orientações do Microsoft Graph para limitação (throttling). - Recorrer a backoff com jitter quando o cabeçalho estiver em falta. Duplique o tempo de espera após cada tentativa falhada, adicione um valor aleatório para que muitos clientes não voltem a tentar no mesmo momento e defina um limite máximo para esse tempo de espera.
- Limita as tuas tentativas. Após algumas tentativas, devolve o erro ao chamador.
- Verifica se uma nova tentativa pode ajudar. Algumas APIs retornam
429quando os seus créditos se esgotam ou atinge o limite de despesa. Esperar não resolve essas coisas. Para um exemplo, veja OpenAI insufficient_quota e credit_balance_exhausted.
function retryDelayMs(response, attempt) {
const value = response.headers.get('retry-after');
if (value) {
const seconds = Number(value);
const ms = Number.isNaN(seconds) ? Date.parse(value) - Date.now() : seconds * 1000;
if (!Number.isNaN(ms)) {
return Math.max(ms, 0);
}
}
// No usable header: exponential backoff with jitter, capped at 30 seconds
return Math.random() * Math.min(30_000, 1_000 * 2 ** attempt);
}
O que fazem os SDKs populares
Muitos SDKs tratam de Retry-After por si, mas só até ficarem sem tentativas. Então o teu código gera o erro.
| SDK | O que faz por defeito |
|---|---|
| .NET manipulador de resiliência padrão | Tenta novamente as respostas 408, 429 e 5xx até 3 vezes com backoff exponencial e jitter. Usa Retry-After para o atraso porque ShouldRetryAfterHeader por defeito é true. |
| Microsoft Graph SDKs | Usa Retry-After quando está presente, e recorre ao backoff exponencial quando não está. Os pedidos dentro de um lote JSON não são retentados automaticamente. |
| OpenAI Python SDK | Tenta novamente em caso de erros de ligação e as respostas 408, 409, 429 e 5xx 2 vezes com um curto backoff exponencial. Configure max_retries para o alterar. |
Verifica a documentação do teu SDK para a política exata e testa o que acontece depois da última tentativa falhar.
Como testar se a sua aplicação lida com Retry-After
Raramente obténs um Retry-After enquanto desenvolves, e quando o obténs, não consegues controlar o seu valor. Por isso, a forma como testas isto decide se encontras os bugs antes dos teus utilizadores.
| Approach | O que encontra | Do que sentes falta |
|---|---|---|
| Aguardar o ambiente de produção | Fracassos reais | Tudo, até que um utilizador lhe clique |
| Simula a API nos teus testes, ou deixa o teu agente de programação escrever o mock | Se o seu código analisa o cabeçalho | Se o teu cliente HTTP real ou o SDK aguardam tempo suficiente, e o que a API realmente envia. A tua aplicação também precisa de um switch só de teste para chegar ao mock. |
| Faz pedidos à API real até que te limite | Comportamento real | Não podes ativar uma resposta com limitação de taxa a pedido, e acabas por gastar a tua quota real |
| Intercete o tráfego real da sua aplicação e devolva respostas com limitação de taxa a pedido | Se o teu SDK real e a política de repetição esperam o tempo que o cabeçalho indicar | Nada na tua aplicação muda, por isso não testa o teu código isoladamente. Guarda os testes unitários para isso. |
Experimente na sua app
O Dev Proxy interceta os pedidos da sua aplicação às APIs que escolhe e devolve 429 as respostas com um cabeçalho Retry-After, enquanto a sua aplicação continua a chamar os URLs reais. O RetryAfterPlugin lembra-se de quando cada pedido sujeito a limitação de taxa pode ser tentado novamente. Se a sua aplicação chamar o mesmo URL antes desse momento, o Dev Proxy reporta e limita novamente o pedido. O plugin regista apenas respostas 429.
No teu ficheiro de erros para o GenericRandomErrorPlugin, define o Retry-After valor de uma 429 resposta para @dynamic, e o Dev Proxy preenche o número de segundos e regista-o por ti.
Para experimentar, descarregue um preset que use ambos os plugins e inicie o Dev Proxy com ele:
devproxy config get openai-throttling
devproxy --config-file "~dataFolder/configs/openai-throttling/.devproxy/devproxyrc.json"
Depois executa a tua aplicação como de costume e vê o que faz. Para instalar Dev Proxy, consulte Configurar Dev Proxy.