文件存储-定时同步租户文件存储容量信息接口优化

This commit is contained in:
2025-12-29 14:42:56 +08:00
parent 36c9b61db0
commit e65bdeb229
5 changed files with 71 additions and 69 deletions

View File

@@ -7,9 +7,17 @@ import (
"oss/model/entity" "oss/model/entity"
) )
var File = &file{} var File = &file{
NoCache: false,
}
type file struct{} type file struct {
NoCache bool
}
func (d *file) SetNoCache() {
File.NoCache = true
}
// Insert 插入 // Insert 插入
func (d *file) Insert(ctx context.Context, entity *entity.File) (err error) { func (d *file) Insert(ctx context.Context, entity *entity.File) (err error) {

View File

@@ -9,9 +9,17 @@ import (
"oss/model/entity" "oss/model/entity"
) )
var TenantOssTotal = &tenantOssTotal{} var TenantOssTotal = &tenantOssTotal{
NoCache: false,
}
type tenantOssTotal struct{} type tenantOssTotal struct {
NoCache bool
}
func (d *tenantOssTotal) SetNoCache() {
TenantOssTotal.NoCache = true
}
// Insert 插入 // Insert 插入
func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err error) { func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err error) {
@@ -20,12 +28,12 @@ func (d *tenantOssTotal) Insert(ctx context.Context, entity []interface{}) (err
} }
// SaveOrUpdate 增加或更新 // SaveOrUpdate 增加或更新
func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, filterData []*entity.TenantOssTotal, updateData []*entity.TenantOssTotal) (err error) { func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*entity.TenantOssTotal) (err error) {
if !g.IsEmpty(updateData) { if !g.IsEmpty(updateData) {
var filter, update []bson.M var filter, update []bson.M
for i, v := range filterData { for _, v := range updateData {
filter = append(filter, bson.M{"tenantId": v.TenantId}) filter = append(filter, bson.M{"tenantId": v.TenantId})
update = append(update, bson.M{"$set": bson.M{"usedOssSize": updateData[i].UsedOssSize, "totalOssSize": updateData[i].TotalOssSize}}) update = append(update, bson.M{"$set": bson.M{"usedOssSize": v.UsedOssSize, "totalOssSize": v.TotalOssSize}})
} }
_, err = mongo.SaveOrUpdate(ctx, filter, update, consts.TenantOssTotalCollection) _, err = mongo.SaveOrUpdate(ctx, filter, update, consts.TenantOssTotalCollection)
} }
@@ -35,6 +43,6 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, filterData []*entity.
func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, tenantId string) (e *entity.TenantOssTotal, err error) { func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, tenantId string) (e *entity.TenantOssTotal, err error) {
filter := bson.M{"tenantId": tenantId} filter := bson.M{"tenantId": tenantId}
e = &entity.TenantOssTotal{} e = &entity.TenantOssTotal{}
err = mongo.FindOne(ctx, filter, e, consts.TenantOssTotalCollection) err = mongo.FindOne(ctx, d.NoCache, filter, e, consts.TenantOssTotalCollection)
return return
} }

View File

@@ -10,7 +10,7 @@ type File struct {
do.MongoBaseDO `bson:",inline"` // 嵌入基础字段Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted do.MongoBaseDO `bson:",inline"` // 嵌入基础字段Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
// 基础信息 // 基础信息
FileURL string `bson:"fileURL" json:"fileURL"` // 图URL FileURL string `bson:"fileURL" json:"fileURL"` // 图URL
FileSize int64 `bson:"fileSize" json:"fileSize"` FileSize byte `bson:"fileSize" json:"fileSize"`
} }
// CollectionName 存储集合名称 // CollectionName 存储集合名称

View File

