日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

弹性和瞬态故障处理库Polly介绍

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 弹性和瞬态故障处理库Polly介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

本節我們來介紹一款強大的庫Polly,Polly是一種.NET彈性和瞬態故障處理庫,允許我們以非常順暢和線程安全的方式來執諸如行重試,斷路,超時,故障恢復等策略。 Polly針對對.NET 4.0,.NET 4.5和.NET Standard 1.1以及.NET Core實現,該項目作者現已成為.NET基金會一員,項目一直在不停迭代和更新,項目地址【https://github.com/App-vNext/Polly】,你值得擁有。接下來我們以.NET Framework ?4.5來演示它的強大功能。

Introduce Polly

我們在下載Polly包,最新版本為5.3.1,如下:

該庫實現了七種恢復策略,下面我一一為您來介紹。

重試策略(Retry)

重試策略針對的前置條件是短暫的故障延遲且在短暫的延遲之后能夠自我糾正。允許我們做的是能夠自動配置重試機制。

斷路器(Circuit-breaker)

斷路器策略針對的前置條件是當系統嚴重掙扎時,快速失敗比讓用戶/呼叫者等待更好。保護故障系統免受過載,可以幫助它恢復。

超時(Timeout)

超時策略針對的前置條件是超過一定的等待時間,想要得到成功的結果是不可能的,保證調用者不必等待超時。

隔板隔離(Bulkhead Isolation)

隔板隔離針對的前置條件是當進程出現故障時,備份的多個失敗的呼叫可以輕松地在主機中對資源(例如線程/ CPU)進行漫游。下游系統故障也可能導致上游“備份”失敗的呼叫。這兩個風險都是一個錯誤的過程,導致更廣泛的系統。

緩存(Cache)

緩存策略針對的前置條件是數據不會很頻繁的進行更新,為了避免系統過載,首次加載數據時將響應數據進行緩存,如果緩存中存在則直接從緩存中讀取。

反饋(Fallback)

操作仍然會失敗,也就是說當發生這樣的事情時我們打算做什么。也就是說定義失敗返回操作。

策略包裝(PolicyWrap)

策略包裝針對的前置條件是不同的故障需要不同的策略,也就意味著彈性靈活使用組合。

幾種策略使用

一旦從事IT就得警惕異常并友好擁抱異常而非不聞不問,這個時候我們利用try{}catch{}來處理。

try{ ? ? ? ? ? ? ? ?var a = 0; ? ? ? ? ? ? ? ?var b = 1 / a;} ? ? ? ? ? ?catch (DivideByZeroException ex){ ? ? ? ? ? ? ? ?throw ex;}


若我們想重試三次,此時我們只能進行循環三次操作。我們只能簡單進行處理,自從有了Polly,什么重試機制,超時都不在話下,下面我們來簡短介紹各種策略。Polly默認處理策略需要指定拋出的具體異常或者執行拋出異常返回的結果。處理單個類型異常如下:

Policy.Handle<DivideByZeroException>()

上述異常指嘗試除以0,下面我們演示下具體使用,我們嘗試除以0并用Polly指定該異常并重試三次。

static int Compute(){ ? ? ? ? ? ?var a = 0; ? ? ? ?
? ? ? ? ? ? ? ? ?? ?
return 1 / a;}


try{ ? ? ? ? ? ? ? ?var retryTwoTimesPolicy =Policy.Handle<DivideByZeroException>().Retry(3, (ex, count) =>{Console.WriteLine("執行失敗! 重試次數 {0}", count);Console.WriteLine("異常來自 {0}", ex.GetType().Name);});retryTwoTimesPolicy.Execute(() =>{Compute();});} ? ? ? ? ? ?catch (DivideByZeroException e){Console.WriteLine($"Excuted Failed,Message: ({e.Message})");}


如果我們想指定處理多個異常類型通過OR即可。

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

