如何在不执行请求的情况下获得波利断路器的状态

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

我知道我们可以在上下文中使用电路状态来获取当前状态。但是有一种方法可以让我在上下文之外获得电路状态。对于下面的示例,如果要在控制器上获取电路状态,该怎么做?现在,我在策略中设置了一个静态变量,但是当电路断开时,无法获取其上下文。这是我当前的设置。

启动

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    services.AddHttpClient<IIntCall, IntCall>().WrapResilientPolicies();
}

接口

public interface IIntCall
    {
        Task<bool> DoSomething();
    }

实施:

public class IntCall : IIntCall
    {
private readonly HttpClient client;

public IntCall(HttpClient httpClient)
{
    this.client = httpClient;
}

public async Task<bool> DoSomething()
{
    var response = await client.GetAsync("http://www.onegoogle.com");
    var content = await response.Content.ReadAsStringAsync();
    return false;
}
}

Polly实现

public static class CBExtensions
    {
    public static void WrapResilientPolicies(this IHttpClientBuilder builder)
    {
        builder.AddPolicyHandler((service, request) =>
        GetRetryPolicy().WrapAsync(GetCircuitBreakerPolicy()));
    }

private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions.HandleTransientHttpError()
        .CircuitBreakerAsync(3, TimeSpan.FromSeconds(30), (result, retryAttempt) =>
        {
            Debug.WriteLine("circuit broken");
        },
        () =>
        {
            Debug.WriteLine("circuit closed");
        });
}

private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    return HttpPolicyExtensions.HandleTransientHttpError()
        .Or<Exception>(e => !(e is BrokenCircuitException))
      .WaitAndRetryAsync(3,
          retryAttempt => TimeSpan.FromMilliseconds(500),
          onRetry: (context, attempt) =>
          {
              Debug.WriteLine("error");
          }
      );
}

}

.net-core dotnet-httpclient polly circuit-breaker
1个回答
0
投票

CircuitState属性在策略实例实现的ICircuitBreaker接口上可用:(更多在Polly readmewiki中)

CircuitState state = breaker.CircuitState;

/*
CircuitState.Closed
CircuitState.Open
CircuitState.HalfOpen
CircuitState.Isolated
*/

其中breaker是策略实例,即最初由GetCircuitBreakerPolicy()方法返回的策略。


您可以通过DI将断路器策略传递给控制器​​。在启动过程中,您可以执行以下操作:

var breaker = GetCircuitBreakerPolicy();
services.AddSingleton<ICircuitBreakerPolicy<HttpResponseMessage>>(breaker as ICircuitBreakerPolicy<HttpResponseMessage>);

当然,您需要在对same single instance of breaker的调用中使用该breaker,而不制造新的/不同的C0。

.AddPolicyHandler(...)

然后,控制器可以通过构造函数注入接收断路器实例的副本:

builder.AddPolicyHandler(GetRetryPolicy().WrapAsync(breaker));

如果在应用程序中仅使用单个断路器实例,则通过在DI容器上注册public class MyController { public MyController(ICircuitBreakerPolicy<HttpResponseMessage> breaker, /* etc */) { } } 将断路器传递到控制器(如上所示)效果很好。

[如果您有多个断路器策略实例,这些实例需要在应用程序的其他位置(例如,由控制器直接访问),请将其存储在ICircuitBreakerPolicy<HttpResponseMessage>中,然后通过DI将PolicyRegistry传递给控制器​​。有PolicyRegistry用于使用IReadOnlyPolicyRegistry<string>中的策略配置.AddPolicyHandlerFromRegistry() overloads

© www.soinside.com 2019 - 2024. All rights reserved.