golang 版本redis分布式鎖


分布式鎖有三種

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM