Heim  >  Artikel  >  Backend-Entwicklung  >  Den Kontext in Go und GoFr verstehen und nutzen

Den Kontext in Go und GoFr verstehen und nutzen

WBOY
WBOYOriginal
2024-07-17 04:51:42650Durchsuche

Context in go

Was ist Kontext?

In Go ist das Kontextpaket ein grundlegendes Tool zum Verwalten und Teilen von anforderungsbezogenen Daten, Stornierungssignalen und Zeitüberschreitungen oder Fristen über verschiedene Ebenen einer Anwendung hinweg.
Der context.Context-Typ bietet eine Möglichkeit, Fristen, Stornierungssignale und andere anfragebezogene Werte auf verkettbare, hierarchische Weise zu übertragen. Es ist so konzipiert, dass es unveränderlich ist, was bedeutet, dass jeder neu abgeleitete Kontext die Eigenschaften seines übergeordneten Kontexts trägt und gleichzeitig neue Werte oder Verhaltensweisen hinzufügt.
Stellen Sie sich einen Kontext als eine spezielle Tragetasche vor, die alle notwendigen Informationen und Anweisungen für eine bestimmte Aufgabe enthält. Dieser Beutel kann von Funktion zu Funktion weitergegeben werden, um sicherzustellen, dass alle Beteiligten über denselben Kontext (Informationen) verfügen und entsprechend handeln können. Es kann auch eine Selbstzerstörungstaste (Abbruchsignal) enthalten, um den Vorgang bei Bedarf zu stoppen.


Warum brauchen wir Kontext?

Vor der Einführung von Context in Go war die Verwaltung anfragebezogener Daten und Stornierungssignale eine umständliche Aufgabe. Entwickler waren auf Ad-hoc-Lösungen angewiesen, etwa auf die Weitergabe benutzerdefinierter Strukturen oder die Verwendung globaler Variablen, um Daten und Signale zwischen Funktionen und Goroutinen auszutauschen. Diese Ansätze waren jedoch fehleranfällig, schwer zu warten und führten oft zu einer engen Kopplung zwischen Komponenten.
Die Notwendigkeit eines Kontexts ergibt sich aus der Tatsache, dass viele Operationen in einem Programm asynchron, gleichzeitig oder von externen Systemen abhängig sind. In solchen Fällen ist es wichtig, eine Möglichkeit zu haben, Stornierungssignale, Fristen und anfragebezogene Daten über mehrere Funktionen und Goroutinen hinweg zu verbreiten.

Betrachten wir einige Szenarien, um die Notwendigkeit eines Kontexts zu veranschaulichen:

1. Die Restaurant-Analogie

Stellen Sie sich vor, Sie wären die Person, die in einem geschäftigen Restaurant Bestellungen entgegennimmt. Wenn eine Bestellung eintrifft, weisen Sie sie einem Ihrer erfahrenen Köche zu. Was aber, wenn sich der Kunde plötzlich zum Abschied entschließt? Ohne zu zögern würden Sie den Koch anweisen, die Bearbeitung dieser Bestellung einzustellen, um eine Verschwendung von Zutaten zu vermeiden. Dieses Szenario spiegelt die Funktionsweise des Kontexts in Go wider.

  • Stornierungsausbreitung: In der Restaurant-Analogie entspricht der Weggang des Kunden einem Stornierungssignal. Ebenso ermöglicht der Kontext in Go die elegante Ausbreitung von Abbruchsignalen. Wenn ein übergeordneter Vorgang (z. B. ein HTTP-Request-Handler) abgebrochen wird, werden alle zugehörigen untergeordneten Vorgänge (z. B. Datenbankabfragen oder API-Aufrufe) sofort beendet. Dies verhindert Ressourcenlecks und sorgt für eine effiziente Bereinigung.

2. Umgang mit langsamen APIs und Zeitüberschreitungen

Angenommen, Ihre Anwendung stellt Webanfragen an externe APIs oder führt Systembefehle aus. In Produktionssystemen ist es wichtig, Zeitüberschreitungen festzulegen. Hier ist der Grund:

  • API-Abhängigkeit: Stellen Sie sich vor, Ihr Dienst ist auf eine externe API angewiesen. Wenn diese API langsam läuft oder nicht mehr reagiert, möchten Sie nicht, dass Ihr System mit ausstehenden Anfragen ein Backup erstellt. Eine Zeitüberschreitung stellt sicher, dass der zugehörige Kontext abgebrochen wird, wenn der API-Aufruf eine bestimmte Dauer überschreitet, sodass Ihre Anwendung die Situation ordnungsgemäß bewältigen kann.

  • Leistungsabfall: Ohne Zeitüberschreitungen, langsame externe
    Abhängigkeiten können zu einem Kaskadeneffekt führen. Rückständige Anfragen erhöhen die Auslastung, verschlechtern die Leistung und beeinträchtigen die Reaktionsfähigkeit des Gesamtsystems. Durch die Verwendung von Kontext mit Fristen können Sie dieses Problem verhindern.



