隨着微服務的流行,服務之間的調用可能變得越來越復雜,一個業務流程可能需要調用五六個甚至更多服務,這就會導致,假設某個服務出現問題,嚴重可能出現服務器負載過高,導致服務雪崩的現象。
因此為了防止此現象的發生,決定了解下服務熔斷機制,根據自身業務的需求,將其應用到服務中。
什么是熔斷:可以聯想到我們家里的電表的保險絲,當電壓負載過高后,保險絲熔斷,確保家里的電器等其他安全。
在我們的服務中,當我們當用第三方服務時失敗到達一定的失敗次數或者超時等問題時,我們將熔斷機制融入到我們的客戶端調用方,當失敗次數等達到閾值時,開啟熔斷器,及時進行彌補處理,或者給上層友好提示。
在熔斷器中有三種狀態:
-
關閉:讓請求通過的默認狀態。如果請求成功/失敗但低於閾值,則狀態保持不變。可能出現的錯誤是超過最大並發數和超時錯誤。
-
打開:當熔斷器打開的時候,所有的請求都會被標記為失敗;這是故障快速失敗機制,而不需要等待超時時間完成。
-
半開:定期的嘗試發起請求來確認系統是否恢復。如果恢復了,熔斷器將轉為關閉狀態或者保持打開
hystrix內部處理邏輯
go-hystrix example:
package main import ( "fmt" "github.com/afex/hystrix-go/hystrix" "net/http" "time" ) func main() { hystrix.ConfigureCommand("get_baidu", hystrix.CommandConfig{ 500, 100, 50, 3, 1000, }) for i:=0; i<100; i++ { TestHystix() time.Sleep(1*time.Second) } time.Sleep(2 * time.Second) // 調用Go方法就是起了一個goroutine,這里要sleep一下,不然看不到效果 } func TestHystix() { // 根據自身業務需求封裝到http client調用處 hystrix.Go("get_baidu", func() error { // 調用關聯服務 res, err := http.Get("https://www.baidu.com/") if err != nil { fmt.Println("get error") return err } fmt.Println("請求成功:",res.Status) return nil }, // 失敗重試,降級等具體操作 func(err error) error { fmt.Println("get an error, handle it") return nil }) }