分布式锁有三种
1.乐观锁
2.redis锁
3.zookeeper锁
这次进行一个设计,redis分布式锁,只需要三种操作,增删查
首先一个redis连接池,由于会被导入,所以init
import ( "redigo/redis" ) const ( SET_IF_NOT_EXIST = "NX" // 不存在则执行 SET_WITH_EXPIRE_TIME = "EX" // 过期时间(秒) PX 毫秒 SET_LOCK_SUCCESS = "OK" // 操作成功 DEL_LOCK_SUCCESS = 1 // lock 删除成功 DEL_LOCK_NON_EXISTENT = 0 // 删除lock key时,并不存在 ) var ( RdPool *redis.Pool Conn redis.Conn ) // NewRedisPool func init(){ pool := &redis.Pool{ Dial: func() (conn redis.Conn, e error) { return redis.Dial("tcp","localhost:6379") }, MaxIdle: 10, MaxActive: 20, IdleTimeout: 100, } RdPool = pool Conn = pool.Get() }
添加lock锁
/* redis 类型 字符串设置一个分布式锁 (哈希内部字段不支持过期判断,redis只支持***key过期) @param key: 锁名,格式为 用户id_操作_方法 @param requestId: 客户端唯一id 用来指定锁不被其他线程(协程)删除 @param ex: 过期时间 */ func AddLock(key,requestId string,ex int) bool { msg,_ := redis.String( Conn.Do("SET",key,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,ex), ) if msg == SET_LOCK_SUCCESS { return true } return false }
查
/* 获得redis分布式锁的值 @param key:redis类型字符串的key值 @param return: redis类型字符串的value */ func GetLock(key string) string { msg,_ := redis.String(Conn.Do("GET",key)) return msg }
删
/* 删除redis分布式锁 @param key:redis类型字符串的key值 @param requestId: 唯一值id,与value值对比,避免在分布式下其他实例删除该锁 */ func DelLock(key ,requestId string) bool{ if GetLock(key) == requestId { msg,_ := redis.Int64(Conn.Do("DEL",key)) // 避免操作时间过长,自动过期时再删除返回结果为0 if msg == DEL_LOCK_SUCCESS || msg == DEL_LOCK_NON_EXISTENT{ return true } return false } return false }
实际操作
package main import ( "fmt" "github.com/google/uuid" "./pool" ) func main() { uid, _ := uuid.NewUUID() id := uid.String() key := "用户id001_操作del_操作方法名DelComment" if pool.AddLock(key, id, 3) { fmt.Println("添加lock成功") } else { fmt.Println("添加lock失败") } if pool.GetLock(key) == id { fmt.Println("相等") }else { fmt.Println("不相等") } if pool.DelLock(key,id){ fmt.Println("删除成功") } else { fmt.Println("删除失败") } }
实际结果
添加lock成功 相等 删除成功
参考资料:
https://www.cnblogs.com/linjiqin/p/8003838.html#!comments