别着急,坐和放宽
使用社交账号登录
go-cache 包
go-cache 是一个线程安全的内存缓存库,支持过期时间。
go get github.com/patrickmn/go-cache
import (
"github.com/patrickmn/go-cache"
"time"
)
func basicCacheUsage() {
// 创建缓存(默认过期时间 5 分钟,清理间隔 10 分钟)
c := cache.New(5*time.Minute, 10*time.Minute)
// 设置值
c.Set("key1", "value1", cache.DefaultExpiration)
// 设置自定义过期时间
c.Set("key2", "value2", 1*time.Minute)
// 永不过期
c.Set("key3", "value3", cache.NoExpiration)
// 获取值
if val, found := c.Get("key1"); found {
fmt.Println("值:", val.(string))
}
// 删除
c.Delete("key1")
// 清空所有
c.Flush()
}
func incrementOperations() {
c := cache.New(5*time.Minute, 10*time.Minute)
// 设置计数器
c.Set("counter", 0, cache.NoExpiration)
// 增加
c.Increment("counter", 1)
// 减少
c.Decrement("counter", 1)
// 获取
if val, found := c.Get("counter"); found {
fmt.Println("计数器:", val.(int))
}
}
func cacheWithCallbacks() {
c := cache.New(5*time.Minute, 10*time.Minute)
// 设置过期回调
c.OnEvicted(func(key string, value interface{}) {
fmt.Printf("缓存过期: %s = %v\n", key, value)
})
c.Set("temp", "data", 1*time.Second)
time.Sleep(2 * time.Second) // 触发过期回调
}
// 用户缓存服务
type UserCacheService struct {
cache *cache.Cache
db *Database // 假设的数据库连接
}
func NewUserCacheService(db *Database) *UserCacheService {
return &UserCacheService{
cache: cache.New(10*time.Minute, 15*time.Minute),
db: db,
}
}
// 获取用户(带缓存)
func (ucs *UserCacheService) GetUser(userID int) (*User, error) {
cacheKey := fmt.Sprintf("user:%d", userID)
// 尝试从缓存获取
if val, found := ucs.cache.Get(cacheKey); found {
return val.(*User), nil
}
// 缓存未命中,从数据库查询
user, err := ucs.db.FindUser(userID)
if err != nil {
return nil, err
}
// 存入缓存
ucs.cache.Set(cacheKey, user, cache.DefaultExpiration)
return user, nil
}
// 更新用户(同时更新缓存)
func (ucs *UserCacheService) UpdateUser(user *User) error {
// 更新数据库
if err := ucs.db.UpdateUser(user); err != nil {
return err
}
// 更新缓存
cacheKey := fmt.Sprintf("user:%d", user.ID)
ucs.cache.Set(cacheKey, user, cache.DefaultExpiration)
return nil
}
// 删除用户(同时删除缓存)
func (ucs *UserCacheService) DeleteUser(userID int) error {
// 删除数据库
if err := ucs.db.DeleteUser(userID); err != nil {
return err
}
// 删除缓存
cacheKey := fmt.Sprintf("user:%d", userID)
ucs.cache.Delete(cacheKey)
return nil
}
// 批量预热缓存
func (ucs *UserCacheService) WarmupCache(userIDs []int) error {
for _, id := range userIDs {
user, err := ucs.db.FindUser(id)
if err != nil {
continue // 跳过错误
}
cacheKey := fmt.Sprintf("user:%d", id)
ucs.cache.Set(cacheKey, user, cache.DefaultExpiration)
}
return nil
}
// 获取缓存统计
func (ucs *UserCacheService) Stats() map[string]int {
items := ucs.cache.Items()
return map[string]int{
"total_items": len(items),
}
}
// 缓存穿透保护
type ProtectedCache struct {
cache *cache.Cache
mu sync.Map // 防止并发击穿
}
func (pc *ProtectedCache) GetOrLoad(key string, loader func() (interface{}, error)) (interface{}, error) {
// 尝试从缓存获取
if val, found := pc.cache.Get(key); found {
return val, nil
}
// 防止并发加载同一个 key
actual, loaded := pc.mu.LoadOrStore(key, &sync.Mutex{})
mtx := actual.(*sync.Mutex)
mtx.Lock()
defer mtx.Unlock()
if !loaded {
defer pc.mu.Delete(key)
}
// 再次检查缓存
if val, found := pc.cache.Get(key); found {
return val, nil
}
// 加载数据
val, err := loader()
if err != nil {
return nil, err
}
// 存入缓存
pc.cache.Set(key, val, cache.DefaultExpiration)
return val, nil
}