Heutzutage ist es üblich, dass unsere Anwendungen einige Abhängigkeiten aufweisen, insbesondere wenn sie in einer Microservice-Umgebung arbeiten. Wenn unsere App Fehler meldet, kommt es nicht selten vor, dass wir feststellen, dass eine Abhängigkeit ausgefallen ist.
Eine gute Vorgehensweise zur Verbesserung unserer Widerstandsfähigkeit besteht darin, die Kommunikation mit Apps zu unterbrechen, die sich nicht gut verhalten. Als wir uns in anderen Bereichen umschauten, lernten wir das Konzept von Leistungsschaltern aus der Elektrotechnik kennen, bei denen ein Schalter ausschaltet, wenn ein Fehler auftritt. In Brasilien verfügen alle Häuser über diese Schalter, die sich automatisch abschalten, wenn unser Stromnetz instabil wird.
In der Informatik ist unser Leistungsschalter etwas komplexer, da er auch einen Zwischenzustand hat. Die folgende Zeichnung erklärt mehr über die Funktionsweise:
Kurz gesagt sind die möglichen Zustände:
Ziemlich cool, oder? Um das Konzept besser zu erklären, warum erstellen Sie nicht eines?
Erstens bauen wir unseren Dienst A auf. Er wird für den Empfang aller Anfragen verantwortlich sein, mit anderen Worten, es wird der Dienst sein, von dem unsere Haupt-App abhängt. Zur Vereinfachung stellen wir zwei Endpunkte bereit: einen /success, der immer mit 200 antwortet, und einen /failure, der immer mit 500 antwortet.
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)) }
Unser Service B wird für den Anruf von Service A verantwortlich sein und unseren Leistungsschalter bauen. Die Go-Community verfügt bereits über den lib gobreaker, der das Muster bereits implementiert. Zunächst definieren wir unsere Breaker-Eigenschaften:
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 uns die Bibliothek die Anpassung weiterer Eigenschaften ermöglicht, konzentrieren wir uns auf nur drei:
Jetzt initialisieren wir einfach den Breaker und senden die Anfragen:
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 wie ein Wrapper um eine Funktion funktioniert. Wenn die Funktion einen Fehler zurückgibt, erhöht sie den Fehlerzähler, andernfalls erhöht sie den Erfolgszähler. Definieren wir 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 so können wir eine Go-App mit Schutzschalter haben! Wenn Sie dieses Muster verwenden, können Sie die Ausfallsicherheit Ihrer App erhöhen, indem Sie sie toleranter gegenüber Fehlern aus Ihren Abhängigkeiten machen. Außerdem wurde durch die Verwendung dieser Bibliothek ein Großteil der Komplexität beseitigt, wodurch es einfacher wurde, das Muster in unsere alltäglichen Apps zu übernehmen. Wenn Sie den Code dieses Proof of Concept sehen möchten, sehen Sie ihn sich hier an.
Wenn Sie immer noch neugierig auf andere Resilienzmuster sind: Elton Minetto hat auch einen tollen Blogbeitrag darüber veröffentlicht!
Sie können diesen und andere Beiträge auch auf meinem persönlichen Blog lesen. Sagen Sie mir in den Kommentaren, was Sie von diesem Blogbeitrag halten, und stellen Sie mir eine Frage: Haben Sie schon einmal Leistungsschalter verwendet?
Das obige ist der detaillierte Inhalt vonLeistungsschalter in Go-Apps. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!