我们正在使用 YARP 反向代理来访问多个服务。但并不是要求我们需要在该代理服务中实现断路器和重试策略,但我没有在网上找到任何参考来实现这一点。
builder.Services.AddReverseProxy().LoadFromMemory().ConfigureHttpClient((context, handler) => {
});
在这里我可以看到配置客户端扩展方法可用,但不知道如何配置。想要使用 Httpclient 配置以下代码。
public class CircuitBreakerAndRetryDelegatingHandler : DelegatingHandler
{
private readonly IOptionsMonitor<AppSettings> _appSettings;
private readonly IDisposable? _onChangeDisposable;
private AsyncPolicyWrap _circuitBreakerAndRetryPolicy;
public CircuitBreakerAndRetryDelegatingHandler(IOptionsMonitor<AppSettings> appSettings)
{
_appSettings = appSettings;
_onChangeDisposable = _appSettings.OnChange(x=> UpdateCircuitBreakerConfig());
UpdateCircuitBreakerConfig();
}
private void UpdateCircuitBreakerConfig()
{
var circuitBreakerPolicy = Policy.Handle<HttpRequestException>()
.CircuitBreakerAsync(exceptionsAllowedBeforeBreaking: 3, durationOfBreak: TimeSpan.FromSeconds(30));
var retryPolicy = Policy.Handle<HttpRequestException>()
.WaitAndRetryAsync(retryCount: 3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
_circuitBreakerAndRetryPolicy = Policy.WrapAsync(circuitBreakerPolicy, retryPolicy);
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return await _circuitBreakerAndRetryPolicy.ExecuteAsync(
async (cancellationToken) => await base.SendAsync(request, cancellationToken),
cancellationToken
);
}
}
有什么办法可以实现吗?
您可以通过使用 DI 注册自定义
IForwarderHttpClientFactory
来添加您自己的委托处理程序。从默认值 ForwarderHttpClientFactory
派生是最简单的选项。
services.AddSingleton<IForwarderHttpClientFactory, MyClientFactory>();
internal sealed class MyClientFactory : ForwarderHttpClientFactory
{
protected override HttpMessageHandler WrapHandler(ForwarderHttpClientContext context, HttpMessageHandler handler)
{
handler = new MyHandler(handler);
return base.WrapHandler(context, handler);
}
}