闽公网安备 35020302035485号
重试间隔时间:定义每次重试之间的时间间隔。



builder.Services.AddSwaggerGen(); builder.Services.AddControllers(); var app = builder.Build(); app.MapControllers();然后创建一个 ResponseController.cs 文件,添加如下操作方法:
[Route("api/[Controller]")]
[ApiController]
public class ResponseController : ControllerBase
{
[HttpGet]
[Route("{id:int}")]
public ActionResult GetAResponse(int id)
{
Random rnd = new Random();
var rndInteger = rnd.Next(1, 101);
if (rndInteger >= id)
{
Console.WriteLine("Failure - Generate an Internal Error");
return StatusCode(StatusCodes.Status500InternalServerError);
}
Console.WriteLine("Failure - Generated a Success");
return Ok("Success");
}
}
在上述代码中,我们使用 Random 函数实现了服务内的瞬态故障。当随机生成的整数小于输入的 ID 时,有可能返回内部服务器错误。运行代码并通过 Postman 测试。根据生成的随机整数,响应服务的状态码会随机返回 200 或 500。
namespace RequestService.Controllers
{
[ApiController]
[Route("api/[Controller]")]
public class RequestController: ControllerBase
{
public RequestController()
{
// 堆代码 duidaima.com
}
[HttpGet]
public async Task<ActionResult> MakeRequest()
{
var client = new HttpClient();
var response = await client.GetAsync("http://localhost:5202/api/response/25");
var response = await _clientPolicy.LinearHttpRetry.ExecuteAsync( () =>
client.GetAsync("http://localhost:5202/api/response/25")
);
if(response.IsSuccessStatusCode)
{
Console.WriteLine("--> Response Service Retuned Success");
return Ok();
}
Console.WriteLine("--> Response Service Retuned Failure");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
可以运行请求服务并在 Postman 中验证。此时我们会从响应服务中得到失败消息,因为还未实现重试机制。dotnet add package Microsoft.Extensions.Http.Polly创建一个名为 Policies 的文件夹,并添加 ClientPolicy 类文件,代码如下:
using Polly;
using Polly.Retry;
namespace RequestService.Policies
{
public class ClientPolicy
{
public AsyncRetryPolicy<HttpResponseMessage> ImmediateHttpRetry {get;}
public AsyncRetryPolicy<HttpResponseMessage> LinearHttpRetry {get;}
public AsyncRetryPolicy<HttpResponseMessage> ExponentialHttpRetry {get;}
public ClientPolicy()
{
ImmediateHttpRetry = Policy.HandleResult<HttpResponseMessage>
( res => !res.IsSuccessStatusCode).RetryAsync(5);
LinearHttpRetry = Policy.HandleResult<HttpResponseMessage>
( res => !res.IsSuccessStatusCode).
WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(3));
ExponentialHttpRetry = Policy.HandleResult<HttpResponseMessage>
( res => !res.IsSuccessStatusCode).
WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,retryAttempt)));
}
}
}
在上述代码中,我们在构造函数中初始化了不同的重试策略。以 LinearHttpRetry 为例,若返回结果不是 SuccessStatusCode,则 WaitAndRetryAsync 方法会重试 5 次,每次间隔 3 秒。接着,我们在 Program.cs 中通过依赖注入配置 ClientPolicy:builder.Services.AddSingleton<ClientPolicy> (new ClientPolicy());然后在 RequestController 中使用 ClientPolicy:
private readonly ClientPolicy _clientPolicy;
private readonly IHttpClientFactory _clientFactory;
public RequestController(ClientPolicy clientPolicy, IHttpClientFactory clientFactory)
{
_clientPolicy = clientPolicy;
_clientFactory = clientFactory;
}
[HttpGet]
public async Task<ActionResult> MakeRequestNormalHttpClient()
{
var client = new HttpClient();
var response = await _clientPolicy.LinearHttpRetry.ExecuteAsync(() =>
client.GetAsync("http://localhost:5202/api/response/25")
);
if(response.IsSuccessStatusCode)
{
Console.WriteLine("--> Response Service Retuned Success");
return Ok();
}
Console.WriteLine("--> Response Service Retuned Failure");
return StatusCode(StatusCodes.Status500InternalServerError);
}
为了更好地管理策略,可以在 Program.cs 中为命名的 HttpClient 添加策略:builder.Services.AddHttpClient("Test")
.AddPolicyHandler(request =>
request.Method == HttpMethod.Get ?
new ClientPolicy().LinearHttpRetry :
new ClientPolicy().LinearHttpRetry
);
在控制器中使用命名的 HttpClient:public async Task<ActionResult> MakeRequest()
{
var client = _clientFactory.CreateClient("Test");
var response = await client.GetAsync("http://localhost:5202/api/response/25");
if (response.IsSuccessStatusCode)
{
Console.WriteLine("--> Response Service Returned Success");
return Ok();
}
Console.WriteLine("--> Response Service Returned Failure");
return StatusCode(StatusCodes.Status500InternalServerError);
}
由于我们在 Program.cs 中为命名的 Http 客户端配置了策略,因此可以直接使用 IHttpClientFactory 来创建客户端,并且策略已经启用。让我们运行代码并在 Postman 中测试 LinearHttpRetry 策略。在 Postman 中,我们成功地测试了线性等待策略。