當然還有更加強大的功能,比如在微信支付時,微信回調我們的應用程序時,此時若失敗,想必微信那邊也會做重試機制,例如隔一段時間重試調用一次,重復調用幾次后仍失敗則不再回調。我們利用Polly則可以演示等待重試機制。

/// <summary>/// 拋出異常 ? ? ? ?/// </summary>static void ZeroExcepcion(){ ? ? ? ? ? ?throw new DivideByZeroException();}


/// <summary>/// 異常信息 ? ? ? ?/// </summary>/// <param name="e"></param>/// <param name="tiempo"></param>/// <param name="intento"></param>/// <param name="contexto"></param>static void ReportaError(Exception e, TimeSpan tiempo, int intento, Context contexto){Console.WriteLine($"異常: {intento:00} (調用秒數: {tiempo.Seconds} 秒)\t執行時間: {DateTime.Now}");}


try{ ? ??var politicaWaitAndRetry = Policy.Handle<DivideByZeroException>().WaitAndRetry(new[]{TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(3),TimeSpan.FromSeconds(5),TimeSpan.FromSeconds(7)}, ReportaError);politicaWaitAndRetry.Execute(() =>{ZeroExcepcion();});} ? ? ? ? ? ?catch (Exception e){Console.WriteLine($"Executed Failed,Message:({e.Message})");}

我們講完默認策略和重試策略,再來看看反饋策略,翻譯的更通俗一點則是執行失敗后返回的結果,此時要為Polly指定返回類型,然后指定異常,最后調用Fallback方法。

static string ThrowException(){ ? ? ? ? ? ?throw new Exception();}


var fallBackPolicy =Policy<string>.Handle<Exception>().Fallback("執行失敗,返回Fallback"); ? ? ? ? ? ?var fallBack = fallBackPolicy.Execute(() =>{ ? ? ? ? ? ? ? ?return ThrowException();});Console.WriteLine(fallBack);


包裹策略說到底就是混合多種策略,并執行。

var fallBackPolicy =Policy<string>.Handle<Exception>().Fallback("執行失敗,返回Fallback"); ? ? ? ? ? ?var fallBack = fallBackPolicy.Execute(() =>{ ? ? ? ? ? ? ? ?return ThrowException();});Console.WriteLine(fallBack); ? ? ?
?? ? ?
var politicaWaitAndRetry = Policy<string>.Handle<Exception>().Retry(3, (ex, count) =>{Console.WriteLine("執行失敗! 重試次數 {0}", count);Console.WriteLine("異常來自 {0}", ex.GetType().Name);}); ? ? ? ?
? ?
var mixedPolicy = Policy.Wrap(fallBackPolicy, politicaWaitAndRetry); ? ? ? ?
? ?
var mixedResult = mixedPolicy.Execute(ThrowException);Console.WriteLine($"執行結果: {mixedResult}");

至此關于Polly的基本介紹就已結束,該庫還是非常強大,更多特性請參考上述github例子,接下來我們來看看兩種具體場景。

ASP.NET Web APi使用Polly重試機制

在Polly v4.30中以上可以利用HandleResult指定返回結果,如下:

Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound)

基于此我們完全可以利用執行Web APi中的響應策略,如下:

public readonly RetryPolicy<HttpResponseMessage> _httpRequestPolicy;

拿到響應中狀態碼,若為500則重試三次。

_httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError).WaitAndRetryAsync(3,retryAttempt => TimeSpan.FromSeconds(retryAttempt));

上述獲取請求響應策略在構造函數中獲取。

public class PollyController : ApiController{ ? ? ?

? ? ??
public readonly RetryPolicy<HttpResponseMessage> _httpRequestPolicy; ? ? ?
? ? ? ?
public PollyController(){_httpRequestPolicy = Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError).WaitAndRetryAsync(3,retryAttempt => TimeSpan.FromSeconds(retryAttempt));}}

此時調用接口時執行策略的Execute或者ExecuteAsync方法即可。

