我在设置波利的断路器时遇到问题
HttpClient
.
明确地,
CircuitBreaker
和
HTTP客户端
用于以下链接的ASP.NET Core Web API控制器:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests
https://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory
下面是我想要的
-
重试策略:如果存在暂时性错误,则对每个请求重试3次。
-
电路断路器策略:如果所有请求中发生五个瞬时错误,则生效。
问题
尽管重试策略工作正常,但断路器策略不工作。
在发生来自HttpClient.SendAsync()的5个异常之后,Carcontroller仍然接收请求,并且在30秒内没有暂停(请求由控制器立即处理)。
破裂前处理事件:5
断裂秒持续时间:30
我是不是丢了什么东西?
配置服务
配置polly重试和断路器策略,以及单独的自定义httpclient,
HttpClientService
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient();
services.AddHttpClient<IHttpClientService, HttpClientService>()
.AddPolicyHandler((service, request) =>
HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(3,
retryCount => TimeSpan.FromSeconds(Math.Pow(2, retryCount)),
onRetry: (outcome, timespan, retryCount, context) =>
{
service.GetService<ILog>().Error("Delaying for {delay}ms, then making retry {retry}.",
timespan.TotalMilliseconds, retryCount);
}
)
)
)
.AddPolicyHandler((service, request) =>
HttpPolicyExtensions.HandleTransientHttpError()
//Further external requests are blocked for 30 seconds if five failed attempts occur sequentially.
//Circuit breaker policies are stateful.All calls through this client share the same circuit state.
.CircuitBreakerAsync(5,
TimeSpan.FromSeconds(30),
(result, timeSpan, context)=>
service.GetService<ILog>().Error("CircuitBreaker onBreak for {delay}ms", timeSpan.TotalMilliseconds),
context =>
service.GetService<ILog>().Error("CircuitBreaker onReset")));
}
汽车控制器
IHttpClientService
在中的polly策略中指定
ConfigureServices
.
HttpClientService服务
使用
HTTP客户端
.
断路器不工作:即使发生五个瞬态错误(例如
HttpRequestException
从
_httpClient.SendAsync()
,carcontroller仍然可以接收请求,并且不会暂停30秒。
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/[controller]")]
[ApiController]
public class CarController : ControllerBase
{
private readonly ILog _logger;
private readonly IHttpClientService _httpClientService;
private readonly IOptions<Config> _config;
public CarController(ILog logger, IHttpClientService httpClientService, IOptions<Config> config)
{
_logger = logger;
_httpClientService = httpClientService;
_config = config;
}
[HttpPost]
public async Task<ActionResult> Post()
{
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
string body = reader.ReadToEnd();
var statusCode = await _httpClientService.PostAsync(
"url",
new Dictionary<string, string>
{
{"headerID", "Id"}
},
body);
return StatusCode((int)statusCode);
}
}
}
HttpClientService服务
似乎httpclient在请求之间不是有状态的。
断路器不工作:即使发生五个瞬态错误(例如
httprequestexception
从
_ HttpClient.SendAsync()
,carcontroller仍然可以接收请求,并且不会暂停30秒。
public class HttpClientService
{
private readonly HttpClient _httpClient;
public HttpClientService(HttpClient client)
{
_httpClient = client;
}
public async Task<HttpStatusCode> PostAsync(string url, Dictionary<string, string> headers, string body)
{
using (var content = new StringContent(body, Encoding.UTF8, "application/json"))
{
foreach (var keyValue in headers)
{
content.Headers.Add(keyValue.Key, keyValue.Value);
}
var request = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = content
};
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
return response.StatusCode;
}
}
ASP.NET核心API 2.2
更新
已更新setwaitandretrypolicy扩展方法以使用iserviceprovider。