Heim > Artikel > Backend-Entwicklung > So implementieren Sie Golangs Memcache einfach
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!
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 }
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 }
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!