etcd 是与 ZooKeeper 类似的分布式组件,也能实现与 ZooKeeper 锁相似的功能:

package main

import (
    clientv3 "go.etcd.io/etcd/client/v3"
    "go.etcd.io/etcd/client/v3/concurrency"
)

func main() {
c := make(chan os.Signal)
    signal.Notify(c)

    client, err := clientv3.New(clientv3.Config{
        Endpoints:   []string{"localhost:2379"},
        DialTimeout: 5 * time.Second,
    })
    if err != nil {
        panic(err)
    }
    defer client.Close()

    lockKey := "/lock"

    go func() {
        session, err := concurrency.NewSession(client)
        if err != nil {
            panic(err)
        }
        m := concurrency.NewMutex(session, lockKey)
        if err := m.Lock(context.Background()); err != nil {
            panic("go1 get mutex failed " + err.Error())
        }
        fmt.Printf("go1 get mutex sucess\n")
        fmt.Println(m)
        time.Sleep(time.Duration(10) * time.Second)
        m.Unlock(context.Background())
        fmt.Printf("go1 release lock\n")
    }()

    go func() {
        time.Sleep(time.Duration(2) * time.Second)
        session, err := concurrency.NewSession(client)
        if err != nil {
            panic(err)
        }
        m := concurrency.NewMutex(session, lockKey)
        if err := m.Lock(context.Background()); err != nil {
            panic("go2 get mutex failed " + err.Error())
        }
        fmt.Printf("go2 get mutex sucess\n")
        fmt.Println(m)
        time.Sleep(time.Duration(2) * time.Second)
        m.Unlock(context.Background())
        fmt.Printf("go2 release lock\n")
    }()

    <-c
}
最后编辑: kuteng  文档更新时间: 2022-03-22 19:29   作者:kuteng