From 413b816a1040d171bfa22726f0c5481959199c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=AD=90=E9=93=AD?= Date: Thu, 20 Mar 2025 17:44:14 +0800 Subject: [PATCH] add cacke --- internal/biz/vo/cache.go | 8 ++++ internal/data/repoimpl/order.go | 2 +- internal/data/repoimpl/product.go | 66 ++++++++++++++++++++++++++++--- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/internal/biz/vo/cache.go b/internal/biz/vo/cache.go index 376012b..0ff13ce 100644 --- a/internal/biz/vo/cache.go +++ b/internal/biz/vo/cache.go @@ -25,6 +25,11 @@ const ( WechatNotifyConsumeLockKey CacheKey = "wechat_notify_consume" ) +const ( + ProductQueryKey CacheKey = "product_query" + ProductQueryLockKey CacheKey = "product_query_lock" +) + var CacheKeyMap = map[CacheKey]time.Duration{ CmbOrderLockKey: 30 * time.Second, CmbQueryLockKey: 30 * time.Second, @@ -37,6 +42,9 @@ var CacheKeyMap = map[CacheKey]time.Duration{ WechatNotifyRegisterTagCacheKey: 86400 * time.Second, // 1天 WechatNotifyRegisterTagCacheLockKey: 60 * time.Second, WechatNotifyConsumeLockKey: 30 * time.Second, + + ProductQueryKey: 86400 * time.Second, + ProductQueryLockKey: 30 * time.Second, } type Cache struct { diff --git a/internal/data/repoimpl/order.go b/internal/data/repoimpl/order.go index 29c96a5..318d214 100644 --- a/internal/data/repoimpl/order.go +++ b/internal/data/repoimpl/order.go @@ -90,7 +90,7 @@ func (p *OrderRepoImpl) GetByOutBizNo(ctx context.Context, t vo.OrderType, outBi if tx.Error != nil { sqlDB, _ := db.DB() - log.Warnf("order 当前打开连接数: %d ,空闲连接数: ", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle) + log.Warnf("order当前打开连接数: %d,空闲连接数: %d", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle) return nil, fmt.Errorf("order db fail %w", tx.Error) } diff --git a/internal/data/repoimpl/product.go b/internal/data/repoimpl/product.go index 9e693fe..c5a9fdd 100644 --- a/internal/data/repoimpl/product.go +++ b/internal/data/repoimpl/product.go @@ -2,25 +2,30 @@ package repoimpl import ( "context" + "encoding/json" "fmt" "github.com/go-kratos/kratos/v2/log" + "github.com/redis/go-redis/v9" "gorm.io/gorm" err2 "voucher/api/err" "voucher/internal/biz/bo" "voucher/internal/biz/repo" + "voucher/internal/biz/vo" "voucher/internal/data" "voucher/internal/data/model" + "voucher/internal/pkg/lock" ) // ProductRepoImpl . type ProductRepoImpl struct { Base[model.Product, bo.ProductBo] - db *data.Db + db *data.Db + rdb *data.Rdb } // NewProductRepoImpl . -func NewProductRepoImpl(db *data.Db) repo.ProductRepo { - return &ProductRepoImpl{db: db} +func NewProductRepoImpl(db *data.Db, rdb *data.Rdb) repo.ProductRepo { + return &ProductRepoImpl{db: db, rdb: rdb} } func (p *ProductRepoImpl) DB(ctx context.Context) *gorm.DB { @@ -28,14 +33,63 @@ func (p *ProductRepoImpl) DB(ctx context.Context) *gorm.DB { } func (r *ProductRepoImpl) GetByPNO(ctx context.Context, PNO string) (*bo.ProductBo, error) { - var item model.Product + + var item *model.Product + + c := vo.ProductQueryKey.BuildCache([]string{PNO}) + + cacheValue, err := r.rdb.Rdb.Get(ctx, c.Key).Result() + + if err != nil && err != redis.Nil { + return nil, fmt.Errorf(fmt.Sprintf("获取商品缓存异常,%s:%v", c.Key, err)) + } + + if len(cacheValue) > 0 { + if err = json.Unmarshal([]byte(cacheValue), &item); err != nil { + return nil, err + } + return r.ToBo(item), nil + } + + cl := vo.ProductQueryLockKey.BuildCache([]string{PNO}) + + err = lock.NewMutex(r.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error { + + cacheValue, err = r.rdb.Rdb.Get(ctx, c.Key).Result() + + if err != nil && err != redis.Nil { + return fmt.Errorf(fmt.Sprintf("二次获取商品缓存异常,%s:%v", c.Key, err)) + } + + if len(cacheValue) > 0 { + return json.Unmarshal([]byte(cacheValue), &item) + } + + item, err = r.getByPNO(ctx, item, PNO) + + b, err := json.Marshal(item) + if err == nil { + r.rdb.Rdb.Set(ctx, c.Key, string(b), c.TTL) + } + + return err + }) + + if err != nil { + return nil, err + } + + return r.ToBo(item), err +} + +func (r *ProductRepoImpl) getByPNO(ctx context.Context, item *model.Product, PNO string) (*model.Product, error) { db := r.DB(ctx) tx := db.Where(model.Product{ProductNo: PNO}).Find(&item) if tx.Error != nil { sqlDB, _ := db.DB() - log.Warnf("当前打开连接数: %d ,空闲连接数: ", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle) + log.Warnf("product当前打开连接数: %d,空闲连接数: %d", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle) return nil, fmt.Errorf("product db fail %w", tx.Error) } @@ -44,5 +98,5 @@ func (r *ProductRepoImpl) GetByPNO(ctx context.Context, PNO string) (*bo.Product return nil, err2.ErrorDbNotFound("商品数据不存在") } - return r.ToBo(&item), nil + return item, nil }