@@ -22,37 +22,24 @@ type file struct{}
var File = new(file) var File = new(file)
func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) { func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
tenantId := "" fileSize := gconv.Byte(req.File.Size)
fileSize := req.File.Size
totalFileSize := int64(0) totalFileSize := int64(0)
// 获取租户id // 获取租户id
user, err := mongo.GetTenantInfo(ctx) user, err := mongo.GetTenantInfo(ctx)
if err != nil { if err != nil {
return return
} }
tenantId := gconv.String(user.TenantId)
// 获取redis-租户存储容量总数key // 获取redis-租户存储容量总数key
tenantOssTotalKey := fmt.Sprintf(consts.TenantOssTotalKey, gconv.String(user.TenantId)) tenantOssTotalKey := fmt.Sprintf(consts.TenantOssTotalKey, gconv.String(user.TenantId))
// 获取redis-租户存储-锁key // 获取redis-租户存储-锁key
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId)) fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
i := 0
LOCK: success, err := redis.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
if ok, err := redis.RedisClient.SetNX(ctx, fileLockKey, fileSize); !ok || err != nil {
// 获取锁失败,需要重试
if i < 5 {
i++
time.Sleep(5 * time.Millisecond)
goto LOCK
}
}
// 设置redis-租户存储-锁key超时时间1分钟
err = redis.RedisClient.SetEX(ctx, fileLockKey, fileSize, gconv.Int64(time.Minute*1))
if err != nil {
return nil, err
}
// 获取redis-租户存储容量总数 // 获取redis-租户存储容量总数
get, err := redis.RedisClient.Get(ctx, tenantOssTotalKey) get, err := redis.RedisClient.Get(ctx, tenantOssTotalKey)
if err != nil { if err != nil {
return nil, err return err
} }
tenantOssTotalEntity := &entity.TenantOssTotal{} tenantOssTotalEntity := &entity.TenantOssTotal{}
if g.IsEmpty(get) { if g.IsEmpty(get) {
@@ -62,9 +49,9 @@ LOCK:
} }
tenantOssTotal, err := TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq) tenantOssTotal, err := TenantOssTotal.GetOneByTenantId(ctx, getByTenantIdReq)
if err != nil { if err != nil {
return nil, err return err
} }
if g.IsEmpty(tenantOssTotal) { if tenantOssTotal.Id.IsZero() {
tenantOssTotalEntity.TenantId = user.TenantId tenantOssTotalEntity.TenantId = user.TenantId
tenantOssTotalEntity.UsedOssSize = int64(0) tenantOssTotalEntity.UsedOssSize = int64(0)
tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int64() tenantOssTotalEntity.TotalOssSize = g.Cfg().MustGet(ctx, "oss.capacitySize").Int64()
@@ -75,26 +62,28 @@ LOCK:
// 反序列化-redis获取租户存储容量总数 // 反序列化-redis获取租户存储容量总数
err = gconv.Struct(get, tenantOssTotalEntity) err = gconv.Struct(get, tenantOssTotalEntity)
if err != nil { if err != nil {
return nil, err return err
} }
} }
tenantId = gconv.String(tenantOssTotalEntity.TenantId) tenantId = gconv.String(tenantOssTotalEntity.TenantId)
fileSize = tenantOssTotalEntity.UsedOssSize + fileSize fileSize = gconv.Byte(tenantOssTotalEntity.UsedOssSize) + fileSize
totalFileSize = tenantOssTotalEntity.TotalOssSize totalFileSize = tenantOssTotalEntity.TotalOssSize
// 设置redis-租户存储容量总数 // 设置redis-租户存储容量总数
tenantOssTotalKeyMap := map[string]interface{}{"tenantId": tenantId, "UsedOssSize": fileSize, "TotalOssSize": totalFileSize} tenantOssTotalKeyMap := map[string]interface{}{"tenantId": tenantId, "UsedOssSize": fileSize, "TotalOssSize": totalFileSize}
// 修改redis-租户存储容量总数 超时时间10分钟 // 修改redis-租户存储容量总数 超时时间10分钟
err = redis.RedisClient.SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10)) err = redis.RedisClient.SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10))
if err != nil { if err != nil {
return nil, err return err
} }
if fileSize < totalFileSize { if fileSize > gconv.Byte(totalFileSize) {
// 删除redis-租户存储-锁key return gerror.New("存储服务内存不足")
_, err = redis.RedisClient.Del(ctx, fileLockKey) }
return nil
})
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { if !success {
return nil, gerror.New("存储服务内存不足") return nil, gerror.New("存储服务内存不足")
} }
// 上传图片 // 上传图片

View File

@@ -2,6 +2,7 @@ package service
import ( import (
"context" "context"
"gitee.com/red-future---jilin-g/common/redis"
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv" "github.com/gogf/gf/v2/util/gconv"
"oss/consts" "oss/consts"
@@ -27,12 +28,11 @@ func (s *tenantOssTotal) GetOneByTenantId(ctx context.Context, req *dto.GetByTen
func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) { func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
// 使用 Keys 取出所有key // 使用 Keys 取出所有key
keys, err := g.Redis().Keys(ctx, consts.OssTotalKey) keys, err := redis.RedisClient.Keys(ctx, consts.OssTotalKey)
if err != nil { if err != nil {
return return
} }
updateData := make([]*entity.TenantOssTotal, 0) updateData := make([]*entity.TenantOssTotal, 0)
filterData := make([]*entity.TenantOssTotal, 0)
for _, key := range keys { for _, key := range keys {
get, err := g.Redis().Get(ctx, key) get, err := g.Redis().Get(ctx, key)
if err != nil { if err != nil {
@@ -44,13 +44,10 @@ func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
return err return err
} }
updateData = append(updateData, e) updateData = append(updateData, e)
totalOssSize := &entity.TenantOssTotal{}
totalOssSize.TenantId = e.TenantId
filterData = append(filterData, totalOssSize)
} }
// 更新数据库 // 更新数据库
err = dao.TenantOssTotal.SaveOrUpdate(ctx, filterData, updateData) err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
if err != nil { if err != nil {
return err return err
} }