Polly
Polly是一个.NET平台上的开源库,用于处理多种不同类型的故障。它提供了一个易于使用且灵活的API,使得开发人员能够轻松地处理和恢复各种不同类型的故障,例如超时、断路器、重试等。在本文中,我们将介绍Polly的基本概念,然后通过实际示例来展示它的使用方法。
# 基本概念
在深入了解Polly之前,我们需要了解几个基本概念。
# 策略
策略是一组规则,用于定义应用程序如何处理故障。在Polly中,有多种类型的策略可供使用,例如重试策略、熔断策略、回退策略等。每种策略都有自己的规则和行为,开发人员可以根据应用程序的需要选择合适的策略。
# 策略执行器
策略执行器是一个对象,用于执行策略。在Polly中,有多种类型的策略执行器可供使用,例如同步执行器、异步执行器等。开发人员可以选择适合自己应用程序的执行器。
# 策略包装器
策略包装器是一个对象,用于将策略与执行器组合起来。在Polly中,有多种类型的策略包装器可供使用,例如 PolicyWrap、FallbackPolicy 等。开发人员可以根据自己应用程序的需要选择合适的策略包装器。
# 安装Polly
在开始使用Polly之前,我们需要先安装它。可以通过NuGet包管理器来安装Polly。
Install-Package Polly
# 重试策略
重试策略是一种策略,用于在失败时尝试重新执行操作。在Polly中,我们可以使用 RetryPolicy 来实现重试策略。RetryPolicy 提供了许多配置选项,例如重试次数、重试间隔等。下面是一个简单的示例,演示如何使用 RetryPolicy。
// 创建重试策略
var retryPolicy = Policy
.Handle<Exception>()
.WaitAndRetry(
retryCount: 3,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
// 使用重试策略
retryPolicy.Execute(() =>
{
// 调用可能会失败的方法
DoSomethingThatMightFail();
});
在这个示例中,我们首先创建了一个重试策略,它会在遇到任何异常时进行重试,最多重试3次。重试间隔使用指数退避算法进行计算。然后我们使用 Execute 方法来执行要重试的操作。如果操作失败,重试策略会自动尝试重新执行操作。
# 按次数重试
# 设置重试次数
//Retry(3) 重试3次
var _Policy = Policy.Handle<Exception>() // 定义条件
.Retry( 3 , ( exception , retryCount ) =>
{
if ( retryCount >= 0 )
{
// 可以写日志
Trace.WriteLine( "次数:" + retryCount.ToString() + " 时间:" + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) );
lbtxt.Text = retryCount.ToString() + "次重试";
}
} );
_Policy.Execute( () =>
{
this.run();
} );
# 无限重试,直到成功
// 不断重试,直到成功 RetryForever
var _Policy = Policy.Handle<Exception>() // 定义条件
.RetryForever( ( exception , retryCount ) =>
{
if ( retryCount >= 0 )
{
Trace.WriteLine( "次数:" + retryCount.ToString() + " 时间:" + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) );
lbtxt.Text = retryCount.ToString() + "次重试";
}
} );
_Policy.Execute( () =>
{
this.run();
} );
# 等待重试
# 等待重试,每次间隔时间
//失败后第一次重试等待1秒,第2次等待2秒,第3次等待5秒,第4次等待1秒,
//重试4次,分别等待1、2、5,1秒。
var _Policy = Policy.Handle<Exception>() // 定义条件
.WaitAndRetry( new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(1)
} , ( exception , timeSpan , retryCount , context ) =>
{
if ( retryCount >= 0 )
{
Trace.WriteLine( "次数:" + retryCount.ToString() + " 时间:" + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) );
lbtxt.Text = retryCount.ToString() + "次重试";
}
} );
另一种模式
// 重试5次,每次间隔2秒
var _Policy = Policy.Handle<Exception>() // 定义条件
.WaitAndRetry( 5 ,
retryAttempt => TimeSpan.FromSeconds( 2 ) ,
( exception , timeSpan , retryCount , context ) =>
{
if ( retryCount >= 0 )
{
Trace.WriteLine( "次数:" + retryCount.ToString() + " 时间:" + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) );
lbtxt.Text = retryCount.ToString() + "次重试";
}
} );
# 等待重试,每次间隔时间,直到成功
var _Policy = Policy.Handle<Exception>() // 定义条件
.WaitAndRetryForever(
retryAttempt => TimeSpan.FromSeconds( 2 ) ,
( exception , retryCount , timeSpan ) =>
{
if ( retryCount >= 0 )
{
Trace.WriteLine( "次数:" + retryCount.ToString() + " 时间:" + DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss" ) );
lbtxt.Text = retryCount.ToString() + "次重试";
}
} );
# 熔断策略
熔断策略是一种策略,用于在一段时间内停止执行操作,以避免系统的过度负载。在Polly中,我们可以使用 CircuitBreakerPolicy 来实现熔断策略。CircuitBreakerPolicy 可以通过监控失败率来自动打开和关闭熔断器。下面是一个简单的示例,演示如何使用 CircuitBreakerPolicy。
// 创建熔断策略
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreaker(
exceptionsAllowedBeforeBreaking: 3,
durationOfBreak: TimeSpan.FromSeconds(30));
// 使用熔断策略
circuitBreakerPolicy.Execute(() =>
{
// 调用可能会失败的方法
DoSomethingThatMightFail();
});
在这个示例中,我们首先创建了一个熔断策略,它会在遇到任何异常时触发熔断器,最多允许3个异常发生,熔断时间为30秒。然后我们使用 Execute 方法来执行要熔断的操作。如果操作失败超过3次,熔断器会自动打开,此后30秒内,所有对此操作的调用都会立即失败,而不是尝试执行操作。30秒后,熔断器会自动关闭,操作可以再次尝试执行。
# 回退策略
回退策略是一种策略,用于在操作失败时返回一个默认值,而不是抛出异常。在Polly中,我们可以使用 fallback 策略来实现回退策略。FallbackPolicy 可以在操作失败时执行回退操作,并返回指定的默认值。下面是一个简单的示例,演示如何使用 FallbackPolicy。
// 创建回退策略
var fallbackPolicy = Policy
.Handle<Exception>()
.Fallback(() => "default value");
// 使用回退策略
var result = fallbackPolicy.Execute(() =>
{
// 调用可能会失败的方法
return DoSomethingThatMightFail();
});
// 输出结果
Console.WriteLine(result);
在这个示例中,我们首先创建了一个回退策略,它会在遇到任何异常时执行回退操作,返回默认值 "default value"。然后我们使用 Execute 方法来执行要执行的操作。如果操作失败,回退策略会自动执行回退操作,并返回默认值。
# 策略包装器
策略包装器是一种将多个策略组合在一起的机制。在Polly中,我们可以使用 PolicyWrap 来实现策略包装器。PolicyWrap 可以将多个策略组合在一起,并按照特定的顺序执行它们。下面是一个简单的示例,演示如何使用 PolicyWrap。
// 创建重试策略
var retryPolicy = Policy
.Handle<Exception>()
.Retry(3);
// 创建熔断策略
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreaker(
exceptionsAllowedBeforeBreaking: 3,
durationOfBreak: TimeSpan.FromSeconds(30));
// 创建回退策略
var fallbackPolicy = Policy
.Handle<Exception>()
.Fallback(() => "default value");
// 创建策略包装器
var policyWrap = Policy.Wrap(fallbackPolicy, circuitBreakerPolicy, retryPolicy);
// 使用策略包装器
var result = policyWrap.Execute(() =>
{
// 调用可能会失败的方法
return DoSomethingThatMightFail();
});
// 输出结果
Console.WriteLine(result);
在这个示例中,我们首先创建了一个重试策略、一个熔断策略和一个回退策略。然后我们使用 Policy.Wrap 方法将它们组合成一个策略包装器。最后,我们使用 Execute 方法来执行要执行的操作。如果操作失败,策略包装器会按照指定的顺序执行它们,并执行相应的操作。
# 异步操作
在异步编程中,我们需要使用异步执行器来执行异步操作。在Polly中,我们可以使用 AsyncPolicy 和 AsyncPolicyWrap 来实现异步操作。下面是一个简单的示例,演示如何使用 AsyncPolicy 和 AsyncPolicyWrap。
// 创建异步重试策略
var retryPolicy = Policy
.Handle<Exception>()
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
// 创建异步熔断策略
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 3,
durationOfBreak: TimeSpan.FromSeconds(30));
// 创建异步回退策略
var fallbackPolicy = Policy
.Handle<Exception>()
.FallbackAsync(() => Task.FromResult("default value"));
// 创建异步策略包装器
var policyWrap = Policy.WrapAsync(fallbackPolicy, circuitBreakerPolicy, retryPolicy);
// 使用异步策略包装器
var result = await policyWrap.ExecuteAsync(async () =>
{
// 调用可能会失败的异步方法
return await DoSomethingThatMightFailAsync();
});
// 输出结果
Console.WriteLine(result);
在这个示例中,我们首先创建了一个异步重试策略、一个异步熔断策略和一个异步回退策略。然后我们使用 Policy.WrapAsync 方法将它们组合成一个异步策略包装器。最后,我们使用 ExecuteAsync 方法来执行要执行的异步操作。如果操作失败,策略包装器会按照指定的顺序执行它们,并执行相应的操作。
# 总结
Polly是一个.NET平台上的开源库,用于处理多种不同类型的故障。它提供了一组易于使用且灵活的API,使得开发人员能够轻松地处理和恢复各种不同类型的故障,例如超时、断路器、重试等。本文介绍了Polly的基本概念,包括策略、策略执行器、策略包装器等。我们通过实际示例演示了如何使用Polly实现重试策略、熔断策略、回退策略和策略包装器,并展示了如何在异步操作中使用Polly。
Polly提供了多种不同类型的策略,每种策略都有自己的规则和行为。开发人员可以根据应用程序的需要选择合适的策略。在使用Polly时,我们需要考虑一些重要的因素,例如重试次数、重试间隔、熔断时间、异常类型等。这些因素可以直接影响应用程序的性能和可靠性。
总之,Polly是一个非常有用的库,可以帮助开发人员轻松地处理和恢复各种不同类型的故障。它提供了易于使用且灵活的API,使得开发人员可以根据应用程序的需要选择合适的策略。使用Polly可以大大提高应用程序的可靠性和性能。