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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

开源服务容错处理库Polly使用文档

發(fā)布時間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开源服务容错处理库Polly使用文档 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在進入SOA之后,我們的代碼從本地方法調用變成了跨機器的通信。任何一個新技術的引入都會為我們解決特定的問題,都會帶來一些新的問題。比如網絡故障、依賴服務崩潰、超時、服務器內存與CPU等其它問題。正是因為這些問題無法避免,所以我們在進行系統設計、特別是進行分布式系統設計的時候以“Design For Failure”(為失敗而設計)為指導原則。把一些邊緣場景以及服務之間的調用發(fā)生的異常和超時當成一定會發(fā)生的情況來預先進行處理。

Design For Failure
1.?一個依賴服務的故障不會嚴重破壞用戶的體驗。
2. 系統能自動或半自動處理故障,具備自我恢復能力。

以下是一些經驗的服務容錯模式

  • 超時與重試(Timeout and Retry)

  • 限流(Rate Limiting)

  • 熔斷器(Circuit Breaker)

  • 艙壁隔離(Bulkhead Isolation)

  • 回退(Fallback)

如果想詳細了解這幾種模式可以參考美團技術團隊的總結:服務容錯模式。我們今天要講的是,thanks to the community?多謝社區(qū), Polly已經為我們實現了以上全部的功能。Polly是一個C#實現的彈性瞬時錯誤處理庫(resilience and transient-fault-handling library一直覺得這個英文翻譯不是很好) 。在Polly中,對這些服務容錯模式分為兩類:

  • 錯誤處理fault handling :重試、熔斷、回退

  • 彈性應變resilience:超時、艙壁、緩存

可以說錯誤處理是當錯誤已經發(fā)生時,防止由于該錯誤對整個系統造成更壞的影響而設置。而彈性應變,則在是錯誤發(fā)生前,針對有可能發(fā)生錯誤的地方進行預先處理,從而達到保護整個系統的目地。

Polly?錯誤處理使用三步曲

  • 定義條件: 定義你要處理的 錯誤異常/返回結果

  • 定義處理方式 : 重試,熔斷,回退

  • 執(zhí)行

先看一個簡單的例子

// 這個例子展示了當DoSomething方法執(zhí)行的時候如果遇到SomeExceptionType的異常則會進行重試調用。var policy = Policy.Handle<SomeExceptionType>() // 定義條件?.Retry(); // 定義處理方式// 執(zhí)行policy.Execute(() => DoSomething());

定義條件

我們可以針對兩種情況來定義條件:錯誤異常和返回結果。

// 單個異常類型Policy.Handle<HttpRequestException>()// 限定條件的單個異常Policy.Handle<SqlException>(ex => ex.Number == 1205)// 多個異常類型Policy.Handle<HttpRequestException>().Or<OperationCanceledException>()// 限定條件的多個異常Policy.Handle<SqlException>(ex => ex.Number == 1205).Or<ArgumentException>(ex => ex.ParamName == "example")// Inner Exception 異常里面的異常類型 Policy.HandleInner<HttpRequestException>().OrInner<OperationCanceledException>(ex => ex.CancellationToken != myToken)

以及用返回結果來限定

// 返回結果加限定條件 Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound)// 處理多個返回結果Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError).OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.BadGateway)// 處理元類型結果 (用.Equals)Policy.HandleResult<HttpStatusCode>(HttpStatusCode.InternalServerError).OrResult<HttpStatusCode>(HttpStatusCode.BadGateway) // 在一個policy里面同時處理異常和返回結果。HttpStatusCode[] httpStatusCodesWorthRetrying = {HttpStatusCode.RequestTimeout, // 408HttpStatusCode.InternalServerError, // 500HttpStatusCode.BadGateway, // 502HttpStatusCode.ServiceUnavailable, // 503HttpStatusCode.GatewayTimeout // 504};?HttpResponseMessage result = Policy.Handle<HttpRequestException>().OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode)).RetryAsync(...).ExecuteAsync( /* some Func<Task<HttpResponseMessage>> */ )

定義處理方式

