分布式锁有三种

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