前言
在我基于 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
}
欢迎各位朋友留言评论一起学习交流。
有疑问加站长微信联系(非本文作者)