首頁  >  文章  >  後端開發  >  如何處理 Golang 快取失效的情況?

如何處理 Golang 快取失效的情況?

WBOY
WBOY原創
2024-06-02 17:09:02645瀏覽

在處理 Golang 中的快取失效時,可以遵循以下策略:使用時間戳標記快取項,並在過期時取得新資料。使用鎖,當協程取得快取項目時對快取進行加鎖,並在快取項目不存在或過期時解鎖快取並取得新資料。

如何处理 Golang 缓存失效的情况?

如何處理 Golang 快取失效的情況?

在 Golang 程式中使用快取時,應對快取失效的情況至關重要,以確保資料的一致性和可靠性。以下是兩種處理策略:

1. 使用時間戳記

  • #將快取項目與時間戳記關聯。
  • 當快取項目過期時,取得新資料並更新快取。
type CacheItem struct {
    Value interface{}
    Timestamp time.Time
}

var cache = make(map[string]CacheItem)

func SetCache(key string, value interface{}) {
    cache[key] = CacheItem{Value: value, Timestamp: time.Now()}
}

func GetCache(key string) (interface{}, bool) {
    item, ok := cache[key]
    if ok && time.Since(item.Timestamp) < time.Second*30 {
        return item.Value, true
    }
    return nil, false
}

2. 使用鎖定

  • 當一個協程取得快取項目時,對快取進行加鎖。
  • 如果快取項目不存在或過期,則解鎖快取並取得新資料。
var cache = sync.Map{}

func SetCache(key string, value interface{}) {
    cache.Store(key, value)
}

func GetCache(key string) (interface{}, bool) {
    if value, ok := cache.Load(key); ok {
        return value, true
    }

    lock := sync.Mutex{}
    lock.Lock()
    defer lock.Unlock()

    if value, ok := cache.Load(key); ok {
        return value, true
    }

    newValue, err := fetchNewValue(key)
    if err == nil {
        cache.Store(key, newValue)
    }

    return newValue, err == nil
}

實戰案例

假設我們在一個 RESTful API 中使用快取來儲存使用者的詳細資訊。

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"

    "github.com/go-redis/redis/v8"
)

var redisClient = redis.NewClient(&redis.Options{})

type User struct {
    ID   int
    Name string
}

func main() {
    // 添加缓存处理
    http.HandleFunc("/users/:id", func(w http.ResponseWriter, r *http.Request) {
        var user User
        id := r.URL.Path[len("/users/"):]

        // 尝试从缓存中获取用户数据
        cachedUser, ok := GetCache(id)
        if ok {
            // 缓存命中
            fmt.Fprintf(w, "User from cache: %+v", cachedUser)
            return
        }

        // 缓存未命中
        // 从数据库中获取用户数据
        err := db.Get(id, &user)
        if err != nil {
            // 数据库中不存在此用户
            fmt.Fprintf(w, "User not found")
            return
        }

        // 设置缓存,有效期为 30 秒
        SetCache(id, user, time.Second*30)
        fmt.Fprintf(w, "User from database: %+v", user)
    })

    http.ListenAndServe(":8080", nil)
}

func GetCache(key string) (User, bool) {
    result, err := redisClient.Get(key).Bytes()
    if err != nil {
        return User{}, false
    }

    var user User
    err = json.Unmarshal(result, &user)
    if err != nil {
        return User{}, false
    }

    return user, true
}

func SetCache(key string, user User, expiration time.Duration) {
    jsonBytes, err := json.Marshal(user)
    if err != nil {
        return
    }

    err = redisClient.Set(key, jsonBytes, expiration).Err()
    if err != nil {
        return
    }
}

以上是如何處理 Golang 快取失效的情況?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn