熔斷器實現(xiàn)Google SRE過載保護算法

熔斷器的實現(xiàn)參考了Google SRE過載保護算法,該算法的原理如下:

  • 請求數(shù)量(requests):調(diào)用方發(fā)起請求的數(shù)量總和
  • 請求接受數(shù)量(accepts):被調(diào)用方正常處理的請求數(shù)量

在正常情況下,這兩個值是相等的,隨著被調(diào)用方服務(wù)出現(xiàn)異常開始拒絕請求,請求接受數(shù)量(accepts)的值開始逐漸小于請求數(shù)量(requests),這個時候調(diào)用方可以繼續(xù)發(fā)送請求,直到requests = K * accepts,一旦超過這個限制,熔斷器就回打開,新的請求會在本地以一定的概率被拋棄直接返回錯誤,概率的計算公式如下:

image.png

大白話解釋:

也就是說,當(dāng) accepts 的數(shù)量少于 requests 的時候;也就是出現(xiàn)請求錯誤,那這個公式就會出現(xiàn)正數(shù),也就是會有一個分數(shù)出來,這個就是本地直接拋棄該請求(不向后端發(fā)送)的概率。

如何使用:

拿 kratos 中的代碼來做例子;

// NewBreaker return a sreBresker with options
func NewBreaker(opts ...Option) circuitbreaker.CircuitBreaker {
    opt := options{
        success: 0.6,
        request: 100,
        bucket:  10,
        window:  3 * time.Second,
    }
    for _, o := range opts {
        o(&opt)
    }
    counterOpts := window.RollingCounterOpts{
        Size:           opt.bucket,
        BucketDuration: time.Duration(int64(opt.window) / int64(opt.bucket)),
    }
    stat := window.NewRollingCounter(counterOpts)
    return &Breaker{
        stat:    stat,
        //這個 r 就是用來比對是否可發(fā)起請求的閥值
        r:       rand.New(rand.NewSource(time.Now().UnixNano())),
        request: opt.request,
        k:       1 / opt.success,
        state:   StateClosed,
    }
}

。。。
。。。
。。。
// Allow request if error returns nil.
func (b *Breaker) Allow() error {
    // The number of requests accepted by the backend
    accepts, total := b.summary()
    // The number of requests attempted by the application layer(at the client, on top of the adaptive throttling system)
    requests := b.k * float64(accepts)
    // check overflow requests = K * accepts
    if total < b.request || float64(total) < requests {
        if atomic.LoadInt32(&b.state) == StateOpen {
            atomic.CompareAndSwapInt32(&b.state, StateOpen, StateClosed)
        }
        return nil
    }
    if atomic.LoadInt32(&b.state) == StateClosed {
        atomic.CompareAndSwapInt32(&b.state, StateClosed, StateOpen)
    }
    dr := math.Max(0, (float64(total)-requests)/float64(total+1))
    drop := b.trueOnProba(dr)
    if drop {
        return circuitbreaker.ErrNotAllowed
    }
    return nil
}
。。。
。。。
。。。
func (b *Breaker) trueOnProba(proba float64) (truth bool) {
    b.randLock.Lock()
    truth = b.r.Float64() < proba
    b.randLock.Unlock()
    return
}

1.定義
NewBreaker 中,隨機定義了閥值 r ,用于比對通過概率。
code github address : https://github.com/go-kratos/aegis

2.允許邏輯(公式實現(xiàn))
Allow 中 首先獲取請求數(shù)和數(shù),并且計算公式結(jié)果

3.通過概率比較
trueOnProba 方法是直接的比較大小,這里就體現(xiàn)了這個隨機丟棄的邏輯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 在微服務(wù)中服務(wù)間依賴非常常見,比如評論服務(wù)依賴審核服務(wù)而審核服務(wù)又依賴反垃圾服務(wù),當(dāng)評論服務(wù)調(diào)用審核服務(wù)時,審核服...
    kevwan閱讀 1,491評論 0 3
  • 1.1 Hystrix介紹 Hystrix的設(shè)計原則是什么? l 資源隔離(線程池隔離和信號量隔離)機制:限制調(diào)用...
  • 簡介 微服務(wù)結(jié)構(gòu)中,服務(wù)調(diào)用其他服務(wù),如果服務(wù)提供者不可用,會引起服務(wù)調(diào)用者不可用,進而引起整個調(diào)用鏈上所有的服務(wù)...
    陸陽226閱讀 1,758評論 0 0
  • 作者:Laszlo Bence Nagy譯者:馬若飛審校:羅廣明原文:https://banzaicloud.co...
    ServiceMesher閱讀 1,508評論 0 0
  • 在深入研究熔斷器之前,我們需要先看一下Hystrix的幾個重要的默認配置,這幾個配置在HystrixCommand...
    Java學(xué)習(xí)錄閱讀 273評論 0 0

友情鏈接更多精彩內(nèi)容