47

Beego 中容易被我们忽视的问题之 Memory 缓存篇

 4 years ago
source link: https://www.tuicool.com/articles/YviqYfy
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言

在我基于 beego 写博客的时候遇到一个很奇怪的问题,那就是在使用 Memory Cache 类型缓存的时候,缓存不生效很是奇怪,但是使用 redis 就没问题。由于时间问题我就没有深究,毕竟那时候实际上也会选用 Memory 做缓存的。所以就放了下来,直到今天在群里有人问了同样的问题。我决定去研究一下这个坑。

我们先来看一个例子

Set Cache 代码:

var (
    urlcache cache.Cache
)

func init() {
    urlcache, _ = cache.NewCache("memory", `{"interval":10}`)
}


func (this *SetController) Get() {
        urlcache.Put("test", "test result sada", 60)
}

Get Cache 代码:

func (this *GetController) Get() {

    result := urlcache.Get("test")

    this.Data["json"] = result
    this.ServeJSON()
}

先卖个关子,先别往下看,思考一下你们觉得输出的结果是什么?

没错,结果是:

null

那么我们再看一下例子:

Set Cache 代码:

var (
    urlcache cache.Cache
)

func init() {
    urlcache, _ = cache.NewCache("memory", `{"interval":10}`)
}


func (this *SetController) Get() {
        urlcache.Put("test", "test result sada", 0)
}

Get Cache 代码:

func (this *GetController) Get() {

    result := urlcache.Get("test")

    this.Data["json"] = result
    this.ServeJSON()
}

再来猜一下这回结果是什么?

大家可能都知道了,结果:

test result sada

那纠究竟是为什么会这样呢?真相只有一个!

原来这个 Put 的第三个参数,设置内存的 GC 的时间单位是 time.Duration 也就是我们说的纳秒,所以我们在直接设置这个时间的时候经常忽略单位只写了个数字,所以最后我们回头取缓存的时候,缓存早已经过期的了。

这个事情告诉我们看文档一定要细心。我贴一下文档以及 Cache 源码:

官方文档给的接口:

type Cache interface {
    Get(key string) interface{}
    GetMulti(keys []string) []interface{}
    Put(key string, val interface{}, timeout time.Duration) error
    Delete(key string) error
    Incr(key string) error
    Decr(key string) error
    IsExist(key string) bool
    ClearAll() error
    StartAndGC(config string) error
}

memory.go 源码:

// Put cache to memory.
// if lifespan is 0, it will be forever till restart.
func (bc *MemoryCache) Put(name string, value interface{}, lifespan time.Duration) error {
    bc.Lock()
    defer bc.Unlock()
    bc.items[name] = &MemoryItem{
        val:         value,
        createdTime: time.Now(),
        lifespan:    lifespan,
    }
    return nil
}

欢迎各位朋友留言评论一起学习交流。

点我阅读原文


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK