Heutzutage ist es durchaus üblich, dass unsere Anwendung von anderen abhängig ist, insbesondere wenn wir in einer Microservices-Umgebung arbeiten. Es kommt durchaus vor, dass unsere Anwendung Fehler meldet und wir bei der Untersuchung feststellen, dass eine API eines Partnerteams oder Lieferanten ausgefallen ist.
Eine gute Vorgehensweise zur Erhöhung der Ausfallsicherheit unserer Anwendung besteht darin, die Kommunikation mit Anwendungen zu unterbrechen, die sich in einem veralteten Zustand befinden. Bei der Betrachtung anderer Bereiche übernehmen wir das Konzept des Leistungsschalters aus der Elektrotechnik. Darin ist ein Gerät oder ein Leistungsschalter untergebracht, der sich bei einem Fehler automatisch abschaltet. Dies ist in unseren Häusern sehr häufig der Fall, denn dort gibt es Schutzschalter, die sich von selbst ausschalten, wenn das Stromnetz instabil wird.
In der Informatik ist unser Circuit Breaker etwas komplexer, da wir auch einen Zwischenzustand definieren. Die folgende Zeichnung erklärt besser, wie ein Leistungsschalter funktioniert:
Schließlich sind die Staaten:
Ziemlich cool, oder? Aber um das Konzept besser zu veranschaulichen, wie wäre es, wenn wir es in die Praxis umsetzen?
Erstens bauen wir unseren Dienst A auf. Er ist für den Empfang von Anfragen verantwortlich, d. h. es handelt sich um den Dienst, von dem unsere Anwendung abhängt, den Dienst des Lieferanten usw. Zur Vereinfachung stellen wir zwei Endpunkte bereit, einen /success, der immer 200 zurückgibt, und einen /failure, der immer 500 zurückgibt.
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)) }
Service B ist dafür verantwortlich, Service A anzurufen. Er wird unseren Leistungsschalter bauen. Zum Glück verfügt die Go-Community bereits über die Gobreaker-Bibliothek, die das Muster implementiert! Zuerst definieren wir die Eigenschaften unseres Leistungsschalters:
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 }
Obwohl wir mit der Bibliothek noch mehr Dinge individuell anpassen können, konzentrieren wir uns auf drei:
Dann können wir den Leistungsschalter initialisieren und Anfragen stellen:
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!
Wir können feststellen, dass Gobreaker als Wrapper um eine Funktion fungiert. Wenn die Funktion einen Fehler zurückgibt, erhöht sie die Anzahl der Fehler, andernfalls erhöht sie die Anzahl der Erfolge. Definieren wir also diese Funktion:
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 }
Und wir haben unseren Go-Service mit Leistungsschalter! Durch die Verwendung dieses Musters können Sie die Ausfallsicherheit und Fehlertoleranz Ihrer Dienste erhöhen. Wir können feststellen, dass bei der Nutzung der Bibliothek die Komplexität vollständig abstrahiert wurde, was den Prozess der Integration in unser tägliches Leben sehr einfach macht. Wenn Sie den gesamten Proof-of-Concept-Code sehen möchten, klicken Sie einfach hier.
Wenn Sie neugierig sind und mehr über andere Resilienzmuster erfahren möchten, hat Elton Minetto einen tollen Beitrag zu diesem Thema veröffentlicht!
Sagen Sie mir in den Kommentaren, was Sie von diesem Beitrag halten, und hier ist eine Frage: Haben Sie schon einmal Schutzschalter verwendet? Oh, Sie können mich auch auf meinem persönlichen Blog finden!
Das obige ist der detaillierte Inhalt vonLeistungsschalter in Go-Anwendungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!