美文网首页
go+redis模拟实现分布式锁

go+redis模拟实现分布式锁

作者: 小怪兽狂殴奥特曼 | 来源:发表于2019-04-24 16:44 被阅读0次

    参考这篇文章# Redis分布式锁的正确实现方式 实现的分布式锁
    整个过程可以分为四步:
    +先用SETNX设置key。key是唯一的,统一时刻只有一个客户端的setnx指令能成功,满足锁的唯一性。如果成功,说明没有人持有锁,否则锁被占有,则获取锁的释放时间,然后进入睡眠。睡眠时间为一个任意的值,小于锁的TTL。

    • 用EXPIRE设置key。expire是为了防止客户端崩溃锁变成死锁。SETNX和EXPIRE两个指令应该是原子的,go下面没法实现。需要修改redis支持。
    • 获取到锁后干活
    • 释放锁
    package main
    
    import (
        "fmt"
        "time"
        "os"
        "strconv"
        "github.com/gomodule/redigo/redis"
    )
    
    const dist_lock = "distlock"
    func main() {
        redis_conn, err := redis.Dial("tcp", "127.0.0.1:6379", redis.DialPassword("hdiot"))
        if err != nil {
            fmt.Println(err)
            return
        }
        defer redis_conn.Close()
    
        pidstr := strconv.Itoa(os.Getpid())
        for {
            fmt.Println("try lock")
            _, err := redis_conn.Do("SETNX", dist_lock, pidstr)
            if err != nil {
                fmt.Println(err)
    
                ttl, err := redis.Int(redis_conn.Do("TTL", dist_lock))
                if err != nil {
                    fmt.Println(err)
                }
                time.Sleep(time.Duration(ttl/2) * time.Second)  
            } else {
                // we get lock
                break;
            }
        }
    
        _, err = redis_conn.Do("EXPIRE", dist_lock, 10)
        if err != nil {
            fmt.Println(err)
            return      
        }
    
        // do something
        fmt.Println("get lock")
    
        // release lock
        pid_ret, err := redis.String(redis_conn.Do("GET", dist_lock))
        if err != nil {
            fmt.Println(err)
            return
        }
    
        pid, _ := strconv.Atoi(pid_ret)
        if(pid != os.Getpid()) {
            fmt.Println("not my lock")
            return
        }
    
        _, err = redis_conn.Do("Del", dist_lock)
        if err != nil {
            fmt.Println(err)
            return      
        }
        fmt.Println("release lock ok")
    }
    

    相关文章

      网友评论

          本文标题:go+redis模拟实现分布式锁

          本文链接:https://www.haomeiwen.com/subject/nloggqtx.html