- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为我的 Rest 客户创建一个综合弹性策略,为此我编写了以下内容:
private static Policy circuitBreakerPolicy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
我得到了错误
Cannot implicitly convert type
Polly.CircuitBreaker.AsyncCircuitBreaker
toPolly.Policy
我错过了什么?我在网上查了很多引用资料,但找不到对导致此问题的原因的足够简洁的解释。
用法:最终我想将上面的 CircuitBreaker 策略与 WaitandRetry
策略结合起来,但我不知道如何提取组合策略:
(这是有效的)
public static IAsyncPolicy<HttpResponseMessage> CreateResiliencePolicy()
{
var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromSeconds(180));
var waitAndRetryPolicy = Polly.Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)),
(result, timeSpan, context) =>
{
});
return timeoutPolicy.WrapAsync(waitAndRetryPolicy);
}
这就是我想要的(不工作):
public static IAsyncPolicy<HttpResponseMessage> CreateResiliencePolicy()
{
var circuitBreakerPolicy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
var waitAndRetryPolicy = Polly.Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)),
(result, timeSpan, context) =>
{
});
return circuitBreakerPolicy.WrapAsync(waitAndRetryPolicy);
//I want to do this instead
//public static Policy resilientAsyncStrategy =circuitBreakerPolicy.WrapAsync(waitAndRetryPolicy);
//Then return resilientAsyncStrategy
//return resilientAsyncStrategy;
}
然后将返回的策略实例用作:
public async Task<IEnumerable<PaymentDetailDto>> GetAsync()
{
var items = await resilientAsyncStrategy.ExecuteAsync(async () => await client.GetAsync());
return items;
}
最佳答案
Polly 定义了以下四种抽象的 Policy 类型:
Policy
Policy<TResult>
异步
AsyncPolicy
AsyncPolicy<TResult>
因此,在您的情况下是 circuitBreakerPolicy
应该这样定义:
private static AsyncPolicy circuitBreakerPolicy = Policy
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
每当你想组合/链接两个(或更多)策略时,你应该考虑使用 PolicyWrap
(reference)。请记住,政策链在 escalation way 中运作。这意味着如果内部策略无法处理问题,那么它会将其传播到下一个外部策略。
另请记住,政策应该相互兼容。因此,如果其中一个是异步的,那么另一个也应该是异步的。如果内部返回一些东西,那么外部应该做同样的事情。
所以,你的 CreateResiliencePolicy
可能看起来像这样:
public static AsyncPolicy<HttpResponseMessage> CreateResilienceStrategy()
{
var circuitBreakerPolicy = Policy<HttpResponseMessage>
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2));
var waitAndRetryPolicy = Polly.Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)),
(result, timeSpan, context) =>
{
});
return Policy.WrapAsync(circuitBreakerPolicy, waitAndRetryPolicy);
}
另请记住,顺序很重要:
Policy.WrapAsync(circuitBreakerPolicy, waitAndRetryPolicy)
你有一个内部重试和一个外部 CBPolicy.WrapAsync(waitAndRetryPolicy, circuitBreakerPolicy)
你有一个内部 CB 和一个外部重试下面两行是等价的:
circuitBreakerPolicy.WrapAsync(waitAndRetryPolicy);
Policy.WrapAsync(circuitBreakerPolicy, waitAndRetryPolicy)
如果您想更改政策的顺序,那么您的策略将以不同的方式运作。如果您想将 CB 用作内部策略并将重试用作外部策略,那么您应该修改 waitAndRetryPolicy
处理BrokenCircuitException
几个月前我整理了一个 sample application它演示了如何逐步设计弹性策略。
更新:添加示例代码
我使用了以下控制台应用程序来测试您的重试策略:
private static HttpClient client = new HttpClient();
public static async Task Main(string[] args)
{
var strategy = CreateResilienceStrategy();
await strategy.ExecuteAsync(async (ct) =>
await client.GetAsync("https://httpstat.us/500", ct)
, CancellationToken.None);
Console.WriteLine("Finished");
}
public static AsyncPolicy<HttpResponseMessage> CreateResilienceStrategy()
{
var circuitBreakerPolicy = Policy<HttpResponseMessage>
.Handle<TimeoutException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2),
onBreak: (_, __) => Console.WriteLine("Break"),
onReset: () => Console.WriteLine("Reset"),
onHalfOpen: () => Console.WriteLine("HalfOpen"));
var waitAndRetryPolicy = Polly.Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)),
onRetryAsync: (_, ts, ___) =>
{
Console.WriteLine($"Retry, penalty: {ts.Seconds} secs");
return Task.CompletedTask;
});
return Policy.WrapAsync(circuitBreakerPolicy, waitAndRetryPolicy);
}
输出:
Retry, penalty: 3 secs
Retry, penalty: 9 secs
Retry, penalty: 27 secs
Finished
如你所见,
strategy.ExecuteAsync
返回状态代码为 500 的响应因为 CB 策略设置为触发 TimeoutException
这就是我设置 client.Timeout
的原因在 Main
中为 1 毫秒.因此,应用程序崩溃并显示 TaskCanceledException
.
它这样做是因为 HttpClient 抛出 TaskCanceledException
如果超时而不是 TimeoutException
.如果您使用 polly 的超时策略,那么您将收到 TimeoutRejectedException
.
所以,这是我修改后的代码,以便能够测试 CB
private static HttpClient client = new HttpClient();
public static async Task Main(string[] args)
{
client.Timeout = TimeSpan.FromMilliseconds(1);
var strategy = CreateResilienceStrategy();
try
{
await strategy.ExecuteAsync(async (ct) =>
await client.GetAsync("https://httpstat.us/500", ct)
, CancellationToken.None);
Console.WriteLine("Finished");
}
catch (Exception ex)
{
Console.WriteLine("Failed with " + ex.GetType().Name);
}
}
public static AsyncPolicy<HttpResponseMessage> CreateResilienceStrategy()
{
var circuitBreakerPolicy = Policy<HttpResponseMessage>
.Handle<OperationCanceledException>()
.Or<TimeoutRejectedException>()
.CircuitBreakerAsync(1, TimeSpan.FromSeconds(2),
onBreak: (_, __) => Console.WriteLine("Break"),
onReset: () => Console.WriteLine("Reset"),
onHalfOpen: () => Console.WriteLine("HalfOpen"));
var waitAndRetryPolicy = Polly.Policy
.Handle<HttpRequestException>()
.Or<OperationCanceledException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(3, retryAttempt)),
onRetryAsync: (_, ts, ___) =>
{
Console.WriteLine($"Retry, penalty: {ts.Seconds} secs");
return Task.CompletedTask;
});
return Policy.WrapAsync(waitAndRetryPolicy, circuitBreakerPolicy);
}
修改:
OperationCanceledException
两种政策的条件输出
Break
Retry, penalty: 3 secs
HalfOpen
Break
Retry, penalty: 9 secs
HalfOpen
Break
Retry, penalty: 27 secs
HalfOpen
Break
Failed with OperationCanceledException
关于c# - 无法将类型 'Polly.CircuitBreaker.AsyncCircuitBreaker' 隐式转换为 'Polly.Policy',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68333247/
我有一个带有 Jubilee 的 Spring Boot 2.6.0-M1 项目(但问题可以从 2.4 开始重现)。在我的项目中,我使用了 Actuator、Spring cloud Kubernet
我遇到了@CircuitBreaker 没有重试的问题。 我有一个服务类(例如 UserService 类和方法名称 getUser),此方法调用另一个 Spring bean(例如 AppClien
是否可以监控所有Circuit Breakers限制和大小? Fielddata Breaker可以通过节点使用它来监控: GET _nodes/stats/breaker,http 但是我们如何监控
我有一个 spring boot 应用程序,它迭代地调用 mockserver通过 hystrix 命令实例化,带有回退方法。 模拟服务器被配置为始终以状态代码 500 响应。当在没有 circuit
我们正在使用响应式(Reactive)伪装客户端 (com.playtika.reactivefeign:feign-reactor-spring-cloud-starter:3.2.0) 断路器版本
我尝试将重试策略与带有 Failsafe 的 CircuitBreaker 模式结合起来,但当尝试打开电路并中断时,我收到了 CircuitBreakerOpenException 异常。 https
CircuitBreaker CircuitBreaker主要分为以下几个模块:熔断器配置,熔断器注册,熔断事件消费者注册,熔断器状态机,熔断器状态及指标,熔断器事件,熔断器事件处理器,熔断器
我在 Gradle 中使用 Spring Boot 2.4。 这是我定义依赖项的方式: compile 'org.springframework.cloud:spring-cloud-starter-
我正在尝试为我的 Rest 客户创建一个综合弹性策略,为此我编写了以下内容: private static Policy circuitBreakerPolicy = Policy .Han
我正在尝试使用 Resilience4j 的 Spring Boot 注释。 当我使用注释时@CircuitBreaker(name = BACKEND,fallbackMethod = "fallb
尽管对于其他返回类型,Spring 重试回退机制似乎工作正常,但是当涉及到调用返回类型为 void 的 API 时。恢复方法根本没有被调用,我已经尝试了所有可能的方法参数类型并更改了后备方法的返回类型
Spring 的@Retryable 注释将重试三次(默认)并回退到@Recovery 方法。然而,@CircuitBreaker 将重试一次并在状态关闭时回退。 我想结合这两者:当断路器状态为关闭时
现在我在 hystrix 中使用 feign,结果发现,当 fallback 方法在 5 秒内调用 20 次时,Circuit 将变为 Open 状态。我怎样才能改变这个规则。例如,当fallback
我有一个通过 REST 调用依赖项的服务。服务和依赖是微服务架构的一部分,所以我想使用弹性模式。我的目标是: 有一个断路器来保护它挣扎时的依赖 限制调用可以运行的时间。该服务具有 SLA,并且必须在特
我正在使用 spring boot 1.3.1 和 spring cloudl Brixtom.M4,在使用 springboot 1.3.1 时我发现 Turbine-AMQP 项目不再可用,我们现
我是一名优秀的程序员,十分优秀!