Polly断路器-动态断开持续时间



修改Polly的Duration Break的正确方法是什么?我知道他们在文档中提到了实现(PolicyRegistry)。有这样的例子吗?我在一个WinService中实现了Polly CircuitBreaker。

Circuit Breaker不是设计为每次断开时使用不同的睡眠时间。

在重试的情况下,您可以提供一个名为sleepDurationProvider的函数,该函数由策略调用,以确定在发出下一次尝试之前的实际睡眠持续时间。

所以,简而言之,在设计上它是不支持的。我将向您展示一个变通方法,但是我使用而不是推荐使用。我将在示例代码之后提供一个推理。

为了简单起见,我们使用以下方法:

static int Probe()
{
Console.WriteLine("Probe has been called");
throw new NotSupportedException();
}
  • 它打印出方法被调用的事实,然后立即失败。
  • IMHO:不是一个真正有用的功能:D

让我们定义一个助手方法来增加时间段(>>(睡眠时长)每次调用

static IEnumerable<TimeSpan> GetSleepDuration()
{
for (int i = 1; i < 10; i++)
{
yield return TimeSpan.FromSeconds(i);
}
}
  • 这或多或少地取代了重试的sleepDurationProvider

现在是时候定义我们的断路器策略了:

var sleepDurationProvider = GetSleepDuration().GetEnumerator();
sleepDurationProvider.MoveNext();
var cb = Policy<int>
.Handle<NotSupportedException>()
.CircuitBreaker(1, TimeSpan.FromSeconds(0),
onBreak: (_, __) => {
Console.WriteLine(sleepDurationProvider.Current.TotalSeconds);
Thread.Sleep((int)sleepDurationProvider.Current.TotalMilliseconds);
sleepDurationProvider.MoveNext();
},
onReset: () => { },
onHalfOpen: () => Console.WriteLine("CB half opens"));
  • 我们得到了GetSleepDuration
  • 的迭代器
  • 我们将连续失败计数设置为1,因此在每次Probe调用之后,CB将中断
  • 我们将durationOfBreak设置为0,因为我们将在onBreak<<解决方案
  • 我们打印出睡眠时间然后我们睡觉最后我们增加下一次休息的睡眠时间

为了简化我们的测试,让我们定义一个重试策略:

var retry = Policy<int>
.Handle<NotSupportedException>()
.WaitAndRetryForever(_ => TimeSpan.FromSeconds(0),
onRetry: (_, __) => Console.WriteLine("Retry is triggered"));
  • 处理Probe的异常
  • 永远重试,每次重试调用之间等待0秒

让我们连接策略并运行测试:

Policy.Wrap(retry, cb).Execute(() => Probe());

输出将是:

Probe has been called
1
Retry is triggered
CB half opens
Probe has been called
2
Retry is triggered
CB half opens
Probe has been called
3
Retry is triggered
CB half opens
Probe has been called
4
Retry is triggered
CB half opens
Probe has been called
5
Retry is triggered
CB half opens
Probe has been called
6
Retry is triggered
CB half opens
Probe has been called
7
Retry is triggered
CB half opens
Probe has been called
8
Retry is triggered
CB half opens
Probe has been called
9
Retry is triggered
CB half opens
Probe has been called
9
...
  1. Probe被调用失败
  2. CB从Open过渡到Broken
  3. onBreak被调用,阻塞执行1秒
  4. PolicyWrap将问题升级为Retry
  5. 重试等待0秒并发出新的尝试
  6. CB从BrokenHal-Open过渡
  7. Probe已经被调用并且失败

这个解决方案最大的问题是它阻塞。不幸的是,没有异步版本的onBreak。(重试确实有onRetryAsync,其中您可以使用Task.Delay而不是Thread.Sleep)

第二个问题是它依赖于当前的实现。例如,如果onBreak在另一个线程上执行并且立即抛出异常,则此解决方案将不起作用。

最新更新