手动撸一个 Redis 分布式锁( 二 )

删除锁逻辑:
// 删除分布式锁// @return bool true-删除成功;false-删除失败func DelDistributeLock(key string) bool { redisAlias := "jointly" redisRet := redis.Del(redisAlias, key) if redisRet != nil {return false } return true}业务逻辑:
func DoProcess(processId int) { fmt.Printf("启动第%d个线程n", processId) redisKey := "redis_lock_key" for {// 获取分布式锁isGetLock := GetDistributeLock(redisKey, 10)if isGetLock {fmt.Printf("Get Redis Key Success, id:%dn", processId)time.Sleep(time.Second * 3)// 删除分布式锁DelDistributeLock(redisKey)} else {// 如果未获取到该锁,为了避免redis负载过高,先睡一会time.Sleep(time.Second * 1)} }}最后起个 10 个多线程 , 去执行这个 DoProcess():
func mAIn() { // 初始化资源 var group string = "group" var name string = "name" var host string // 初始化资源 host = "http://ip:port" _, err := xrpc.NewXRpcDefault(group, name, host) if err != nil {panic(fmt.Sprintf("initRpc when init rpcfailed, err:%v", err)) } redis.SetRedis("louzai", "redis_louzai") // 开启10个线程,去抢Redis分布式锁 for i := 0; i <= 9; i ++ {go DoProcess(i) } // 避免子线程退出,主线程睡一会 time.Sleep(time.Second * 100) return}程序跑了100 s,我们可以看到,每次都只有 1 个线程获取到锁,分别是 2、1、5、9、3,执行结果如下:
启动第0个线程启动第6个线程启动第9个线程启动第4个线程启动第5个线程启动第2个线程启动第1个线程启动第8个线程启动第7个线程启动第3个线程Get Redis Key Success, id:2Get Redis Key Success, id:2Get Redis Key Success, id:1Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:5Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:9Get Redis Key Success, id:3Get Redis Key Success, id:3Get Redis Key Success, id:3Get Redis Key Success, id:3Get Redis Key Success, id:304 后记这个代码,其实是我很久之前写的,因为当时 Go 没有开源的分布式锁,但是我又需要通过单机去执行某个任务 , 所以就自己手动撸了一个,后来在线上跑了 2 年 , 一直都没有问题 。
不过期间也遇到过一个坑,就是我们服务迁移时,忘了将旧机器的分布式锁停掉,导致锁经常被旧机器抢占,当时觉得很奇怪,我的锁呢?
写这篇文章时,又让我想到当时工作的场景 。
最后再切回正题,本文由浅入深,详细讲解了 Redis 实现的详细过程,以及锁超时、并发场景下,如何保证锁能正常释放,且只有一个线程去获取锁 。

【手动撸一个 Redis 分布式锁】


推荐阅读