HttpClientHttpRequester implements the Circuit Breaker Pattern

HttpClientHttpRequester implements the Circuit Breaker Pattern,I using
Polly from thepollyproject.org
This commit is contained in:
geffzhang 2017-02-02 23:35:02 +08:00
parent 3f71bd55d5
commit e80364a1f8
2 changed files with 40 additions and 3 deletions

View File

@ -4,22 +4,58 @@ using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ocelot.Errors; using Ocelot.Errors;
using Ocelot.Responses; using Ocelot.Responses;
using Polly;
using Polly.Timeout;
using Polly.CircuitBreaker;
using Ocelot.Logging;
namespace Ocelot.Requester namespace Ocelot.Requester
{ {
public class HttpClientHttpRequester : IHttpRequester public class HttpClientHttpRequester : IHttpRequester
{ {
private readonly IOcelotLogger _logger;
public HttpClientHttpRequester(IOcelotLoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<HttpClientHttpRequester>();
}
public async Task<Response<HttpResponseMessage>> GetResponse(Request.Request request) public async Task<Response<HttpResponseMessage>> GetResponse(Request.Request request)
{ {
double timeoutvalue = 5000;
TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic;
var timeoutPolicy = Policy
.TimeoutAsync(TimeSpan.FromMilliseconds(timeoutvalue), timeoutStrategy);
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.Or<TimeoutRejectedException>()
.Or<TimeoutException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 4,
durationOfBreak: TimeSpan.FromSeconds(8),
onBreak: (ex, breakDelay) =>
{
_logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
},
onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."),
onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.")
);
using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer }) using (var handler = new HttpClientHandler { CookieContainer = request.CookieContainer })
using (var httpClient = new HttpClient(handler)) using (var httpClient = new HttpClient(handler))
{ {
try try
{ {
var response = await httpClient.SendAsync(request.HttpRequestMessage); // Retry the following call according to the policy - 3 times.
HttpResponseMessage response = await Policy.WrapAsync(circuitBreakerPolicy, timeoutPolicy).ExecuteAsync<HttpResponseMessage>(() =>
{
return httpClient.SendAsync(request.HttpRequestMessage);
});
return new OkResponse<HttpResponseMessage>(response); return new OkResponse<HttpResponseMessage>(response);
} }
catch (Exception exception) catch (BrokenCircuitException exception)
{ {
return return
new ErrorResponse<HttpResponseMessage>(new List<Error> new ErrorResponse<HttpResponseMessage>(new List<Error>

View File

@ -27,7 +27,8 @@
"Microsoft.NETCore.App": "1.1.0", "Microsoft.NETCore.App": "1.1.0",
"CacheManager.Core": "0.9.2", "CacheManager.Core": "0.9.2",
"CacheManager.Microsoft.Extensions.Configuration": "0.9.2", "CacheManager.Microsoft.Extensions.Configuration": "0.9.2",
"CacheManager.Microsoft.Extensions.Logging": "0.9.2" "CacheManager.Microsoft.Extensions.Logging": "0.9.2",
"Polly": "5.0.3"
}, },
"runtimes": { "runtimes": {
"win10-x64": {}, "win10-x64": {},