微服務元件之限流器與熔斷器
在微服務架構裡面一個很常見的問題就是服務之間的延遲和通訊失敗問題,極端的情況下,甚至會因為某個服務的效能下降或者故障當機,導致訪問超時,層層傳遞,引發雪崩,最終導致整個系統崩潰,而限流器和熔斷器 (這兩個元件都是客戶端的) 能很好的解決這個問題,提高系統的可靠性和穩定性
限流器
限流器,從字面上理解就是用來限制流量,有時候流量突增 (可預期的比如 “雙 11”,不可預期的微博的熱門話題等),會將後端服務壓垮,甚至直接當機,使用限流器能限制訪問後端的流量,起到一個保護作用,被限制的流量,可以根據具體的業務邏輯去處理,直接返回錯誤或者返回預設值等等
golang 提供了擴充庫 (golang.org/x/time/rate
) 提供了限流器元件,用法上也很簡單直觀,通過下面這段程式碼就可以建立一個限流器
// 每 800ms 產生 1 個 token,最多快取 1 個 token,如果快取滿了,新的 token 會被丟棄
limiter := rate.NewLimiter(rate.Every(time.Duration(800)*time.Millisecond), 1)
限流器提供三種使用方式,Allow
, Wait
, Reserve
Allow
: 返回是否有 token,沒有 token 返回 false,或者消耗 1 個 token 返回 true
Wait
: 阻塞等待,知道取到 1 個 token
Reserve
: 返回 token 資訊,Allow
其實相當於 Reserve().OK
,此外還會返回需要等待多久才有新的 token
一般使用 Wait 的場景會比較多一些
if err := limiter.Wait(context.Background()); err != nil {
panic(err)
}
// do you business logic
熔斷器
和限流器對依賴服務的保護機制不一樣,熔斷器是當依賴的服務已經出現故障時,為了保證自身服務的正常執行不再訪問依賴的服務,防止雪崩效應
熔斷器有三種狀態:
-
關閉
狀態:服務正常,並維護一個失敗率統計,當失敗率達到閥值時,轉到開啟
狀態 -
開啟
狀態:服務異常,呼叫 fallback 函式,一段時間之後,進入半開啟
狀態 -
半開啟
裝態:嘗試恢復服務,失敗率高於閥值,進入開啟
狀態,低於閥值,進入關閉
狀態
github.com/afex/hystrix-go
,提供了 go 熔斷器實現,使用上面也很方便,首先建立一個熔斷器
hystrix.ConfigureCommand(
"addservice", // 熔斷器名字,可以用服務名稱命名,一個名字對應一個熔斷器,對應一份熔斷策略
hystrix.CommandConfig{
Timeout: 100, // 超時時間 100ms
MaxConcurrentRequests: 2, // 最大併發數,超過併發返回錯誤
RequestVolumeThreshold: 4, // 請求數量的閥值,用這些數量的請求來計算閥值
ErrorPercentThreshold: 25, // 錯誤數量閥值,達到閥值,啟動熔斷
SleepWindow: 1000, // 熔斷嘗試恢復時間
},
)
提供了阻塞和非阻塞兩種使用方式,完整程式碼可以參考如下連結: <https://github.com/hatlonely/hellogolang/blob/master/sample/addservice/cmd/client/main.go>
阻塞使用 Do
方法,返回一個 err
err := hystrix.Do("addservice", func() error {
// 正常業務邏輯,一般是訪問其他資源
var err error
// 設定總體超時時間 10 ms 超時
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
defer cancel()
res, err = client.Add(
ctx, req,
// 這裡可以再次設定重試次數,重試時間,重試返回碼
grpc_retry.WithMax(3),
grpc_retry.WithPerRetryTimeout(time.Duration(5)*time.Millisecond),
grpc_retry.WithCodes(codes.DeadlineExceeded),
)
return err
}, func(err error) error {
// 失敗處理邏輯,訪問其他資源失敗時,或者處於熔斷開啟狀態時,會呼叫這段邏輯
// 可以簡單構造一個response返回,也可以有一定的策略,比如訪問備份資源
// 也可以直接返回 err,這樣不用和遠端失敗的資源通訊,防止雪崩
// 這裡因為我們的場景太簡單,所以我們可以在本地在作一個加法就可以了
fmt.Println(err)
res = &addservice.AddResponse{V: req.A + req.B}
return nil
})
非阻塞方法使用 Go
方法,返回一個 error 的 channel,建議在有多個資源需要併發訪問的場景下是使用
errc1 := hystrix.Go("addservice", func() error {
var err error
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
defer cancel()
res1, err = client.Add(ctx, req)
if err == nil {
success <- struct{}{}
}
return err
}, nil)
// 有 fallback 處理
errc2 := hystrix.Go("addservice", func() error {
var err error
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(50*time.Millisecond))
defer cancel()
res2, err = client.Add(ctx, req)
if err == nil {
success <- struct{}{}
}
return err
}, func(err error) error {
fmt.Println(err)
res2 = &addservice.AddResponse{V: req.A + req.B}
success <- struct{}{}
return nil
})
for i := 0; i < 2; i++ {
select {
case <-success:
fmt.Println("success", i)
case err := <-errc1:
fmt.Println("err1:", err)
case err := <-errc2:
// 這個分支永遠不會走到,因為熔斷機制裡面永遠不會返回錯誤
fmt.Println("err2:", err)
}
}
參考連結
- 測試程式碼: <https://github.com/hatlonely/hellogolang/blob/master/sample/addservice/cmd/client/main.go>
- Circuit Breaker Pattern: <https://docs.microsoft.com/en-us/previous-versions/msp-n-p/dn589784v%3dpandp.10)(>
- hystrix-go: <https://github.com/afex/hystrix-go/>
> 轉載請註明出處 > 本文連結:<http://www.hatlonely.com/2018/06/21/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E7%BB%84%E4%BB%B6%E4%B9%8B%E9%99%90%E6%B5%81%E5%99%A8%E4%B8%8E%E7%86%94%E6%96%AD%E5%99%A8/>
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 微服務熔斷限流Hystrix之Dashboard微服務
- 微服務SpringCloud之熔斷器微服務SpringGCCloud
- 微服務熔斷限流Hystrix之流聚合微服務
- 利用Spring Boot實現微服務的API閘道器統一限流與熔斷Spring Boot微服務API
- .Net Core微服務——Ocelot(3):超時、熔斷、限流微服務
- 微服務架構 | 5.2 基於 Sentinel 的服務限流及熔斷微服務架構
- .NET Core 微服務之Polly熔斷策略微服務
- 微服務 - Nginx閘道器 · 程式機制 · 限流熔斷 · 效能最佳化 · 動態負載 · 高可用微服務Nginx負載
- 使用springcloud gateway搭建閘道器(分流,限流,熔斷)SpringGCCloudGateway
- springcloud之Hystrix熔斷器SpringGCCloud
- go-kit微服務:服務熔斷Go微服務
- springcloud3(六) 服務降級限流熔斷元件Resilience4jSpringGCCloud元件
- 微服務SpringCloud之熔斷監控Hystrix Dashboard和Turbine微服務SpringGCCloud
- 熔斷器設計模式設計模式
- 熔斷器 Hystrix 原始碼解析 —— 斷路器 HystrixCircuitBreaker原始碼UI
- Envoy熔斷限流實踐(二)Rainbond基於RLS服務全侷限流AI
- Spring Cloud Alibaba:Sentinel實現熔斷與限流SpringCloud
- SpringCloud原始碼學習之Hystrix熔斷器SpringGCCloud原始碼
- springcloud(四):熔斷器HystrixSpringGCCloud
- 微服務技術棧:流量整形演算法,服務熔斷與降級微服務演算法
- 聊聊自定義SPI如何與sentinel整合實現熔斷限流
- 面試官:說說降級、熔斷、限流面試
- Envoy熔斷限流實踐(一)基於Rainbond外掛實現熔斷AI
- 微服務分散式系統熔斷實戰-為何我們需要API級別熔斷?微服務分散式API
- 跳閘了啊! 服務容災:熔斷器簡介
- 微服務熔斷隔離機制及注意事項微服務
- Snetinel服務限流及熔斷的一些基本知識
- 重新整理 .net core 實踐篇————熔斷與限流[三十五]
- 一個故事理解限流熔斷降級
- springcloud之hystrix熔斷器-Finchley.SR2版SpringGCCloud
- SpringCloud 微服務閘道器 Gateway 元件SpringGCCloud微服務Gateway元件
- 分散式服務防雪崩熔斷器,Hystrix理論+實戰。分散式
- Sentinel入門到實操 (限流熔斷降級)
- 五. SpringCloud服務降級與熔斷SpringGCCloud
- Hystrix斷路器在微服務閘道器中的應用微服務
- 微服務11:熔斷、降級的Hystrix實現(附原始碼)微服務原始碼
- 微服務斷路器模式實現:Istio vs Hystrix微服務模式
- 《SpringCloud專題17》-Hystrix熔斷器案例SpringGCCloud