在這里使用的處理方式就是我們最開始說的服務容錯模式,我們將介紹以下三種:重試、熔斷、回退。

重試

重試很好理解,當發(fā)生某種錯誤或者返回某種結果的時候進行重試。Polly里面提供了以下幾種重試機制

  • 按次數重試

  • 不斷重試(直到成功)

  • 等待之后按次數重試

  • 等待之后不斷重試(直到成功)

按次數重試

// 重試1次Policy.Handle<SomeExceptionType>().Retry()// 重試3(N)次Policy.Handle<SomeExceptionType>().Retry(3)// 重試多次,加上重試時的action參數Policy.Handle<SomeExceptionType>().Retry(3, (exception, retryCount) =>{ // 干點什么,比如記個日志之類的?});

不斷重試

// 不斷重試,直到成功Policy.Handle<SomeExceptionType>().RetryForever()// 不斷重試,帶action參數在每次重試的時候執(zhí)行Policy.Handle<SomeExceptionType>().RetryForever(exception =>{ // do something?});

等待之后重試

// 重試3次,分別等待1、2、3秒。Policy.Handle<SomeExceptionType>().WaitAndRetry(new[]{TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(2),TimeSpan.FromSeconds(3)});

當然也可以在每次重試的時候添加一些處理,這里我們可以從上下文中獲取一些數據,這些數據在policy啟動執(zhí)行的時候可以傳進來。

