欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net彈性和瞬態(tài)故障處理庫Polly介紹

 更新時(shí)間:2022年06月29日 15:20:48   作者:天方  
這篇文章介紹了.Net彈性和瞬態(tài)故障處理庫Polly,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

Polly 是 .Net 下的一套瞬時(shí)故障處理及恢復(fù)的函式庫,可讓開發(fā)者以fluent及線程安全的方式來應(yīng)用諸如Retry、Circuit Breaker、TimeoutBulkhead IsolationFallback等策略。

安裝

可以通過Nuget實(shí)現(xiàn)快速安裝:Install-Package Polly

基本用法

一個(gè)簡單的示例如下:

var policy = Policy
    .Handle<DivideByZeroException>()    //定義所處理的故障
    .Retry();    //故障的處理方法

policy.Execute(() => DoSomething());    //應(yīng)用策略

從上面的例子中我們可以看出,使用該策略一般包括三個(gè)步驟:

  • 定義所處理的故障
  • 定義故障的處理方法
  • 應(yīng)用策略

上述代碼在功能上和下面的代碼等價(jià):

for (int i = 0; i < 2; i++)
{
    try
    {
        DoSomething();
    }
    catch (DivideByZeroException)
    {
        if (i > 1)
            throw;
    }
}

雖然這個(gè)例子比較簡單,帶來的優(yōu)越性并不明顯,但它以一種比較規(guī)范的方式定義了異常的處理策略,一來帶來了更好的體驗(yàn),帶來了更好的代碼可讀性,另外,隨著異常策略的復(fù)雜,它所帶來的對代碼的簡化就更加明顯了。下面就稍微詳細(xì)一點(diǎn)的深入介紹一下:

定義錯(cuò)誤(故障)

常見故障定義方式是指定委托執(zhí)行過程中出現(xiàn)的特定異常,Polly中支持異常處理方式如下:

// 處理指定異常
Policy.Handle<DivideByZeroException>();

// 處理有條件的指定異常
Policy.Handle<SqlException>(ex => ex.Number == 1205);

// 處理多種異常
Policy.Handle<DivideByZeroException>()
    .Or<ArgumentException>();

// 處理多種有條件的異常
Policy.Handle<SqlException>(ex => ex.Number == 1205)
    .Or<ArgumentException>(ex => ex.ParamName == "example");

也支持異常的聚合:

Policy.Handle<ArgumentException>()
    .Or<ArgumentException>();

另外,也支持通過返回值判斷是否故障:

// 指定錯(cuò)誤的返回值
Policy.HandleResult<int>(ret => ret <= 0);

故障處理策略:重試 

常見的處理策略是重試,Polly庫中內(nèi)置了各種常用的重試策略:

// 重試1次
Policy.Handle<TimeoutException>().Retry();

// 重試多次
Policy.Handle<TimeoutException>().Retry(3);

// 無限重試
Policy.Handle<TimeoutException>().RetryForever();

也支持retry時(shí)增加一些額外的行為:

Policy.Handle<TimeoutException>().Retry(3, (err, countdown, context) =>
{
    // log retry
});

也支持等待并重試:

// 等待并重試
Policy.Handle<TimeoutException>().WaitAndRetry(3, _ => TimeSpan.FromSeconds(3));

故障處理策略:回退(Fallback)

Fallback策略是在遇到故障是指定一個(gè)默認(rèn)的返回值,

Policy<int>.Handle<TimeoutException>().Fallback(3);
Policy<int>.Handle<TimeoutException>().Fallback(() => 3);

當(dāng)然,遇到?jīng)]有返回值的也可以指定故障時(shí)的處理方法,

Policy.Handle<TimeoutException>().Fallback(()?=>?{?});

使用Fallback時(shí),異常被捕獲,返回默認(rèn)的返回結(jié)果。

PS: 帶參數(shù)的Fallback處理方式貌似在5.0之后發(fā)生了變化,成了本文所示的方式,以前是Fallback<T>

故障處理策略:斷路保護(hù)(Circuit Breaker)

Circuit Breaker也是一種比較常見的處理策略,它可以指定一定時(shí)間內(nèi)最大的故障發(fā)生次數(shù),當(dāng)超過了該故障次數(shù)時(shí),在該時(shí)間段內(nèi),不再執(zhí)行Policy內(nèi)的委托。下面以一個(gè)簡單的示例演示下該策略的功能:

