在RichCMS的管理平台,可以开启文章详情页的redis缓存,如下图所示,开启后,当访问前台的文章页面时,会优先从redis的缓存中读取数据,本文可以看到这一部分的Golang源码实现。

image.png

文件地址:/src/cms/dao/article_redis.go

package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/zituocn/logx"
	"github.com/zituocn/richcms/common/constname"
	"github.com/zituocn/richcms/common/repository/enum"
	"github.com/zituocn/richcms/common/repository/model"
	"github.com/zituocn/richcms/common/sdk/goredis"
	"github.com/zituocn/richcms/src/cms/cache"
	"time"
)

type ArticleRedis struct{}

var (
	ctx = context.Background()
)

// Delete 从redis中删除
func (m *ArticleRedis) Delete(id int64) error {
	config, _ := new(cache.ConfigCache).GetConfig()
	if config != nil && config.RedisCacheEnable == enum.CommonStateEnable {
		key := fmt.Sprintf(constname.ArticleRedisKey, id)
		rdb, _ := goredis.GetRDB()
		if rdb != nil {
			_, err := rdb.Del(ctx, key).Result()
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// GetArticleDetail redis中获取文章详情
func (m *ArticleRedis) GetArticleDetail(id int64) (v *model.ArticleDetail, err error) {
	config, _ := new(cache.ConfigCache).GetConfig()
	if config != nil && config.RedisCacheEnable == enum.CommonStateEnable {
		redisCacheTime := 10
		if config.RedisCacheTime > 0 {
			redisCacheTime = config.RedisCacheTime
		}
		var flag bool
		key := fmt.Sprintf(constname.ArticleRedisKey, id)
		rdb, _ := goredis.GetRDB()
		if rdb != nil {
			result, _ := rdb.Get(ctx, key).Result()
			if result != "" {
				err = json.Unmarshal([]byte(result), &v)
				if err != nil {
					flag = false
				} else {
					flag = true
				}
			}
		}
		if !flag {
			v = new(model.ArticleDetail)
			err = v.GetArticleDetail(id)
			if err != nil {
				return
			}
			//状态正常时,再存入redis
			if v.State == enum.ArticleStateEnable {
				//存储 redis
				go func() {
					b, err1 := json.Marshal(v)
					if err1 != nil {
						logx.Errorf("article detail marshal err: %v", err1)
					}
					_, err = rdb.SetEx(ctx, key, string(b), time.Duration(redisCacheTime)*time.Minute).Result()
					if err != nil {
						logx.Errorf("article detail set err: %v", err)
					}
				}()
			}
		}
	} else {
		v = new(model.ArticleDetail)
		err = v.GetArticleDetail(id)
		if err != nil {
			return
		}
	}

	return
}

代码解读:

  • Delete(id int64)是根据文章ID,删除redis缓存,可以用来做为重载redis缓存,当文章被删除、被编辑时,会调用此方法;
  • GetArticleDetail(id int64),是根据文章ID,从redis中读取文章详情,如果没有命中redis缓存,会从数据库(mysql)中获取代码,同时放置到redis中,再返回给前台页面。

建议有条件的站长,在网站流量较大,数据库访问压力较大时,开启此功能。