文章目录

Etcd 分布式锁例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main

import (
"context"
"log"
"time"

"github.com/coreos/etcd/clientv3/concurrency"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/pkg/transport"
)

var (
defaultTimeout = 10 * time.Second
Client *clientv3.Client
)

func init() {
endpoints := []string{
"127.0.0.1:2379"
}
tlsInfo := transport.TLSInfo{
CertFile: "/tmp/test-certs/test-name-1.pem",
KeyFile: "/tmp/test-certs/test-name-1-key.pem",
TrustedCAFile: "/tmp/test-certs/trusted-ca.pem",
}
tlsConfig, err := tlsInfo.ClientConfig()
if err != nil {
log.Fatal(err)
}

Client, err = clientv3.New(clientv3.Config{
Endpoints: endpoints,
DialTimeout: dialTimeout,
TLS: tlsConfig,
})
if err != nil {
log.Fatal(err)
}
// defer Client.Close() // make sure to close the client
}

func main() {
m,err := GetLockSession("hello","boy")
if err != nil {
fmt.Println("m get etcd lock failed:",err)
return
}

// 添加带超时时间的ctx
ctx,cancel := context.WithTimeout(context.Background(),15*time.Second)
defer cancel()

err = m.Lock(ctx)
if err !=nil {
fmt.Println("m lock failed:",err)
return
}

fmt.Println("m lock ...")

go func() {
select {
case <-ctx.Done:
err = m.Unlock(context.TODO())
if err != nil {
fmt.Println("unlock:",err)
return
}
fmt.Println("m unlock ...")
}
}()

for i := 1; i< 8; i++ {
time.Sleep(1*time.Second)
fmt.Println("sleep ",i)
}
}

func GetLockSession(key string,id string) (*concurrency.Mutex,error) {
def := "/com/lock"
lockKey := fmt.Sprintf("%s/%s-%s",def,key,id)
session,err:=concurrency.NewSession(Client)
if err != nil {
return nil,fmt.Errorf("get lock session %v",err)
}

return concurrency.NewMutex(session,lockKey),nil
}
文章目录