public async Task<IHttpActionResult> Get(){ ? ? ? ? ?
??
var httpClient = new HttpClient(); ? ? ? ?
?? ?
string requestEndpoint = "http://localhost:4096";HttpResponseMessage httpResponse = await _httpRequestPolicy.ExecuteAsync(() => httpClient.GetAsync(requestEndpoint));IEnumerable<string> numbers = await httpResponse.Content.ReadAsAsync<IEnumerable<string>>(); ? ? ? ? ? ?return Ok(numbers);}

你以為除了在Web APi中使用,在其他框架中也可以使用,例如EntityFramework 6.x中,在EntityFramework 6+上出現了執行策略,也就是執行重試機制,這個時候我們依然可以借助Polly輪子來實現。

EntityFramework 6.x使用Polly重試機制

在EntityFramework 6.x中有如下執行策略接口,看起來是不是和Polly中的Execute方法是不是很類似。

//

? ? // 摘要:

? ? //? ? ?A strategy that is used to execute a command or query against the database, possibly

? ? //? ? ?with logic to retry when a failure occurs.

? ? public interface IDbExecutionStrategy

? ? {

? ? ? ? //

? ? ? ? // 摘要:

? ? ? ? //? ? ?Indicates whether this System.Data.Entity.Infrastructure.IDbExecutionStrategy

? ? ? ? //? ? ?might retry the execution after a failure.

? ? ? ? bool RetriesOnFailure { get; }


? ? ? ? //

? ? ? ? // 摘要:

? ? ? ? //? ? ?Executes the specified operation.

? ? ? ? //

? ? ? ? // 參數:

? ? ? ? //? ?operation:

? ? ? ? //? ? ?A delegate representing an executable operation that doesn't return any results.

? ? ? ? void Execute(Action operation);

? ? ? ? //

? ? ? ? // 摘要:

? ? ? ? //? ? ?Executes the specified operation and returns the result.

? ? ? ? //

? ? ? ? // 參數:

? ? ? ? //? ?operation:

? ? ? ? //? ? ?A delegate representing an executable operation that returns the result of type

? ? ? ? //? ? ?TResult.

? ? ? ? //

? ? ? ? // 類型參數:

? ? ? ? //? ?TResult:

? ? ? ? //? ? ?The return type of operation.

? ? ? ? //

? ? ? ? // 返回結果:

? ? ? ? //? ? ?The result from the operation.

? ? ? ? TResult Execute<TResult>(Func<TResult> operation);

? ? ? ? //

? ? ? ? // 摘要:

? ? ? ? //? ? ?Executes the specified asynchronous operation.

? ? ? ? //

? ? ? ? // 參數:

? ? ? ? //? ?operation:

? ? ? ? //? ? ?A function that returns a started task.

? ? ? ? //

? ? ? ? //? ?cancellationToken:

? ? ? ? //? ? ?A cancellation token used to cancel the retry operation, but not operations that

? ? ? ? //? ? ?are already in flight or that already completed successfully.

? ? ? ? //

? ? ? ? // 返回結果:

? ? ? ? //? ? ?A task that will run to completion if the original task completes successfully

? ? ? ? //? ? ?(either the first time or after retrying transient failures). If the task fails

? ? ? ? //? ? ?with a non-transient error or the retry limit is reached, the returned task will

? ? ? ? //? ? ?become faulted and the exception must be observed.

? ? ? ? Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken);

? ? ? ? //

? ? ? ? // 摘要:

? ? ? ? //? ? ?Executes the specified asynchronous operation and returns the result.

? ? ? ? //

? ? ? ? // 參數:

? ? ? ? //? ?operation:

? ? ? ? //? ? ?A function that returns a started task of type TResult.

? ? ? ? //

? ? ? ? //? ?cancellationToken:

? ? ? ? //? ? ?A cancellation token used to cancel the retry operation, but not operations that

? ? ? ? //? ? ?are already in flight or that already completed successfully.

? ? ? ? //

? ? ? ? // 類型參數:

? ? ? ? //? ?TResult:

? ? ? ? //? ? ?The result type of the System.Threading.Tasks.Task`1 returned by operation.

? ? ? ? //

? ? ? ? // 返回結果:

? ? ? ? //? ? ?A task that will run to completion if the original task completes successfully

? ? ? ? //? ? ?(either the first time or after retrying transient failures). If the task fails

? ? ? ? //? ? ?with a non-transient error or the retry limit is reached, the returned task will

? ? ? ? //? ? ?become faulted and the exception must be observed.

? ? ? ? [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]

? ? ? ? Task<TResult> ExecuteAsync<TResult>(Func<Task<TResult>> operation, CancellationToken cancellationToken);

? ? }

EntityFramework 6.x中的執行策略說到底就是數據庫連接問題即彈性連接,若考慮到數據庫過渡負載問題,此時應用程序和數據庫之間存在網絡問題的話。可能數據庫連接在幾秒內才返回,此時也沒有什么很大的問題,我們完全可以再嘗試一次,此時或許過了連接頻繁期,保證連接立馬恢復。如果數據庫連接一會恢復不了呢?或許是五分鐘,又或者是半個小時。如果我們只是一味盲目的進行重試,這顯然不可取。如果我們的應用程序連接超時時間超過了20秒,若我們選擇繼續連接到數據庫,我們將很快用完我們應用程序池中的工作線程。一直等待數據庫的響應。此時網站將完全無響應,同時會給用戶頁面無響應的友好提醒。這是Polly庫中描述斷路器的很好例子,換句話說如果我們捕獲了m個數量的SqlExceptions,假設數據庫有其他問題存在,導致我們不能在n秒內再嘗試連接數據庫。此時在數據庫連接上存在一個問題,那就是阻塞了我們的應用程序工作線程被掛起,我們試圖連接數據庫,我們假設不可用的話,但是我們要打破這種不可用,那就用Polly吧。

?

我們看到上述EntityFramework 6.x實現了IDbExecutionStrategy接口,但沒有實現如Polly中的斷路器模式,EntityFramework 6.x中的執行策略只是重試機制而已。 比如SqlAzureExecutionStrategy將在指定的時間段內重試指定的次數,直到一段時間段過去,重試指數過后,接著就是失敗。 同時所有后續調用將執行相同操作,重試并失敗。 這是調用數據庫時最好的策略嗎? 不敢肯定,或許Polly中的斷路器模式值得我們借鑒。我們自己來實現上述執行策略接口。

public class CirtuitBreakerExecutionStrategy : IDbExecutionStrategy{ ? ? ?
? ? ?
private Policy _policy; ? ?
? ? ?
public CirtuitBreakerExecutionStrategy(Policy policy){_policy = policy;} ? ?

? ?? ?
public void Execute(Action operation){_policy.Execute(() =>{operation.Invoke();});} ? ? ?
public TResult Execute<TResult>(Func<TResult> operation){ ? ? ? ? ? ?return _policy.Execute(() =>{ ? ? ? ? ? ? ? ?return operation.Invoke();});} ? ? ?

?
public async Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken){ ? ? ? ? ?
?
await _policy.ExecuteAsync(() =>{ ? ? ?
return operation.Invoke();});} ? ? ? ?

public async Task<TResult> ExecuteAsync<TResult>(Func<Task<TResult>> operation, CancellationToken cancellationToken){ ? ? ? ? ?
?
return await _policy.ExecuteAsync(() =>{ ? ? ? ? ? ?
return operation.Invoke();});} ? ? ?
??
public bool RetriesOnFailure { get { return true; } }}


接下來在基于代碼配置文件中設置我們上述自定義實現的斷路器模式。

? ?public class EFConfiguration : DbConfiguration{ ? ?
? ? ? ?
public Policy _policy; ? ?
? ?
? ? ? ?
public EFConfiguration(){_policy = Policy.Handle<Exception>().CircuitBreaker(3, TimeSpan.FromSeconds(60));SetExecutionStrategy("System.Data.SqlClient", () => new CirtuitBreakerExecutionStrategy(_policy));}}