Verwendung des Kontexts:

Das Kontextpaket in Go ist vielseitig und wird in verschiedenen Szenarien verwendet, um anforderungsbezogene Daten, Abbruchsignale und Zeitüberschreitungen zu verwalten.

Hier sind einige häufige Anwendungsfälle aus der Praxis:

1. Weitergabe von Trace-IDs über verteilte Dienste hinweg
In einer Microservices-Architektur ist die Verfolgung von Anforderungen über verschiedene Dienste hinweg für die Überwachung und Fehlerbehebung von entscheidender Bedeutung. Mit dem Kontextpaket können Sie Ablaufverfolgungs-IDs und andere Metadaten über Dienstgrenzen hinweg weitergeben und so eine konsistente Protokollierung und Ablaufverfolgungsinformationen während des gesamten Lebenszyklus der Anfrage sicherstellen.

2. Weitergabe von Authentifizierungstoken
In vielen Anwendungen müssen Authentifizierungstoken oder Benutzerinformationen durch verschiedene Ebenen der Anwendung geleitet werden. Das Kontextpaket bietet eine saubere Möglichkeit, dies zu handhaben und stellt sicher, dass Authentifizierungsinformationen dort verfügbar sind, wo sie benötigt werden, ohne Funktionssignaturen mit zusätzlichen Parametern zu verunreinigen.

3. WebSocket- und Streaming-APIs
In WebSocket- und Streaming-APIs wird Kontext verwendet, um die Lebensdauer der Verbindung zu verwalten und anforderungsbezogene Daten wie die Benutzer-ID und Sitzungsinformationen weiterzugeben. Dadurch können Sie Funktionen wie Authentifizierung, Ratenbegrenzung und Sitzungsverwaltung effizient implementieren.


Verschiedene Arten von Kontext in Go:

Das Kontextpaket in Go bietet mehrere Möglichkeiten zum Erstellen und Bearbeiten von Kontextobjekten. Hier ist eine Aufschlüsselung der häufig verwendeten Typen:

1. Hintergrundkontext/TODO-Kontext

Dies ist der grundlegendste Kontext und dient als leerer Ausgangspunkt. Es enthält kein Kündigungssignal oder eine Kündigungsfrist. Verwenden Sie es, wenn kein spezifischer Kontext erforderlich ist.
TODO wird nur dann anstelle von Background verwendet, wenn die Implementierung unklar ist oder der Kontext noch nicht bekannt ist.

Wird normalerweise in Hauptfunktionen, Initialisierung und Tests verwendet.

ctx := context.Background()
ctx2 := context.TODO()

2. context.WithCancel

Erstellt einen neuen Kontext, der von einem übergeordneten Kontext abgeleitet ist. Die WithCancel-Methode gibt eine Kopie des übergeordneten Kontexts zusammen mit einer Abbruchfunktion zurück. Durch den Aufruf der Abbruchfunktion werden mit dem Kontext verbundene Ressourcen freigegeben und sollten aufgerufen werden, sobald Vorgänge im Kontexttyp endgültig abgeschlossen sind.

Wird verwendet, um Vorgänge in einer Goroutine abzubrechen, wenn bestimmte Bedingungen erfüllt sind.

parentCtx := context.Background()
ctx, abbrechen := context.WithCancel(parentCtx)
defer cancel() // Ressourcen bereinigen

3. context.WithDeadline

Ähnlich wie man sich selbst eine Frist setzt, kann man auch eine Frist für den Kontext setzen. Go bricht den Kontext automatisch für Sie ab, wenn das von Ihnen angegebene Zeitlimit für den Abschluss erreicht ist. Es erstellt einen neuen Kontext, der von einem übergeordneten Kontext mit einer bestimmten Frist abgeleitet ist.

Nützlich, wenn Sie eine bestimmte Frist für den Abschluss eines Vorgangs haben.

parentCtx := context.Background()
Frist := time.Now().Add(10 * time.Second)
ctx, abbrechen := context.WithDeadline(parentCtx, Deadline)
defer cancel() // Ressourcen bereinigen

4. context.WithValue

