最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go-zero熔斷機制組件Breaker接口定義使用解析

 更新時間:2023年05月29日 09:03:12   作者:Keson  
這篇文章主要為大家介紹了go-zero熔斷機制組件Breaker接口定義使用解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

概述

熔斷機制是一種微服務保護機制。當某個微服務出現(xiàn)故障或者異常時,通過熔斷機制,可以防止故障或異常擴散到整個微服務系統(tǒng)中,從而避免整個微服務系統(tǒng)被拖垮,熔斷機制的大致流程是(以下流程基于 go-zero 熔斷器為背景):

  • 指標采集:熔斷器通過不斷監(jiān)測服務的請求和響應來收集指標,這些指標包含但不限于響應時間,錯誤率,超時率等。
  • 閾值設定:熔斷器通過指標來計算出閾值,當指標超過閾值時,熔斷器會打開。
  • 熔斷狀態(tài)控制:一般熔斷器都有3個狀態(tài),熔斷開啟,熔斷恢復,熔斷半開:
    3.1 熔斷開啟:當服務的指標超過設定的閾值時,熔斷機制將服務切換到熔斷狀態(tài)。在熔斷狀態(tài)下,服務將停止接收新的請求,并立即返回錯誤響應,而不會進行實際的業(yè)務邏輯處理。
    3.2 熔斷恢復:一旦服務進入熔斷狀態(tài),熔斷機制會設定一個恢復時間窗口,在該窗口內(nèi)不再接收新的請求。在這段時間內(nèi),系統(tǒng)可以嘗試修復服務或等待服務自動恢復。
    3.3 半開狀態(tài):在熔斷恢復時間窗口結束后,熔斷機制將服務切換到半開狀態(tài)。在半開狀態(tài)下,系統(tǒng)會嘗試發(fā)送一部分請求給服務,以檢測其是否已經(jīng)恢復正常。如果這些請求成功響應,那么服務將被認為是恢復正常,并繼續(xù)接收新的請求。否則,服務將重新進入熔斷狀態(tài)。
    但在 go-zero 中并非完全如此,go-zero 中只有熔斷關閉,熔斷觸發(fā)開啟狀態(tài),為什么是熔斷觸發(fā)開啟,在 go-zero 中,熔斷指標達到設定閾值后,并不是直接攔截所有請求,而是有一定的概率攔截請求,這并不是說他就沒有熔斷恢復和熔斷半開狀態(tài),只是 go-zero 中熔斷器將這 2 個狀態(tài)巧妙的用滑動窗口來實現(xiàn)了。

go-zero 熔斷器時序圖

源碼解析

在 go-zero 中,Breaker 是一個接口,其接口定義如下:

Breaker interface {
   Name() string
   Allow() (Promise, error)
   Do(req func () error) error
   DoWithAcceptable(req func () error, acceptable Acceptable) error
   DoWithFallback(req func () error, fallback func (err error) error) error
   DoWithFallbackAcceptable(req func () error, fallback func (err error) error, acceptable Acceptable) error
}

Breaker 接口定義了 6 個方法,提供了 2 中對熔斷器控制執(zhí)行的機制:

Allow 方法拋出了一個 Promise 句柄,允許用戶自行對熔斷指標進行控制,采集指標可以根據(jù)用戶需求選擇請求時延、錯誤碼等,且熔斷觸發(fā)后需要執(zhí)行的邏輯也有用戶自行控制。如 go-zero
中 rest 中熔斷中間件的用法:

