Niveau :


13 minutes de lecture

Dans cet article, vous allez apprendre à rendre votre application résiliente avec Visual Studio et la célèbre bibliothèque Polly ainsi :
- Qu’est-ce que la résilience ?
- Prérequis
- Modification du projet ApiRessourcesExternes
- Installation et configuration de Polly
- Création d’une stratégie de type RETRY
Qu’est-ce que la résilience ?
Définition de la résilience informatique : Dans le domaine des technologies de l’information, la résilience fait référence à la capacité d’un système informatique à continuer à fonctionner en cas de panne, d’incident, de piratage ou d’augmentation des opérations commerciales (source oracle.com)
Il existe des implémentations permettant lors de la consommation de ressources externes (ressources sur lesquelles vous n’avez aucune garantie quant à leurs disponibilités) de créer des stratégies comme par exemple :
- retenter un appel à la ressource,
- retenter un appel à la ressource après un certain laps de temps,
- retenter un appel à la ressource un certain nombre de fois,
- router vers une autre ressource ou une autre action,
- définir une alternative car la ressource n’est pas disponible,
- ect…
Polly vous permet de faire tout cela et bien plus encore.
Prérequis
- Un projet web comme par exemple le template API web ASP.NET Core contenant un controller avec une méthode (nom : ApiRessourcesExternes)
- Un autre projet web qui permettra d’appeler ApiRessourcesExternes et qui contiendra les stratégies de résiliences (nom : ApiResiliencesPolicies). Vous trouverez ci-dessous un projet déjà tout prêt
Modification du projet ApiRessourcesExternes
Commençons par apporter une modification sur le projet ApiRessourcesExternes afin de simuler de l’instabilité réseau :
[Route("{count}")]
[HttpGet]
public ActionResult<WeatherForecast> Get(int count)
{
Random random = new Random();
var result = random.Next(0, 100);
if (result>count)
{
return Ok(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray());
}
else
return StatusCode(StatusCodes.Status500InternalServerError);
}
La méthode contient un paramètre qui permettra de générer de manière aléatoire des erreurs de serveur. Par exemple, un appel avec une valeur initialisé à 50 devrait générer à peu près 50% d’erreurs :
Testons l’appel avec le projet ApiResiliencesPolicies. Dans la classe RequestController, paramétrer la méthode CallApiExterne pour appeler le projet ApiRessourcesExternes :
[HttpGet]
public async Task<ActionResult> CallApiExterne()
{
var client = new HttpClient();
var response = await client.GetAsync("https://localhost:7286/WeatherForecast/50");
return response.IsSuccessStatusCode ? Ok() : StatusCode(StatusCodes.Status500InternalServerError);
}
Testez que l’appel fonctionne correctement. Si tout est correct, vous obtiendrez des réponses en http200 et http500.
Installation et configuration de Polly
Nous allons maintenant installer le NuGet Polly sur le projet ApiResiliencesPolicies :

Créez une nouvelle classe RequestPolicies dans un répertoire Policies. Cette classe va contenir les stratégies de résilience du projet. Elle sera consommé par les controllers par injection de dépendances :
using Polly;
using Polly.Retry;
namespace ApiResilienceWithPolly.Policies
{
public class RequestPolicies
{
public RequestPolicies()
{
}
}
}
Il ne reste plus qu’à déclarer cette classe à notre moteur d’injection dans le fichier Program comme ci-dessous :
//DI polly
builder.Services.AddSingleton<RequestPolicies>(new RequestPolicies());
Création d’une stratégie de type RETRY
Dans le fichier RequestPolicies ajoutez la stratégie de type RETRY. Cette stratégie permet d’exécuter une ou plusieurs nouvelles tentatives. Le nombre de tentatives est paramétrable et l’appel peut être réexécuter après un certain délai d’attente :
using Polly;
using Polly.Retry;
namespace ApiResilienceWithPolly.Policies
{
public class RequestPolicies
{
public AsyncRetryPolicy<HttpResponseMessage> HttpRetryPolicy { get; }
public RequestPolicies()
{
int retryCount = 5;
HttpRetryPolicy = Policy.HandleResult<HttpResponseMessage>(result=> !result.IsSuccessStatusCode).RetryAsync(retryCount);
}
}
}
Cette stratégie est paramétrée pour relancer l’appel immédiatement et pour un maximum de 5 fois. Appliquez là à la méthode Get du controller RequestController comme ci-dessous :
public class RequestController : ControllerBase
{
private readonly RequestPolicies _requestPolicies;
public RequestController(RequestPolicies requestPolicies)
{
_requestPolicies = requestPolicies;
}
[HttpGet]
public async Task<ActionResult> CallApiExterne()
{
var client = new HttpClient();
//var response = await client.GetAsync("https://localhost:7286/WeatherForecast/50");
var response = await _requestPolicies.HttpRetryPolicy.ExecuteAsync(() =>
client.GetAsync("https://localhost:7286/WeatherForecast/50"));
return response.IsSuccessStatusCode ? Ok() : StatusCode(StatusCodes.Status500InternalServerError);
}
}
Exécutez les projets et utilisez le verbe CallApiExterne. Vous obtiendrez souvent une réponse Http200 :

Afin d’avoir un peu plus d’informations sur le nombre de tentatives, rajoutons juste un logger dans le projet ApiRessourcesExternes :
[Route("{count}")]
[HttpGet]
public ActionResult<WeatherForecast> Get(int count)
{
Random random = new Random();
var result = random.Next(0, 100);
if (result > count)
{
_logger.LogInformation("HTTP 200 : OK...");
return Ok(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray());
}
else
{
_logger.LogError("HTTP 500 : ERROR...");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
Si vous relancez l’application vous verrez la stratégie de nouvelles tentatives :




Une réflexion sur “Résilience avec Polly.Net (partie 1)”