Policy.Handle<SomeExceptionType>().WaitAndRetry(new[]{TimeSpan.FromSeconds(1),TimeSpan.FromSeconds(2),TimeSpan.FromSeconds(3)}, (exception, timeSpan, context)?=> { // do something });

把WiatAndRetry抱成WaitAndRetryForever()則可以實現重試直到成功。

熔斷

熔斷也可以被作為當遇到某種錯誤場景下的一個操作。以下代碼展示了當發(fā)生2次SomeExceptionType的異常的時候則會熔斷1分鐘,該操作后續(xù)如果繼續(xù)嘗試執(zhí)行則會直接返回錯誤 。

Policy.Handle<SomeExceptionType>() .CircuitBreaker(2, TimeSpan.FromMinutes(1));

可以在熔斷和恢復的時候定義委托來做一些額外的處理。onBreak會在被熔斷時執(zhí)行,而onReset則會在恢復時執(zhí)行。

Action<Exception, TimeSpan> onBreak = (exception, timespan)?=> { ... }; Action onReset = ()?=> { ... }; CircuitBreakerPolicy breaker = Policy.Handle<SomeExceptionType>().CircuitBreaker(2, TimeSpan.FromMinutes(1), onBreak, onReset);

熔斷器狀態(tài)

我們的CircuitBreakPolicy的State定義了當前熔斷器的狀態(tài),我們也可能調用它的Isolate和Reset方法來手動熔斷和恢復 。

CircuitState state = breaker.CircuitState;
  • Closed?關閉狀態(tài),允許執(zhí)行

  • Open?自動打開,執(zhí)行會被阻斷

  • Isolate?手動打開,執(zhí)行會被阻斷

  • HalfOpen? 從自動打開狀態(tài)恢復中,在熔斷時間到了之后從Open狀態(tài)切換到Closed

// 手動打開熔斷器,阻止執(zhí)行breaker.Isolate();?// 恢復操作,啟動執(zhí)行 breaker.Reset();

回退(Fallback)

// 如果執(zhí)行失敗則返回UserAvatar.BlankPolicy.Handle<Whatever>().Fallback<UserAvatar>(UserAvatar.Blank)// 發(fā)起另外一個請求去獲取值Policy.Handle<Whatever>().Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar()) // where: public UserAvatar GetRandomAvatar() { ... }// 返回一個指定的值,添加額外的處理操作。onFallbackPolicy.Handle<Whatever>().Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) => { // do something});

執(zhí)行polly policy

為我聲明了一個Policy,并定義了它的異常條件和處理方式,那么接下來就是執(zhí)行它。執(zhí)行是把我們具體要運行的代碼放到Policy里面。

// 執(zhí)行一個Actionvar policy = Policy.Handle<SomeExceptionType>().Retry();policy.Execute(() => DoSomething());

這就是我們最開始的例子,還記得我們在異常處理的時候有一個context上下文嗎?我們可以在執(zhí)行的時候帶一些參數進去

// 看我們在retry重試時被調用的一個委托,它可以從context中拿到我們在execute的時候傳進來的參數 。var policy = Policy.Handle<SomeExceptionType>().Retry(3, (exception, retryCount, context) =>{ var methodThatRaisedException = context["methodName"];Log(exception, methodThatRaisedException);});policy.Execute(() => DoSomething(), new Dictionary<string, object>() {{ "methodName", "some method" }} );

當然,我們也可以將Handle,Retry, Execute?這三個階段都串起來寫。

Policy.Handle<SqlException>(ex => ex.Number == 1205).Or<ArgumentException>(ex => ex.ParamName == "example").Retry().Execute(() => DoSomething());

Polly?彈性應變處理Resilience

我們在上面講了Polly在錯誤處理方面的使用,接下來我們介紹Polly在彈性應變這塊的三個應用:?超時、艙壁和緩存。

超時

Policy.Timeout(TimeSpan.FromMilliseconds(2500))

支持傳入action回調

Policy.Timeout(30, onTimeout: (context, timespan, task)?=> { // do something });

超時分為樂觀超時與悲觀超時,樂觀超時依賴于CancellationToken?,它假設我們的具體執(zhí)行的任務都支持CancellationToken。那么在進行timeout的時候,它會通知執(zhí)行線程取消并終止執(zhí)行線程,避免額外的開銷。下面的樂觀超時的具體用法 。

// 聲明 PolicyPolicy timeoutPolicy = Policy.TimeoutAsync(30); HttpResponseMessage httpResponse = await timeoutPolicy.ExecuteAsync( async ct => await httpClient.GetAsync(endpoint, ct), CancellationToken.None // 最后可以把外部的 CacellationToken附加到 timeoutPollcy的 CT上,在這里我們沒有附加);

悲觀超時與樂觀超時的區(qū)別在于,如果執(zhí)行的代碼不支持取消CancellationToken,它還會繼續(xù)執(zhí)行,這會是一個比較大的開銷。

Policy.Timeout(30, TimeoutStrategy.Pessimistic)

上面的代碼也有悲觀sad…的寫法

Policy timeoutPolicy = Policy.TimeoutAsync(30, TimeoutStrategy.Pessimistic);var response = await timeoutPolicy.ExecuteAsync( async () => await FooNotHonoringCancellationAsync(), );// 在這里我們沒有 任何與CancllationToken相關的處理

艙壁

在開頭的那篇文章中詳細解釋了艙壁這種模式,它用來限制某一個操作的最大并發(fā)執(zhí)行數量 。比如限制為12

Policy.Bulkhead(12)

同時,我們還可以控制一個等待處理的隊列長度

Policy.Bulkhead(12, 2)

以及當請求執(zhí)行操作被拒絕的時候,執(zhí)行回調

Policy.Bulkhead(12, context => { // do something?});

緩存

Polly的緩存需要依賴于一個外部的Provider。

var memoryCacheProvider = new Polly.Caching.MemoryCache.MemoryCacheProvider(MemoryCache.Default);
var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5));// 設置一個絕對的過期時間
var cachePolicy = Policy.Cache(memoryCacheProvider, new AbsoluteTtl(DateTimeOffset.Now.Date.AddDays(1));// 設置一個滑動的過期時間,即每次使用緩存的時候,過期時間會更新

var cachePolicy = Policy.Cache(memoryCacheProvider, new SlidingTtl(TimeSpan.FromMinutes(5));// 我們用Policy的緩存機制來實現從緩存中讀取一個值,如果該值在緩存中不存在則從提供的函數中取出這個值放到緩存中。// 借且于Polly Cache 這個操作只需要一行代碼即可。

TResult result = cachePolicy.Execute(() => getFoo(), new Context("FooKey")); // "FooKey" is the cache key used in this execution.// Define a cache Policy, and catch any cache provider errors for logging.var cachePolicy = Policy.Cache(myCacheProvider, TimeSpan.FromMinutes(5), (context, key, ex) => { logger.Error($"Cache provider, for key {key}, threw exception: {ex}."); // (for example)?} );

組合Policy

最后我們要說的是如何將多個policy組合起來。大致的操作是定義多個policy,然后用Wrap方法即可。

var policyWrap = Policy.Wrap(fallback, cache, retry, breaker, timeout, bulkhead); policyWrap.Execute(...)

在另一個Policy聲明時組合使用其它外部聲明的Policy。

PolicyWrap commonResilience = Policy.Wrap(retry, breaker, timeout);Avatar avatar = Policy.Handle<Whatever>().Fallback<Avatar>(Avatar.Blank).Wrap(commonResilience).Execute(() => { /* get avatar */ });

相關文章:

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

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

  • Polly組件對微服務場景的價值

原文地址:http://www.jessetalk.cn/2018/03/25/asp-vnext-polly-docs/


.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com

總結

以上是生活随笔為你收集整理的开源服务容错处理库Polly使用文档的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 在线观看视频你懂得 | 免费午夜视频在线观看 | 97人人爱| 精品视频免费看 | 九色激情网 | 欧美激情一区在线 | 曰韩av| 日日干天天射 | xxxxwwww国产| 国产农村妇女毛片精品久久 | 美女被草视频在线观看 | 东京热一区二区三区四区 | 91二区| 亚洲20p| 国产美女又黄又爽又色视频免费 | 在线超碰av | 亚洲狼人综合网 | 亚洲性生活网站 | 污污的视频网站在线观看 | 99热精品在线播放 | 九九热精品视频 | 夜晚福利视频 | 亚洲成人aa| 91综合精品 | 加勒比综合在线 | 一区二区三区国产 | 777精品视频 | 欧美亚洲国产一区二区三区 | 国产精品久久久久久久久久免费看 | 老地方在线观看免费动漫 | 欧美亚洲 | 亚洲精品成人片在线观看精品字幕 | 成人国产精品视频 | hs视频在线观看 | 国产成人一区在线观看 | 亚洲综合激情五月久久 | 成人精品一区二区三区视频 | 亚洲欧美偷拍视频 | 亚洲精品国产欧美 | 国产精品77| 91精品国产免费 | 动漫艳母在线观看 | 操操操日日日 | 久久99国产精品久久99果冻传媒 | 欧美日韩人妻精品一区二区三区 | 高h视频在线观看 | 极品白嫩少妇无套内谢 | 校园春色亚洲激情 | 99久久人妻无码中文字幕系列 | 亚洲一区二区播放 | 日本高清三区 | 国产精品一卡二卡在线观看 | 色爱亚洲 | 国产一级片免费视频 | 啪一啪在线 | 韩国三级hd中文字幕叫床浴室 | 黄色免费网站观看 | 综合激情婷婷 | av免费播放网站 | 国产免费av在线 | 在线成人日韩 | 欧美极品少妇xxxxⅹ免费视频 | 国产精彩视频一区二区 | 精品99999 | 老色鬼在线| 91麻豆精品国产91久久久更新时间 | 校花被c到呻吟求饶 | 久久久久婷婷 | brazzers精品成人一区 | a级片毛片| 丁香伊人网 | 风间由美av | 国产一级啪啪 | 欧美精品性视频 | 精品福利一区二区 | 亚洲精品.www | 天堂中文在线免费观看 | 国产91福利| 国产精品入口 | 日韩一区二区三区在线观看 | 中文字幕亚洲综合 | 国产高清不卡一区 | 国产女人18毛片水真多18 | 久久精品国产欧美亚洲人人爽 | 久久久资源 | 波多野吉衣中文字幕 | 粉嫩aⅴ一区二区三区 | 亚洲一二三区视频 | 精品视频999 | 成人小视频在线播放 | 在线男人天堂 | 亚洲男人天堂网址 | 德国经典free性复古xxxx | 色窝窝无码一区二区三区成人网站 | 亚洲欧美日本在线观看 | 黄色网在线 | av资源首页 | 97av视频在线 | 强开乳罩摸双乳吃奶羞羞www |