func BreakerHandler(method, path string, metrics *stat.Metrics) func(http.Handler) http.Handler {
 brk := breaker.NewBreaker(breaker.WithName(strings.Join([]string{method, path}, breakerSeparator)))
 return func(next http.Handler) http.Handler {
     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
         promise, err := brk.Allow()// 熔斷執(zhí)行邏輯,用戶自行控制
         if err != nil {
             metrics.AddDrop()
             logx.Errorf("[http] dropped, %s - %s - %s",
                 r.RequestURI, httpx.GetRemoteAddr(r), r.UserAgent())
             w.WriteHeader(http.StatusServiceUnavailable)
             return
         }
         cw := &response.WithCodeResponseWriter{Writer: w}
         defer func() {// 熔斷指標采集,用戶自行控制
             if cw.Code < http.StatusInternalServerError {
                 promise.Accept()
             } else {
                 promise.Reject(fmt.Sprintf("%d %s", cw.Code, http.StatusText(cw.Code)))
             }
         }()
         next.ServeHTTP(cw, r)
     })
 }
}
  • DoXxx 方法則是另一個中熔斷器控制機制,其只能通過錯誤碼來進行指標采集,當然,用戶是可以根據(jù)錯誤碼來控制哪些錯誤碼是要加入到指標里面的,除此外,
    函數(shù)執(zhí)行體也是用用戶告知到熔斷器中,熔斷器會在熔斷未觸發(fā)的情況下執(zhí)行函數(shù)體,如果熔斷觸發(fā),則會執(zhí)行熔斷器中的邏輯。如返回熔斷錯誤。

DoXxx 方法在底層邏輯最終都是調(diào)用一個基礎方法,只是根據(jù)入?yún)⒌牟煌┞读瞬煌暮瘮?shù):

doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error

我們來看一下 doReq 方法的一個流程圖:

func (b *googleBreaker) doReq(req func() error, fallback func(err error) error, acceptable Acceptable) error {
    // 判斷熔斷器是否開啟
    if err := b.accept(); err != nil {
        if fallback != nil {
            return fallback(err)
        }
        return err
    }
    // 函數(shù)異常退出,上報失敗指標
    defer func() {
        if e := recover(); e != nil {
            b.markFailure()
            panic(e)
        }
    }()
    // 執(zhí)行用戶函數(shù),并通過函數(shù)執(zhí)行返回的錯誤信息由用戶判斷是否為可接受的錯誤
    // 上報指標
    err := req()
    if acceptable(err) {
        b.markSuccess()
    } else {
        b.markFailure()
    }
    return err
}

熔斷器狀態(tài)判斷

判斷熔斷器是否開啟是根據(jù)當前窗口的歷史指標來計算的,這里采用了 google SRE 里面的丟棄比例算法,當丟棄比例為0時,則無需觸發(fā)熔斷,否則
隨機觸發(fā)熔斷機制。

func (b *googleBreaker) accept() error {
    accepts, total := b.history()
    weightedAccepts := b.k * float64(accepts)
    // https://landing.google.com/sre/sre-book/chapters/handling-overload/#eq2101
    dropRatio := math.Max(0, (float64(total-protection)-weightedAccepts)/float64(total+1))
    if dropRatio <= 0 {
        return nil
    }
    if b.proba.TrueOnProba(dropRatio) {
        return ErrServiceUnavailable
    }
    return nil
}
func (b *googleBreaker) history() (accepts, total int64) {
   b.stat.Reduce(func(b *collection.Bucket) {
      accepts += int64(b.Sum)
      total += b.Count
   })
    return
}

指標上報

指標上報是將用戶執(zhí)行后的請求錯誤返回給用戶,用戶可以根據(jù)錯誤碼指定改錯誤碼是否納入失敗指標

// 標記成功一次
func (b *googleBreaker) markSuccess() {
    b.stat.Add(1)
}
// 標記失敗一次
func (b *googleBreaker) markFailure() {
    b.stat.Add(0)
}

總結

熔斷器的實現(xiàn)起始就是一個指標采集+指標計算的過程,然后用戶可以根據(jù)指標計算結果來決定是否觸發(fā)熔斷,其中難點還是在于指標統(tǒng)計過程,這個過程是用滑動窗口來進行指標采集的,關于滑動窗口算法這里就不做過多的介紹了。

以上就是go-zero組件Breaker的詳細內(nèi)容,更多關于go-zero 組件Breaker的資料請關注腳本之家其它相關文章!

