Cache die Ausführungsergebnisse von Anfragen

GolangBeginner
Jetzt üben

Einführung

In diesem Projekt lernst du, wie du eine Caching-Bibliothek implementierst, die die Ablaufzeit basierend auf dem singleflight-Paket in Go unterstützt. Diese Caching-Bibliothek kann in verteilten Systemen verwendet werden, um die Ausführungsergebnisse von Anfragen zu cachen und die Leistung deiner Anwendung zu verbessern.

👀 Vorschau

$ /usr/local/go/bin/go test --race
PASS
ok      cacheflight     1.263s

🎯 Aufgaben

In diesem Projekt wirst du lernen:

  • Wie du ein Go-Modul initialisierst und die erforderlichen Pakete installierst
  • Wie du die Caching-Bibliothek mit dem singleflight-Paket implementierst
  • Wie du die Caching-Bibliothek testest, um sicherzustellen, dass sie wie erwartet funktioniert

🏆 Errungenschaften

Nach Abschluss dieses Projekts wirst du in der Lage sein:

  • Die grundlegenden Konzepte von Caching und dem singleflight-Paket in Go zu verstehen
  • Eine Caching-Bibliothek zu implementieren, die die Ablaufzeit unterstützt
  • Die Caching-Bibliothek in dein verteiltes System zu integrieren, um die Leistung deiner Anwendung zu verbessern

Initialisiere das Modul und installiere die erforderlichen Pakete

In diesem Schritt lernst du, wie du das Modul initialisierst und die erforderlichen Pakete für das Projekt installierst.

  1. Öffne das Terminal im Verzeichnis /home/labex/project.

  2. Initialisiere das Modul mit dem folgenden Befehl:

    /usr/local/go/bin/go mod init cacheflight
    
  3. Installiere die erforderlichen Pakete mit den folgenden Befehlen:

    /usr/local/go/bin/go get github.com/golang/groupcache/singleflight
    /usr/local/go/bin/go get github.com/stretchr/testify/assert
    

Implementiere die Caching-Bibliothek

In diesem Schritt wirst du die Caching-Bibliothek basierend auf dem singleflight-Paket implementieren.

  1. Öffne die Datei cacheflight.go im Verzeichnis /home/labex/project.

  2. Füge den notwendigen Inhalt zu import hinzu.

    import (
        "sync"
        "time"
    
        "github.com/golang/groupcache/singleflight"
    )
    
  3. Füge den notwendigen Inhalt zu type Group und type cacheResult hinzu.

    // cacheResult ist das Cachergebnis
    type cacheResult struct {
        data      interface{} // die Cachedaten
        ctime     time.Time   // Cache-Erstellungszeit
        isRunning chan bool   // Läuft die Funktion?
    }
    
    // Group ist die Kernstruktur
    type Group struct {
        cacheExpiration time.Duration          // Cacheablaufzeit
        sfg             *singleflight.Group    // singleflight-Gruppe
        cache           map[string]cacheResult // Cachergebnisse
        mu              sync.Mutex             // Mutex
    }
    
  4. Implementiere die NewGroup-Funktion, um eine neue Caching-Gruppe mit der angegebenen Cacheablaufzeit zurückzugeben.

    func NewGroup(cacheExpiration time.Duration) (group *Group) {
        group = &Group{
            sfg:             &singleflight.Group{},
            cache:           make(map[string]cacheResult),
            cacheExpiration: cacheExpiration,
        }
        return
    }
    
  5. Implementiere die do-Funktion, um die Caching-Logik zu behandeln.

    func (g *Group) do(key string, fn func() (interface{}, error)) (ret interface{}, err error) {
        return g.sfg.Do(key, func() (interface{}, error) {
            g.mu.Lock()
            result, ok := g.cache[key]
            if result.isRunning!= nil {
                g.mu.Unlock()
                // Warte auf die Fertigstellung von fn
                <-result.isRunning
                return g.do(key, fn)
            } else if!ok || result.ctime.Add(g.cacheExpiration).Before(time.Now()) {
                // Wenn der Cache nicht existiert oder abgelaufen ist
                var run = make(chan bool)
                result.isRunning = run
                g.cache[key] = result
                // Wenn fn abgeschlossen ist und der run-Kanal geschlossen wird, können andere Goroutinen den Cache abrufen
                defer close(run)
            } else {
                // Wenn der Cache existiert und nicht abgelaufen ist
                g.mu.Unlock()
                return result.data, nil
            }
    
            g.mu.Unlock()
    
            // Verschiedene Schlüssel können gleichzeitig ausgeführt werden
            ret, err = fn()
            if err!= nil {
                return ret, nil
            }
    
            result = cacheResult{
                data:  ret,
                ctime: time.Now(),
            }
            g.mu.Lock()
            g.cache[key] = result
            g.mu.Unlock()
    
            return ret, nil
        })
    }
    
  6. Implementiere die Do-Funktion als Umhüllung um die do-Funktion.

    func (g *Group) Do(key string, fn func() (interface{}, error)) (ret interface{}, err error) {
        return g.do(key, fn)
    }
    

Teste die Caching-Bibliothek

In diesem Schritt wirst du die Caching-Bibliothek testen, um sicherzustellen, dass sie wie erwartet funktioniert.

  1. Öffne das Terminal im Verzeichnis /home/labex/project.

  2. Führe den folgenden Befehl aus, um die Tests auszuführen:

    cd /home/labex/project
    /usr/local/go/bin/go test --race
    
  3. Wenn die Cache-Funktion richtig implementiert wurde, wirst du die folgende Ausgabe sehen:

    PASS
    ok      cacheflight     1.263s
    
  4. Wenn du einen Timeout-Fehler erhältst, führe die folgenden Befehle im Terminal aus und klicke dann auf die Schaltfläche "Wieder überprüfen", um die Prüfung zu bestehen:

    cd /home/labex/project
    /usr/local/go/bin/go test --race
    

Herzlichen Glückwunsch! Du hast erfolgreich die Caching-Bibliothek basierend auf dem singleflight-Paket implementiert. Du kannst jetzt diese Bibliothek in deinem verteilten System verwenden, um die Ausführungsergebnisse von Anfragen zu cachen und die Leistung deiner Anwendung zu verbessern.

Zusammenfassung

Herzlichen Glückwunsch! Du hast dieses Projekt abgeschlossen. Du kannst in LabEx weitere Übungen absolvieren, um deine Fähigkeiten zu verbessern.

✨ Lösung prüfen und üben✨ Lösung prüfen und üben✨ Lösung prüfen und üben