Erstellt einen neuen Kontext, der von einem übergeordneten Kontext mit einem zugehörigen Schlüssel-Wert-Paar abgeleitet wird. Dadurch können Sie anforderungsspezifische Informationen im Kontext speichern und abrufen. WithValue akzeptiert einen übergeordneten Kontext und gibt eine Kontextkopie zurück. Dadurch wird der Wert nicht überschrieben, sondern ein neues Duplikat mit einem neuen Schlüssel-Wert-Paar erstellt.

Nützlich für die Weitergabe anforderungsbezogener Daten durch den Kontext, z. B. Authentifizierungstokens oder Trace-IDs.

parentCtx := context.Background()
userIDKey := "auth-token"
ctx := context.WithValue(parentCtx, userIDKey, "abc123")

5. context.WithTimeout

Erstellt einen Kontext mit einem zugehörigen Timeout. Der Kontext wird nach der angegebenen Dauer automatisch abgebrochen. WithTimeout ermöglicht es einem Programm, dort fortzufahren, wo es sonst hängen bleiben würde, was dem Endbenutzer ein besseres Erlebnis bietet. Es akzeptiert einen kurzen Zeitraum als Parameter zusammen mit dem übergeordneten Kontext und beendet die Funktion, wenn sie über den Timeout-Zeitraum hinaus ausgeführt wird.

Nützlich zum Festlegen von Fristen für Vorgänge.

parentCtx := context.Background()
ctx, cancel := context.WithTimeout(parentCtx, 5*time.Second)
defer cancel() // Ressourcen bereinigen

Different types of context in Golang



GoFr-Kontext: Supergeladener Kontext für Go-Anwendungen

Nachdem wir nun die Macht des Kontexts in Go erkundet haben, wollen wir uns damit befassen, wie GoFr mit GoFr Context noch einen Schritt weiter geht.

GoFr ist ein eigenwilliges Microservices-Entwicklungsframework, das auf Go aufbaut. Ziel ist es, den Entwicklungsprozess zu rationalisieren, indem ein strukturierter Ansatz zum Aufbau robuster und skalierbarer Microservices bereitgestellt wird.

GoFr Context erweitert die Funktionalität des Standard-Go-Kontextpakets auf wunderbare Weise, indem es einen Wrapper darum erstellt. Dieser Wrapper bietet einen umfangreichen Satz vorkonfigurierter Abhängigkeiten, auf die direkt über das Kontextobjekt zugegriffen werden kann. Dieser vollständig geladene Kontext ermöglicht Entwicklern den nahtlosen Zugriff auf Protokollierung, Datenbankverbindungen, zugrunde liegende Dienste, Ablaufverfolgungen und Metriken – alles über ein einziges Kontextobjekt.

Beispiel

func MyHandler(c *gofr.Context) (interface{}, error) {
  // Logging
  c.Info("Processing request...")

  // Database access
  var value int
  err := c.SQL.QueryRowContext(c, "select 2+2").Scan(&value)
  if err != nil {
    return nil, datasource.ErrorDB{Err: err, Message: "error from sql db"}
  }

  // Accessing another service
  resp, err := c.GetHTTPService("anotherService").Get(c, "book", nil)
  if err != nil {
    return nil, err
  }

  // Creating a tracing span
  span := c.Trace("some-sample-work")
  defer span.End()
  // ... perform some work

  return value, nil
}

Beachten Sie in diesem Beispiel, wie wir direkt über das GoFr-Kontextobjekt auf Funktionen wie Protokollierung (c.Info), Datenbankinteraktion (c.SQL), Dienstaufrufe (c.GetHTTPService) und Ablaufverfolgung (c.Trace) zugreifen können (c).

Der GoFr-Kontext ist in allen HTTP-Handlern verfügbar und verbessert die Entwicklungserfahrung erheblich, indem er eine zentrale Möglichkeit zur Verwaltung verschiedener Aspekte der Anwendung bietet. Diese Integration stellt sicher, dass sich Entwickler auf die Geschäftslogik konzentrieren und gleichzeitig die Fähigkeiten von GoFr für ein effektives Kontextmanagement nutzen können.


Abschluss

Wenn es um Programmdesign geht, ist das Golang-Kontextpaket ein äußerst nützliches Werkzeug. Context in Go dient als leistungsstarkes Tool zur Verwaltung von anfragebezogenen Daten, Stornierungssignalen und Fristen. Unabhängig davon, ob Sie Microservices, APIs oder Webanwendungen erstellen, sorgt der Kontext für eine saubere Ressourcenverwaltung und konsistentes Verhalten.

Schauen Sie sich GoFr und sein Github Repo an und unterstützen Sie es, indem Sie ihm ein ⭐ geben.

Das obige ist der detaillierte Inhalt vonDen Kontext in Go und GoFr verstehen und nutzen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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