相關文章

  • Go 實現(xiàn)基于Token 的登錄流程深度分析

    Go 實現(xiàn)基于Token 的登錄流程深度分析

    Token 認證機制的核心思想是,服務端在用戶登錄時生成一個 Token,客戶端在后續(xù)的請求中攜帶這個 Token,服務端通過驗證 Token 的有效性來確認用戶的身份,本文將帶你深入探索基于 Token 的登錄流程,這是一種更為靈活且適用于現(xiàn)代應用架構的認證方式
    2024-03-03
  • golang中為什么Response.Body需要被關閉詳解

    golang中為什么Response.Body需要被關閉詳解

    這篇文章主要給大家介紹了關于golang中為什么Response.Body需要被關閉的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-08-08
  • Go語言七篇入門教程一簡介初識

    Go語言七篇入門教程一簡介初識

    本篇是Go語言七篇入門系列第一篇Go語言初識及簡單介紹,從現(xiàn)在開始一起打開Go語言的學習大門吧,希望能夠有所幫助,祝大家多多進步
    2021-11-11
  • 詳解如何在Go中實現(xiàn)優(yōu)雅停止

    詳解如何在Go中實現(xiàn)優(yōu)雅停止

    和其他語言相比,Go 中有相同也有不同,相同的是實現(xiàn)思路上和其他語言沒啥差異,不同在于 Go 采用的是 goroutine + channel 的并發(fā)模型,與傳統(tǒng)的進程線程相比,實現(xiàn)細節(jié)上存在差異,本文將從實際場景和它的一般實現(xiàn)方式展開,逐步討論這個話題,需要的朋友可以參考下
    2024-04-04
  • Go語言使用釘釘機器人推送消息的實現(xiàn)示例

    Go語言使用釘釘機器人推送消息的實現(xiàn)示例

    本文主要介紹了Go語言使用釘釘機器人推送消息的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Golang學習筆記之安裝Go1.15版本(win/linux/macos/docker安裝)

    Golang學習筆記之安裝Go1.15版本(win/linux/macos/docker安裝)

    這篇文章主要介紹了Golang學習筆記之安裝Go1.15版本(win/linux/macos/docker安裝),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 詳解Go語言中的數(shù)據(jù)庫操作

    詳解Go語言中的數(shù)據(jù)庫操作

    數(shù)據(jù)庫是應用開發(fā)中必須要掌握的技巧。這篇文章主要和大家介紹一下Go語言中相關的數(shù)據(jù)庫操作,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2023-02-02
  • golang開發(fā)中channel使用

    golang開發(fā)中channel使用

    channel[通道]是golang的一種重要特性,正是因為channel的存在才使得golang不同于其它語言。這篇文章主要介紹了golang開發(fā)中channel使用,需要的朋友可以參考下
    2020-09-09
  • 詳解Go語言如何高效解壓ZIP文件

    詳解Go語言如何高效解壓ZIP文件

    在日常開發(fā)中,我們經(jīng)常需要處理 ZIP 文件,本文主要為大家介紹一個使用 Go 語言編寫的高效 ZIP 文件解壓工具,希望對大家有一定的幫助
    2025-03-03
  • Go語言利用excelize庫自動化操作Excel的實戰(zhàn)指南

    Go語言利用excelize庫自動化操作Excel的實戰(zhàn)指南

    這篇文章主要為大家詳細介紹了如何使用Go語言自動化操作Excel,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下吧
    2026-03-03

最新評論

永丰县| 互助| 凤山市| 贡嘎县| 屏南县| 长武县| 岑溪市| 武乡县| 建阳市| 类乌齐县| 仙游县| 商都县| 荥阳市| 乳源| 合肥市| 尼勒克县| 木兰县| 白城市| 贵溪市| 新蔡县| 聂拉木县| 那曲县| 镇雄县| 张掖市| 息烽县| 砚山县| 神农架林区| 丽江市| 安宁市| 名山县| 扶风县| 宜昌市| 将乐县| 手游| 丹凤县| 阳信县| 浦城县| 青海省| 岚皋县| 英德市| 姜堰市|