如今,我們的應用程式具有多個相依性是很常見的,尤其是在微服務環境中工作時。當我們的應用程式報告錯誤時,我們發現一個依賴項已關閉,這種情況並不罕見。
提高我們恢復能力的一個好習慣是關閉與那些表現不佳的應用程式的溝通。看看其他領域,我們從電氣工程中學到了斷路器的概念,即當發生故障時開關會關閉。在巴西,所有房屋都有這些開關,如果我們的電網不穩定,這些開關會自動關閉。
在電腦科學中,我們的斷路器有點複雜,因為它也有一個中間狀態。下圖詳細解釋了它的工作原理:
簡而言之,可能的狀態有:
很酷,對吧?為了更好地解釋這個概念,為什麼不創建一個呢?
首先,讓我們建構我們的服務A。它將負責接收所有請求,換句話說,它將是我們的主應用程式所依賴的服務。為了簡化,我們將公開兩個端點:始終響應 200 的 /success 和始終響應 500 的 /failure。
package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/success", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) http.HandleFunc("/failure", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) }) fmt.Println("Server is running at http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) }
我們的服務 B 將負責呼叫服務 A 並建立我們的斷路器。 Go 社群已經擁有已經實現了該模式的 lib gobreaker。首先,我們定義斷路器屬性:
var st gobreaker.Settings st.Name = "Circuit Breaker PoC" st.Timeout = time.Second * 5 st.MaxRequests = 2 st.ReadyToTrip = func(counts gobreaker.Counts) bool { return counts.ConsecutiveFailures >= 1 }
即使該函式庫允許我們自訂更多屬性,我們只會專注於三個:
現在我們只需啟動斷路器並發送請求:
cb := gobreaker.NewCircuitBreaker[int](st) url := "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // closed! url = "http://localhost:8080/failure" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // open! time.Sleep(time.Second * 6) url = "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // half-open! url = "http://localhost:8080/success" cb.Execute(func() (int, error) { return Get(url) }) fmt.Println("Circuit Breaker state:", cb.State()) // closed!
我們可以注意到 gobreaker 的工作原理就像函數的包裝器。如果函數傳回錯誤,則會增加失敗計數器,如果沒有回傳錯誤,則會增加成功計數器。讓我們定義該函數:
func Get(url string) (int, error) { r, _ := http.Get(url) if r.StatusCode != http.StatusOK { return r.StatusCode, fmt.Errorf("failed to get %s", url) } return r.StatusCode, nil }
這就是我們如何擁有一個帶有斷路器的 Go 應用程式!使用此模式時,您可以透過提高應用程式對依賴項故障的容忍度來提高應用程式的彈性。此外,使用這個函式庫消除了大部分複雜性,使得我們更容易在日常應用程式中採用該模式。如果您想查看此概念驗證的程式碼,請在此處查看。
如果您仍然對其他彈性模式感到好奇,Elton Minetto 也發表了一篇關於它的精彩部落格文章!
您也可以在我的個人部落格上查看這篇文章和其他貼文。請在評論中告訴我您對這篇文章的看法,並提出一個問題:您以前使用過斷路器嗎?
以上是Go 應用程式中的斷路器的詳細內容。更多資訊請關注PHP中文網其他相關文章!