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

前言

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

咱们先来看一个例子

Set Cache 代码:redis

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 代码:json

func (this *GetController) Get() {

    result := urlcache.Get("test")

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

先卖个关子,先别往下看,思考一下大家以为输出的结果是什么?缓存

没错,结果是:学习

null

那么咱们再看一下例子:

Set Cache 代码:this

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 代码:url

func (this *GetController) Get() {

    result := urlcache.Get("test")

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

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

你们可能都知道了,结果:rest

test result sada

那纠到底是为何会这样呢?真相只有一个!

原来这个 Put 的第三个参数,设置内存的 GC 的时间单位是 time.Duration 也就是咱们说的纳秒,因此咱们在直接设置这个时间的时候常常忽略单位只写了个数字,因此最后咱们回头取缓存的时候,缓存早已通过期的了。
这个事情告诉咱们看文档必定要细心。我贴一下文档以及 Cache 源码:code

官方文档给的接口:

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
}

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

点我阅读原文

相关文章
相关标签/搜索