<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          云原生系統(tǒng)之彈性模式

          共 5307字,需瀏覽 11分鐘

           ·

          2021-07-16 05:04

          大綱


          1.云原生系統(tǒng)的彈性模式resiliency pattern    1.1 服務(wù)故障的雪崩效應(yīng)    1.2 回應(yīng)之前云原生--彈性請求的疑問?

          2. 彈性模式:作用在下游請求消息上3. 短期中斷的響應(yīng)碼4. Polly經(jīng)典策略5.   Golang 斷路器模式
          德國哲學(xué)家尼采說過:那些殺不死我的東西,只會讓我更加強(qiáng)大


          hi,好久不見,馬甲哥之前意譯并連載了《Microsoft Cloud-native toc.pdf》部分內(nèi)容

          ?什么是云原生?現(xiàn)代云原生設(shè)計理念?.NET微服務(wù)?談到云原生,繞不開容器化?支撐性服務(wù) & 自動化能力

          01

          云原生系統(tǒng)的彈性模式

          結(jié)合最近的工作經(jīng)驗,本次繼續(xù)聊一聊云原生的彈性模式 (resilience not scale), 這也是回應(yīng)《現(xiàn)代云原生設(shè)計理念》中

          “在分布式體系結(jié)構(gòu)中,當(dāng)服務(wù)B不響應(yīng)來自服務(wù)A的網(wǎng)絡(luò)請求會發(fā)生什么?
          當(dāng)服務(wù)C暫時不可用,其他調(diào)用C的服務(wù)被阻塞時該怎么辦?”

          由于網(wǎng)絡(luò)原因或自身原因,B、C服務(wù)不能及時響應(yīng),服務(wù)A發(fā)起的請求將被阻塞(直到B、C響應(yīng)),此時若大量請求涌入,服務(wù)A的線程資源將被消耗殆盡,服務(wù)A的處理性能受到極大影響,進(jìn)而影響下游依賴的external clients/backend srv。

          故障會傳播,造成連鎖反應(yīng),對整個分布式結(jié)構(gòu)造成災(zāi)難性后果,這就是服務(wù)故障的“雪崩效應(yīng)”。

          當(dāng)B、C服務(wù)不可用,下游客戶端/backend srv能做什么?
          客觀上請求不通,執(zhí)行預(yù)定的彈性策略:重試/斷路?

          02

          彈性模式:作用在下游的請求消息上

          彈性模式是系統(tǒng)面對故障仍然保持工作狀態(tài)的能力,它不是為了避免故障,而是接受故障并嘗試去面對它。

          Polly是一個全面的.NET彈性和瞬時錯誤處理庫,允許開發(fā)者以流暢和線程安全的方式表達(dá)彈性策略。

          策略場景行為
          Retry抖動/瞬時錯誤,短時間內(nèi)自動恢復(fù)在特定操作上配置重試行為
          Circuit Breaker在短期內(nèi)不大可能恢復(fù)當(dāng)故障超過閾值,在一段時間內(nèi)快速失敗
          Timeout
          限制調(diào)用者等待響應(yīng)的時間
          Bulkhead
          將操作限制在固定的資源池,防止故障傳播
          Cache
          自動存儲響應(yīng)
          Bulkhead
          一旦失敗,定義結(jié)構(gòu)化的行為

          一般將彈性策略作用到各種請求消息上(外部客戶端請求或后端服務(wù)請求)

          其目的是補償暫時不可用的服務(wù)請求。

          03

           短期中斷的響應(yīng)碼


          Http Status code原因
          404not found
          408request timeout
          429two many requests
          502bad gateway
          503service unavailable
          504gateway timeout

          正確規(guī)范的響應(yīng)碼能幫助開發(fā)者盡快確認(rèn)故障。

          執(zhí)行故障策略時,也能有的放矢,比如只重試那些由失敗引起的操作,對于403UnAuthorized不可重試。

          Kubernetes探針踩坑記

          04

           Polly的經(jīng)典策略


          ?Retry:對網(wǎng)絡(luò)抖動/瞬時錯誤可以執(zhí)行retry策略(預(yù)期故障可以很快恢復(fù)),?Circuit Breaker:為避免無效重試導(dǎo)致的故障傳播,在特定時間內(nèi)如果失敗次數(shù)到達(dá)閾值,斷路器打開(在一定時間內(nèi)快速失敗);           同時啟動一個timer,斷路器進(jìn)入半開模式(發(fā)出少量請求,請求成功則認(rèn)為故障已經(jīng)修復(fù),進(jìn)入關(guān)閉狀態(tài),重置失敗計數(shù)器。)

          services.AddHttpClient("small")        //降級        .AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(new HttpResponseMessage(),async b =>        {           // 1、降級打印異常          Console.WriteLine($"服務(wù)開始降級,上游異常消息:{b.Exception.Message}");          // 2、降級后的數(shù)據(jù)          b.Result.Content= new StringContent("請求太多,請稍后重試", Encoding.UTF8, "text/html");          b.Result.StatusCode = HttpStatusCode.TooManyRequests;          await Task.CompletedTask;        }))        //熔斷                                                              .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>()            .CircuitBreakerAsync(              3,    // 打開斷路器之前失敗的次數(shù)              TimeSpan.FromSeconds(20), // 斷路器的開啟的時間間隔              (ex, ts) =>  //熔斷器開啟              {                  Console.WriteLine($"服務(wù)斷路器開啟,異常消息:{ex.Exception.Message}");                  Console.WriteLine($"服務(wù)斷路器開啟的時間:{ts.TotalSeconds}s");              },               () => { Console.WriteLine($"服務(wù)斷路器重置"); },   //斷路器重置事件              () => { Console.WriteLine($"服務(wù)斷路器半開啟(一會開,一會關(guān))"); }  //斷路器半開啟事件            )        )        //重試        .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().RetryAsync(3))       // 超時        .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(2)));        

          ??當(dāng)一個應(yīng)用存在多個Http調(diào)用,按照上面的經(jīng)典寫法,代碼中會混雜大量重復(fù)、與業(yè)務(wù)無關(guān)的口水代碼,
          思考如何優(yōu)雅的對批量HttpClient做彈性策略。

          這里提供兩個實踐:

          ① 博客園馳名博主edisonchou: 使用AOP框架,動態(tài)織入Polly

          ② CSDN某佚名大牛,使用反射加配置實現(xiàn)的PollyHttpClientServiceCollectionExtension擴(kuò)展類, 支持在配置文件指定HttpClientName

          05

           Golang的斷路器

          go get github.com/sony/gobreaker

          func NewCircuitBreaker(st Settings) *CircuitBreaker 實例化斷路器對象, 參數(shù)如下:

          type Settings struct {    Name          string    MaxRequests   uint32       #半開狀態(tài)允許的最大請求數(shù)量,默認(rèn)為0,允許1個請求    Interval      time.Duration    Timeout       time.Duration  # 斷路器進(jìn)入半開狀態(tài)的間隔,默認(rèn)60s    ReadyToTrip   func(counts Counts) bool   # 切換狀態(tài)的邏輯    OnStateChange func(name string, from State, to State)}

          下面這個示例演示了:請求谷歌網(wǎng)站,失敗比例達(dá)到60%,就切換到"打開"狀態(tài),同時開啟60sTimer,到60s進(jìn)入“半開”狀態(tài)(允許發(fā)起一個請求),如果成功, 斷路器進(jìn)入"關(guān)閉"狀態(tài);失敗則重新進(jìn)入“打開”狀態(tài),并重置60sTimer

          package mainimport (    "fmt"    "io/ioutil"    "log"    "net/http"    "github.com/sony/gobreaker")var cb *gobreaker.CircuitBreakerfunc init() {    var st gobreaker.Settings    st.Name = "HTTP GET"    st.ReadyToTrip = func(counts gobreaker.Counts) bool {        failureRatio := float64(counts.TotalFailures) / float64(counts.Requests)        return counts.Requests >= 3 && failureRatio >= 0.6    }    cb = gobreaker.NewCircuitBreaker(st)}// Get wraps http.Get in CircuitBreaker.func Get(url string) ([]byte, error) {    body, err := cb.Execute(func() (interface{}, error) {        resp, err := http.Get(url)        if err != nil {            return nil, err        }        defer resp.Body.Close()        body, err := ioutil.ReadAll(resp.Body)        if err != nil {            return nil, err        }        return body, nil    })    if err != nil {        return nil, err    }    return body.([]byte), nil}func main() {    body, err := Get("http://www.google.com/robots.txt")    if err != nil {        log.Fatal(err)    }    fmt.Println(string(body))}

          總結(jié)



             本文記錄了云原生系統(tǒng)的彈性模式:通過預(yù)設(shè)策略直面失敗,補償暫時不可用的請求、避免故障傳播, 這對于實現(xiàn)微服務(wù)高可用、彈性容錯相當(dāng)重要。
          ?https://blog.csdn.net/weixin_44588495/article/details/106361934?https://blog.csdn.net/qq_26900081/article/details/108071374?https://www.cnblogs.com/edisonchou/p/9159644.html?https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/application-resiliency-patterns?https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker





          更多干貨及最佳實踐
          關(guān)注并星標(biāo)我們

          后臺回復(fù)cloud-native,獲取微軟云原生技術(shù)白皮書

          今天因為你的點贊,讓我元氣滿滿!

           ??本文永久鏈接在這里!

          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  豆花视频网页 | 日韩区一中文字幕a∨ | 亚洲欧美高清在线观看 | 青青草在线超碰 | 色逼|