我们写一些请求时会需要用到分布式锁,主要是为了防连击或一些基础的幂等操作。最简单的方式那肯定是用redis的set加上nx和px/ex参数来实现,利用redis串行操作的天然原子性很方便搞出来,只是发现写的人多了,一个人一个用法,有的忘了加过期,有的忘了解锁,有的干脆懒得就不写了,于是抽象出一个公共方法来搞,解放下生产力。
方法使用非常简单。
原使用方法
rnum := rand.Intn(1000)
key := fmt.Sprintf("interface1:%s:%s:%s", param1,param2,param3)
flag, err := redisCli.SetNX(ctx, key, rnum, 3*time.Second).Result()
if err != nil {
return err
}
if !flag {
return errors.New("request locking")
}
//do some work
num, err := redisCli.Get(ctx, key)
if err == nil && num == rnum {
redisCli.Del(ctx, key)
}
lock_request
fn, err := LockRequest(ctx, redisCli, "interface1", params)
if err != nil {
return err
}
if fn == nil {
return errors.New("request locking")
}
defer fn()
// do some work
其实看LockRequest的函数就是把原逻辑里的代码封装在方法里,并没什么复杂用法,只是把解锁的逻辑做成了一个闭包返回,让业务方可以自己决策什么时候去释放锁
Just show the code