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: Confirme que o seu handler de resiliência HTTP .NET tenta novamente, aplica um intervalo de espera entre tentativas e atinge o tempo limite conforme esperado
Tempo: 15 minutos
Plugins:GenericRandomErrorPlugin, RetryAfterPlugin, LatencyPlugin
Pré-requisitos:Configurar o Dev Proxy, uma aplicação .NET que utiliza Microsoft.Extensions.Http.Resilience
Acrescentaste AddStandardResilienceHandler() ao teu HttpClient. Como sabes que funciona? As APIs que chamas raramente falham a pedido, e testes unitários que simulam HttpMessageHandler saltam o pipeline de resiliência que queres testar.
O Dev Proxy situa-se entre a tua aplicação e a API. Ele devolve erros e respostas lentas à tua aplicação, por isso a aplicação continua a executar-se sem alterações e o handler de resiliência reage a respostas HTTP reais. Vês todas as tentativas no resultado do Dev Proxy.
O que faz o handler de resiliência padrão
Antes de testares, sabes o que esperar. Com as opções padrão, AddStandardResilienceHandler():
| Comportamento | Default |
|---|---|
| Retentativas ativadas | HTTP 500 e superiores, 408, 429, HttpRequestException, e TimeoutRejectedException |
| Número de tentativas | 3, com backoff exponencial e jitter, começando aos 2 segundos |
Retry-After Cabeçalho |
Cumprido. O processador espera pelo tempo que a API pede. |
| Tempo limite para a tentativa | 10 segundos por tentativa |
| Tempo total de espera | 30 segundos para a solicitação, incluindo todas as tentativas |
Para a lista completa de estratégias e os respetivos valores predefinidos, veja valores predefinidos do processador de resiliência padrão.
Encaminhe a sua aplicação através do Dev Proxy
O .NET usa o proxy do sistema, por isso, quando inicias o Dev Proxy, ele interceta os pedidos da tua app sem alterações de código. Para mais informações, consulte Usar Proxy de Desenvolvimento com aplicações .NET.
Simular erros transitórios
Cria uma configuração de Proxy de Desenvolvimento que faz falhar os pedidos à tua API com os erros que o handler repete. Este exemplo utiliza https://api.contoso.com. Substitua-a pelo URL da API que a sua aplicação invoca.
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": "transientErrors"
}
],
"urlsToWatch": [
"https://api.contoso.com/*"
],
"transientErrors": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.schema.json",
"errorsFile": "transient-errors.json",
"rate": 50
}
}
Caution
Adicione o RetryAfterPlugin antes do GenericRandomErrorPlugin no seu arquivo de configuração. Se adicionares depois, o GenericRandomErrorPlugin rejeita o pedido antes de o RetryAfterPlugin poder verificar.
No ficheiro de erros, defina uma resposta de limitação e dois erros de servidor. O valor @dynamic define o cabeçalho Retry-After e indica ao RetryAfterPlugin para verificar se a sua aplicação espera esse tempo antes de voltar a chamar a API.
Ficheiro: transient-errors.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/genericrandomerrorplugin.errorsfile.schema.json",
"errors": [
{
"request": {
"url": "https://api.contoso.com/*"
},
"responses": [
{
"statusCode": 429,
"headers": [
{
"name": "Retry-After",
"value": "@dynamic"
}
]
},
{
"statusCode": 500
},
{
"statusCode": 503
}
]
}
]
}
Inicia o Dev Proxy e executa a tua aplicação.
devproxy --config-file devproxyrc.json
Com uma taxa de falha de 50%, a maioria dos pedidos é recuperada após uma ou duas tentativas. Na saída do Dev Proxy, verifique se:
- Após uma resposta 429, a próxima tentativa para o mesmo URL ocorre decorrido o tempo
Retry-After. O Dev Proxy usa 5 segundos por predefinição. Se a tua aplicação chamar a API demasiado cedo, oRetryAfterPluginreporta isso e limita o pedido. - A tua aplicação não envia mais tentativas do que as que configuraste.
- Pedidos que não queres retentar, como um
POSTque cria um registo, são enviados apenas uma vez. Para os excluir, ligueoptions.Retry.DisableForUnsafeHttpMethods()ouoptions.Retry.DisableFor(...).
Testa o que acontece quando as tentativas acabam
As retentativas ocultam falhas temporárias. Também precisas de saber o que a tua aplicação faz quando a API continua a falhar. Inicie o Proxy de Desenvolvimento com uma taxa de falha de 100%:
devproxy --config-file devproxyrc.json --failure-rate 100
Dev Proxy mostra 4 tentativas para cada pedido: o pedido original e 3 novas tentativas. Depois da última tentativa, o processador padrão não gera. Ele devolve a última resposta de erro ao teu código. Vê o que a tua aplicação faz com isso. Por exemplo, EnsureSuccessStatusCode() lança um HttpRequestException, e GetStringAsync() também lança. Certifica-te de que a tua aplicação mostra uma mensagem útil ou recorre a uma alternativa, em vez de crashar ou mostrar um erro genérico.
Limites de tempo dos testes
APIs lentas ativam um caminho diferente no handler. Para testar, use o LatencyPlugin para atrasar respostas para além do timeout de tentativa de 10 segundos.
Ficheiro: devproxyrc.json
{
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
"plugins": [
{
"name": "LatencyPlugin",
"enabled": true,
"pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
"configSection": "slowApi"
}
],
"urlsToWatch": [
"https://api.contoso.com/*"
],
"slowApi": {
"$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/latencyplugin.schema.json",
"minMs": 11000,
"maxMs": 15000
}
}
Inicie o Dev Proxy e execute a sua app. Cada tentativa demora mais de 10 segundos, por isso o timeout da tentativa cancela-a e o manipulador tenta novamente. Após 30 segundos, o timeout total cancela o pedido e o seu código recebe um TimeoutRejectedException. Verifica se a tua aplicação lida com isso e informa o utilizador do que aconteceu.
Tip
Para testar os mesmos cenários com as suas próprias definições de resiliência, altere os valores na sua AddStandardResilienceHandler(options => ...) chamada e execute novamente as mesmas configurações de Dev Proxy.
Passo seguinte
Saiba mais sobre como simular throttling em qualquer API.
Ver também
- Utilizar o Dev Proxy com aplicações .NET - Configuração do .NET
- GenericRandomErrorPlugin - Referência completa
- RetryAfterPlugin - Verificar o comportamento de nova tentativa
- LatencyPlugin - Simula respostas lentas
- Taxa de falha dos pedidos de alteração - Ajuste a frequência com que os pedidos falham
- Utilize o Dev Proxy em CI/CD - Automatize os testes de resiliência no pipeline