static void testPolicy()
{
    var circuitBreaker = Policy.Handle<TimeoutException>()
            .CircuitBreaker(3, TimeSpan.FromMinutes(1));
    for (int i = 0; i < 5; i++)
    {
        try
        {
            circuitBreaker.Execute(DoSomething);
        }
    
        catch (Polly.CircuitBreaker.BrokenCircuitException e)
        {
            Console.WriteLine(e.Message);
        }
        catch (TimeoutException)
        {
            Console.WriteLine("timeout");
        }
    }
}

static int index = 0;
static int DoSomething()
{
    Console.WriteLine($"DoSomething {index++}");
    throw new TimeoutException();
}

執(zhí)行結(jié)果如下:

DoSomething 0
timeout
DoSomething 1
timeout
DoSomething 2
timeout
The circuit is now open and is not allowing calls.
The circuit is now open and is not allowing calls.

可以看到,前面3次都能執(zhí)行委托DoSomething,但出錯(cuò)次數(shù)到達(dá)3次后,已經(jīng)進(jìn)入斷路保護(hù)章臺(tái),后面兩次調(diào)用直接返回BrokenCircuitException。直到達(dá)到保護(hù)時(shí)間超時(shí)后,對策略的調(diào)用才會(huì)再次執(zhí)行DoSomething委托。

這種策略在調(diào)用遠(yuǎn)程服務(wù)時(shí)非常實(shí)用,當(dāng)一定時(shí)間內(nèi)的調(diào)用都出錯(cuò)時(shí),往往可以認(rèn)為服務(wù)提供者已經(jīng)不可用,后續(xù)調(diào)用完全可以直接失敗,以避免重試的開銷。直到一定時(shí)間后才需要再次重試。

相對其它處理策略,CircuitBreaker是一個(gè)比較復(fù)雜的策略,它是有狀態(tài)的,可以通過CircuitState屬性獲?。?/p>

var state = circuitBreaker.CircuitState;

它有四種狀態(tài):

  • CircuitState.Closed - 常態(tài),可執(zhí)行actions。
  • CircuitState.Open - 自動(dòng)控制器已斷開電路,不允許執(zhí)行actions。
  • CircuitState.HalfOpen - 在自動(dòng)斷路時(shí)間到時(shí),從斷開的狀態(tài)復(fù)原。可執(zhí)行actions,后續(xù)的action/s或控制的完成,會(huì)讓狀態(tài)轉(zhuǎn)至Open或Closed。
  • CircuitState.Isolated - 在電路開路的狀態(tài)時(shí)手動(dòng)hold住,不允許執(zhí)行actions。

除了超時(shí)和策略執(zhí)行失敗的這種自動(dòng)方式外,也可以手動(dòng)控制它的狀態(tài):

// 手動(dòng)打開(且保持)一個(gè)斷路器–例如手動(dòng)隔離downstream的服務(wù)
circuitBreaker.Isolate();

// 重置一個(gè)斷路器回closed的狀態(tài),可再次接受actions的執(zhí)行
circuitBreaker.Reset();

更多的介紹可以參看官方文檔:Circuit Breaker

故障封裝策略(PolicyWrap)

我們可以通過PolicyWrap的方式,封裝出一個(gè)更加強(qiáng)大的策略:

var fallback = Policy<int>.Handle<TimeoutException>().Fallback(100);
var retry = Policy<int>.Handle<TimeoutException>().Retry(2);

var retryAndFallback = fallback.Wrap(retry);

這個(gè)策略就是將Retry和Fallback組合起來,形成一個(gè)retry and fallback的策略,也可以寫成如下形式:

Policy.Wrap(fallback,?retry);

當(dāng)執(zhí)行這個(gè)新策略時(shí):

retryAndFallback.Execute(DoSomething);

等價(jià)于執(zhí)行:

fallback.Execute(()=>?retry.Execute(DoSomething));

封裝策略本身是屬于彈性策略的范疇,這里只是提及一下,以演示Polly模塊強(qiáng)大的功能,關(guān)于彈性策略更多內(nèi)容在下文中再做更詳細(xì)的介紹。

到此這篇關(guān)于.Net彈性和瞬態(tài)故障處理庫Polly的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論