上述自定義實現執行策略不保證一定有用或許也是一種解決方案呢。

總結

本節我們介紹了強大的Polly庫和其對應使用的兩種實際場景,有此輪子我們何不用起,將其進行封裝可以用于一切重試、緩存、異常處理。?

相關文章:?

  • 云計算設計模式(一)緩存預留模式

  • 使用熔斷器設計模式保護軟件

  • 云計算設計模式(二)——斷路器模式

  • API網關Ocelot 使用Polly 處理部分失敗問題

原文地址:http://www.cnblogs.com/CreateMyself/p/7589397.html


.NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

總結

以上是生活随笔為你收集整理的弹性和瞬态故障处理库Polly介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美少妇色图 | 久久男人天堂 | 丰满岳乱妇一区二区 | 日韩一区二区a片免费观看 伊人网综合在线 | 国产一区二区视频在线观看 | 日韩av看片 | 最近更新中文字幕 | 日韩亚洲一区二区三区 | 99热导航 | 视频在线一区二区三区 | 在线理论片| 亚洲第一黄 | 亚洲桃色av | 日本免费在线视频观看 | 国产女人水真多18毛片18精品 | 色妞www精品视频 | 少妇精品一区 | 国产精品久久久久野外 | 麻豆久久久9性大片 | 精品裸体舞一区二区三区 | av资源首页| 成人黄色免费看 | 国产一级二级三级在线观看 | 亚洲欧美一二三 | 日本在线小视频 | 亚洲在线观看一区 | 亚洲a∨无码无在线观看 | 狠狠干夜夜骑 | 国产青青 | 日韩中文在线播放 | 麻豆va | 久久久久亚洲av无码麻豆 | 在线视频在线观看 | 一级爱爱片 | 日本中文字幕在线播放 | 国产情侣第一页 | 伊人久久久久久久久久久 | 91网站免费| 国模私拍大尺度裸体av | 一级黄网站 | 欧美整片在线 | 深夜免费福利 | 成人在线视频观看 | 久久久午夜精品福利内容 | 国产av一区二区三区最新精品 | 久久yy | 精品国产乱子伦一区二区 | 亚欧精品在线 | 国产精品爽爽久久 | 免费一区二区视频 | 在线观看欧美精品 | 老熟妇午夜毛片一区二区三区 | 谁有免费黄色网址 | 噜噜噜在线视频 | 四虎永久网站 | 9l视频自拍蝌蚪9l视频成人 | 香蕉久久夜色精品 | 午夜精品久久久久久久久久蜜桃 | 亚洲免费黄色网 | 91久久视频 | 亚洲va天堂va欧美ⅴa在线 | 久久精品国产亚洲a | 精品中文字幕一区二区三区 | 日韩av色图 | 久久久久久久伊人 | 精品久久国产字幕高潮 | 白丝一区 | 殴美黄色大片 | 一本大道久久a久久综合婷婷 | 污视频大全 | 国产成人自拍偷拍 | www.av在线免费观看 | 成人在线免费观看视频 | 情欲超| 久久久久免费精品 | 一本色道久久综合亚洲二区三区 | 国产无遮挡a片又黄又爽 | av无码久久久久久不卡网站 | 欧美高潮视频 | 亚洲色图校园春色 | 国产呦小j女精品视频 | 一级片www| av在线天天 | 一区二区啪啪 | 亚洲视频网站在线观看 | 国产99久久九九精品无码免费 | 色香色香欲天天天影视综合网 | 爱爱中文字幕 | 激情欧美一区二区三区 | 午夜精品久久久久久久久久久久久 | 一区二区免费 | 免费观看高清在线 | 偷拍一区二区 | 国产精品视频导航 | 香蕉视频在线免费看 | 免费观看在线播放 | 综合激情五月婷婷 | 麻豆精品国产传媒av | 美女午夜激情 |