Leistungsschalter in Go-Anwendungen

PHPz
Freigeben: 2024-08-27 21:31:56
Original
592 Leute haben es durchsucht

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:

Circuit Breaker em aplicações Go

Schließlich sind die Staaten:

  • offen: Es findet keine Kommunikation zwischen Anwendungen statt. Bei Erreichen dieses Zustands startet ein Timer, um Zeit für den Rücksetzdienst einzuräumen. Am Ende des Timers gehen wir in den halboffenen Zustand über.
  • geschlossen: Es findet Kommunikation zwischen Anwendungen statt. Für jede fehlgeschlagene Anfrage wird ein Zähler aktualisiert. Wenn die Fehlergrenze erreicht ist, schalten wir den Stromkreis auf „Offen“.
  • halboffen: Erholungszustand, bis die Kommunikation vollständig fließen kann. Darin wird bei jeder Anfrage ein Erfolgszähler aktualisiert. Wenn die ideale Erfolgszahl erreicht ist, stellen wir den Kreislauf auf geschlossen. Wenn Anfragen fehlschlagen, kehren wir zum offenen Zustand zurück.

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))
}
Nach dem Login kopieren

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
}
Nach dem Login kopieren

Obwohl uns die Bibliothek die Anpassung weiterer Dinge ermöglicht, konzentrieren wir uns auf drei:

  • Timeout: Die Zeit, die der Stromkreis im offenen Zustand bleibt. In unserem Fall wurde die Zeit auf 5 Sekunden eingestellt.
  • MaxRequests: Anzahl erfolgreicher Anfragen, bevor sie geschlossen werden. In unserem Beispiel haben wir es auf 2 Anfragen eingestellt.
  • ReadyToTrip: Definiert die Bedingung für den Übergang von geschlossen nach offen. Um es einfacher zu machen, nehmen wir an, ein Fehler reicht aus.

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!
Nach dem Login kopieren

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
}
Nach dem Login kopieren

Und wir haben unseren Go-Service mit einem 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, andere Resilienzmuster kennenzulernen, 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 Leistungsschalter 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!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!