這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
hystrix是一個容錯庫,旨在隔離指向遠程系統,服務和第三方庫的請求,杜絕級聯故障,並在複雜的分布式系統中實現彈性,畢竟在分布式系統中,故障是不可避免的。
此項目脫胎於由Netflix開源的同名java項目。https://github.com/Netflix/Hystrix
像Hystrix命令一樣執行代碼
定義依賴於外部系統的應用邏輯,將函數傳給Go
。當外部系統處於健康狀態,這個函數將是唯一被執行的代碼。
hystrix.Go("my_command", func() error {// talk to other servicesreturn nil}, nil)
定義fallback行為
如果希望外部系統掛了的時候執行一些動作,可以給Go
傳遞第二個函數。理想情況下,這裡的邏輯可以讓你的應用優雅地處理外部系統停用情況。
當第一個函數返回error,或者在一系列健全狀態檢查的情況下函數無法運行結束,都會觸發fallback。更詳細的參考在這裡
hystrix.Go("my_command", func() error {// talk to other servicesreturn nil}, func(err error) error {// do this when services are downreturn nil})
等待輸出
調用Go
就像執行了一個goroutine,除了你能擷取到一個error的channel並且監控它。
output := make(chan bool, 1)errors := hystrix.Go("my_command", func() error {// talk to other servicesoutput <- truereturn nil}, nil)select {case out := <-output:// successcase err := <-errors:// failure}
同步API
調用一個借口並且等待返回是一個常見的情境(對應於goroutine),Hystrix提供了一個Do
函數,返回一個error
err := hystrix.Do("my_command", func() error {// talk to other servicesreturn nil}, nil)
配置
在應用啟動期間,你可以調用ConfigureCommand
來為每個command添加配置:
hystrix.ConfigureCommand("my_command", hystrix.CommandConfig{Timeout: 1000,MaxConcurrentRequests: 100,ErrorPercentThreshold: 25,})
也有別的配置方法,更詳細的介紹請參考官方文檔。
一個例子
最後給大家舉個例子
package mainimport ("fmt""github.com/afex/hystrix-go/hystrix""net/http""time")func main() {hystrix.Go("get_baidu", func() error {// talk to other services_, err := http.Get("https://www.baidu.com/")if err != nil {fmt.Println("get error")return err}return nil}, func(err error) error {fmt.Println("get an error, handle it")return nil}) time.Sleep(2 * time.Second) // 調用Go方法就是起了一個goroutine,這裡要sleep一下,不然看不到效果}
網路請求,大家把網路斷開後就能夠類比外部服務掛掉的情況。
總結
熔斷機制在分布式系統中幾乎是必備的組件,下面總結一下:
特點
hystrix作用在用戶端,用戶端程式依賴hystrix相關的第三方包,使得用戶端與所依賴的服務,形成隔離(goroutine的隔離)。依賴服務的延遲與失敗變的可控。保護調用者goroutine的執行。
避免了分布式系統中,單個組件的失敗導致的級聯影響。
快速失敗,迅速恢複。 hystrix有快速失敗機制,單個元件服務失敗率到一定程度後,再請求,會直接響應失敗。再這之後,會有重試機制。減少系統在錯誤服務調用上的開銷。
降級應用
hystrix的設計原則
防止任何單個依賴服務耗盡所有使用者線程
直接響應失敗,而不是一直等待
提供錯誤返回介面,而不是讓使用者線程直接處理依賴服務拋出的異常
使用隔離或熔斷技術來降低並限制單個依賴對整個系統造成的影響