Heim > Backend-Entwicklung > Golang > So implementieren Sie Golangs Memcache einfach

So implementieren Sie Golangs Memcache einfach

藏色散人
Freigeben: 2021-02-10 09:31:47
nach vorne
2838 Leute haben es durchsucht

Die folgende Tutorial-Kolumne von golang stellt Ihnen die einfache Memcache-Implementierungsmethode in Golang vor. Ich hoffe, dass sie Freunden in Not hilfreich sein wird!

So implementieren Sie Golangs Memcache einfach

In den letzten zwei Tagen bin ich während des Projekts auf ein Problemszenario beim Zugriff auf globale Variablen gestoßen: Schreiben Sie eine Methode, um den Token-Wert zu erhalten, der der ID entspricht. Das Token muss zwischengespeichert werden (Globaler Variablenspeicher-Cache). ). Wenn die Zeit kürzer ist oder das Token abläuft, senden Sie eine HTTP-Anfrage an ein anderes Ende, um es zwischenzuspeichern, und geben Sie es dann wie folgt zurück:

code.go:

package person

import (
	"time"
)

var gAccId2Token map[int]interface{} = make(map[int]interface{})

func GetTokenByAccountId(accountId uint, acl string) (map[string]interface{}, error) {
	//get token from cache
	if token, ok := gAccId2Token[accountId]; ok {
		if token != nil {
			now := time.Now().Unix()
			if int(now) < int(token.(map[string]interface{})["expireDate"].(float64)) {
				return token.(map[string]interface{}), nil
			}
		}
	}

	token, err := getTokenByHttpUrl(apiUrl)
	if err != nil {
		return map[string]interface{}{}, err
	}

	gAccId2Token[accountId] = token

	return token.(map[string]interface{}), nil
}
Nach dem Login kopieren

Dann kommt die Frage:

1 Da es sich bei der gAccId2Token-Variable um eine globale Variable handelt, können Lese- und Schreibvorgänge gleichzeitig erfolgen und es kann zu inkonsistenten Lese- und Schreibvorgängen kommen.

2. Um das Token mit der ID = 2 abzurufen und das zwischengespeicherte Token abgelaufen ist, wird eine HTTP-Anfrage gesendet, um es abzurufen, und dann wird der Cache geschrieben ist sehr lang, während dieses Zeitraums gibt es zufällig eine große Anzahl von Anfragen, um das Token mit der ID = 2 zu erhalten. Da die Token abgelaufen sind, wird es ein Problem mit einer großen Anzahl von Anfragen geben Der HTTP-Server erreicht nicht nur den Zweck, den Cache abzurufen, sondern erhöht auch den Druck auf das Backend. Gleichzeitig gibt es mehrere Schreib-Cache-Vorgänge, und Golangs Karte sollte nicht atomar sein, sodass das Schreiben von a Eine große Speichermenge kann auch zu Absturzproblemen führen.

Daher müssen wir die Lese- und Schreibvorgänge sperren:

memcache.go:

package person

import (
	"sync"
	"time"
)

type memoryCache struct {
	lock  *sync.RWMutex
	items map[interface{}]interface{}
}

func (mc *memoryCache) set(key interface{}, value interface{}) error {
	mc.lock.Lock()
	defer mc.lock.Unlock()
	mc.items[key] = value
	return nil
}

func (mc *memoryCache) get(key interface{}) interface{} {
	mc.lock.RLock()
	defer mc.lock.RUnlock()

	if val, ok := mc.items[key]; ok {
		return val
	}
	return nil
}

var gAccId2Token *memoryCache = &memoryCache{
		lock:  new(sync.RWMutex),
		items: make(map[interface{}]interface{}),
	}

func GetTokenByAccountId(accountId uint, acl string) (map[string]interface{}, error) {
	//get token from cache
	token := gAccId2Token.get(accountId)
	if token != nil {
		now := time.Now().Unix()
		if int(now) < int(token.(map[string]interface{})["expireDate"].(float64)) {
			return token.(map[string]interface{}), nil
		}
	}

	token, err := getTokenByHttpUrl(apiUrl)
	if err != nil {
		return map[string]interface{}{}, err
	}

	gAccId2Token.set(accountId, token)

	return token.(map[string]interface{}), nil
}
Nach dem Login kopieren

Ein paar Hinweise:

1. Sobald Lock() ausgeführt wird, werden andere Sperren gesetzt Die Sperre kann nicht gesperrt werden, bis die Sperre aufgehoben wird (Unlock()), was bedeutet, dass die Atomizität des Schreibvorgangs gewährleistet ist.

2. Wenn eine Lesesperre für einen Lesevorgang festgelegt ist, können mehrere Threads einen Bereich sperren, um ihn zu sperren, wodurch sichergestellt wird, dass der Bereich lesbar ist, bis alle Lesesperren aktiviert sind.

3. Definieren Sie die Schlüssel- und Werttypen der Karte als Schnittstelle{}. Schnittstelle{} kann jeden Typ empfangen, genau wie Object in Java.

4.Interface{} Typkonvertierungsmethode, value.(type), dient der Konvertierung von Werten in Typtypen, wie zum Beispiel: value.(int), value.(map[string]interface{}) usw.

Das obige ist der detaillierte Inhalt vonSo implementieren Sie Golangs Memcache einfach. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:csdn.net
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