如何配置 Yarp.ReverseProxy HttpClient 以使用断路器模式

问题描述 投票:0回答:1

我们正在使用 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
        );
    }
}

有什么办法可以实现吗?

c# .net-core microservices reverse-proxy ms-yarp
1个回答
0
投票

您可以通过使用 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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.