Heim >Backend-Entwicklung >Golang >So verwenden Sie den Kontext, um den Anforderungsschutzschalter in Go zu implementieren

So verwenden Sie den Kontext, um den Anforderungsschutzschalter in Go zu implementieren

WBOY
WBOYOriginal
2023-07-25 09:04:541425Durchsuche

So verwenden Sie den Kontext, um den Anforderungsschutzschalter in Go zu implementieren

Mit der Popularität der Microservice-Architektur ist die Kommunikation zwischen verschiedenen Diensten immer häufiger geworden. Bei der Kommunikation zwischen Diensten kann die Anrufkette sehr lang sein, und der Ausfall oder die Zeitüberschreitung einer Anforderung kann dazu führen, dass die gesamte Anrufkette fehlschlägt und somit die Verfügbarkeit des gesamten Systems beeinträchtigt wird. Um das gesamte System vor dem Ausfall eines einzelnen Dienstes zu schützen, können wir den Zugriff auf einen bestimmten Dienst mithilfe von Request Circuit Breaking steuern und beschränken. In diesem Artikel wird erläutert, wie Sie mithilfe des Kontexts den Anforderungsschutzschalter in Go implementieren.

Was ist ein Leistungsschalter?

Die Anforderung einer Stromkreisunterbrechung ist eine Strategie zum Schutz des gesamten Systems. Wenn die Anforderungsfehlerrate eines Dienstes einen vorgegebenen Schwellenwert überschreitet, verweigert der Anforderungsschutzschalter schnell den Zugriff auf den Dienst und verhindert so das Auftreten kaskadierender Fehler. Der Anforderungsschaltermodus wird normalerweise in Kombination mit dem Leistungsschaltermodus (Leistungsschaltermuster) verwendet. Wenn eine Anforderung fehlschlägt, wird der Leistungsschalter schnell geöffnet, wodurch Anforderungen für den Dienst abgelehnt und verhindert werden, dass sich eine große Anzahl von Anforderungen anhäuft was zu einer Erschöpfung der Systemressourcen führt.

Der Beispielcode für die Verwendung von Kontext zum Implementieren eines Anforderungs-Leistungsschalters in Go lautet wie folgt:

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

type CircuitBreaker struct {
    context    context.Context
    cancel     context.CancelFunc
    maxFail    int
    fail       int
    breaker    bool
    resetTime  time.Duration
    breakerMux sync.Mutex
}

func NewCircuitBreaker(maxFail int, resetTime time.Duration) *CircuitBreaker {
    ctx, cancel := context.WithCancel(context.Background())

    circuitBreaker := &CircuitBreaker{
        context:    ctx,
        cancel:     cancel,
        maxFail:    maxFail,
        fail:       0,
        breaker:    false,
        resetTime:  resetTime,
        breakerMux: sync.Mutex{},
    }

    return circuitBreaker
}

func (c *CircuitBreaker) Do(req func() error) error {
    select {
    case <-c.context.Done():
        return fmt.Errorf("circuit breaker is open")
    default:
        if !c.breaker {
            err := req()
            if err == nil {
                c.reset()
            } else {
                c.fail++
                if c.fail >= c.maxFail {
                    c.breakerMux.Lock()
                    c.breaker = true
                    c.breakerMux.Unlock()
                    go time.AfterFunc(c.resetTime, c.reset)
                }
            }
            return err
        } else {
            return fmt.Errorf("circuit breaker is open") 
        }
    }
}

func (c *CircuitBreaker) reset() {
    c.fail = 0
    c.breakerMux.Lock()
    c.breaker = false
    c.breakerMux.Unlock()
    c.cancel()
}

func main() {
    circuitBreaker := NewCircuitBreaker(3, 2*time.Minute)

    // 进行模拟请求
    for i := 0; i < 10; i++ {
        err := circuitBreaker.Do(func() error {
            // 这里执行实际的请求操作,此处只是模拟
            fmt.Println("执行请求...")
            if i%5 == 0 {
                return fmt.Errorf("request failed")
            }
            return nil
        })

        if err != nil {
            fmt.Printf("请求失败: %v
", err)
        } else {
            fmt.Println("请求成功")
        }
    }
}

Im obigen Beispielcode haben wir einen einfachen Anforderungs-Leistungsschalter über die CircuitBreaker-Struktur implementiert. Die CircuitBreaker-Struktur verfügt über die folgenden Attribute:

  • context und cancel: werden zur Steuerung des Lebenszyklus des Anforderungsschalters verwendet. Nachdem die Sicherung geöffnet wurde, wird die Anforderung abgelehnt.
  • maxFail: Legen Sie die maximale Anzahl von Ausfällen fest. Wenn die Anzahl der Ausfälle den eingestellten Wert überschreitet, öffnet sich die Sicherung.
  • fail: Notieren Sie die Anzahl der fehlgeschlagenen Anfragen.
  • Unterbrecher: Notieren Sie den Status der Sicherung. Wenn dieser Wert wahr ist, bedeutet dies, dass die Sicherung offen ist.
  • resetTime: Sicherungs-Reset-Zeit Nach dem Öffnen der Sicherung wird die Sicherung nach dieser Zeit wieder geschlossen.

Sie können bestimmte Anforderungsvorgänge über die Do-Methode ausführen. Wenn die Anforderung erfolgreich ist, wird der Fehlerzähler zurückgesetzt und Null zurückgegeben. Wenn die Anforderung fehlschlägt, wird die Fehleranzahl erhöht, und wenn die Fehleranzahl den eingestellten Wert erreicht, wird die Sicherung geöffnet.
Es ist zu beachten, dass beim Öffnen der Sicherung bei neuen Anfragen sofort Fehlerinformationen zurückgegeben werden.

In der Hauptfunktion haben wir einen Beispiel-CircuitBreaker erstellt und 10 Anfragen simuliert. Wenn die Anzahl der Ausfälle den eingestellten Wert erreicht, öffnet sich die Sicherung und neue Anfragen werden abgelehnt.

Durch die Verwendung des Kontextpakets und der benutzerdefinierten CircuitBreaker-Struktur können wir die Anforderungsschalterfunktion problemlos in Go implementieren. Durch den Einsatz eines Anforderungsschutzschalters kann das gesamte System wirksam vor den Auswirkungen eines einzelnen Dienstausfalls geschützt und die Verfügbarkeit und Stabilität des Systems verbessert werden.

Das obige ist der detaillierte Inhalt vonSo verwenden Sie den Kontext, um den Anforderungsschutzschalter in Go zu implementieren. 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