1 package main
 2 
 3 import (
 4     "context"
 5     "fmt"
 6     "time"
 7 
 8     "go.etcd.io/etcd/clientv3"
 9 )
10 
11 func main() {
12     var (
13         client *clientv3.Client
14         cfg    clientv3.Config
15         err    error
16         lease clientv3.Lease
17         ctx context.Context
18         cancelFunc context.CancelFunc
19         leaseId clientv3.LeaseID
20         leaseGrantResponse *clientv3.LeaseGrantResponse
21         leaseKeepAliveChan <-chan *clientv3.LeaseKeepAliveResponse
22         leaseKeepAliveResponse *clientv3.LeaseKeepAliveResponse
23         txn clientv3.Txn
24         txnResponse *clientv3.TxnResponse
25         kv clientv3.KV
26     )
27 
28     cfg = clientv3.Config{
29         Endpoints:   []string{"youwebsite:2379"},
30         DialTimeout: time.Second * 5,
31     }
32     if client, err = clientv3.New(cfg); err != nil {
33         fmt.Println(err)
34         return
35     }
36 
37     lease = clientv3.NewLease(client)
38     if leaseGrantResponse,err = lease.Grant(context.TODO(),5);err!=nil{
39         fmt.Println(err)
40         return
41     }
42     leaseId = leaseGrantResponse.ID
43 
44     //租约自动过期,立刻过期。//cancelfunc 取消续租,而revoke 则是立即过期
45     ctx,cancelFunc = context.WithCancel(context.TODO())
46     defer cancelFunc()
47     defer lease.Revoke(context.TODO(),leaseId)
48 
49     if leaseKeepAliveChan,err = lease.KeepAlive(ctx,leaseId);err!=nil{
50         fmt.Println(err)
51         return
52     }
53     //启动续租协程,每秒续租一次
54     go func() {
55         for {
56             select {
57             case leaseKeepAliveResponse = <-leaseKeepAliveChan:
58                 if leaseKeepAliveResponse != nil{
59                     fmt.Println("续租成功,leaseID :",leaseKeepAliveResponse.ID)
60                 }else {
61                     fmt.Println("续租失败")
62                 }
63 
64             }
65             time.Sleep(time.Second*1)
66         }
67     }()
68     //锁逻辑。
69     kv = clientv3.NewKV(client)
70     txn = kv.Txn(context.TODO())
71 
72     txn.If(clientv3.Compare(clientv3.CreateRevision("/dev/lock"),"=",0)).Then(
73         clientv3.OpPut("/dev/lock","占用",clientv3.WithLease(leaseId))).Else(
74             clientv3.OpGet("/dev/lock"))
75     if txnResponse,err = txn.Commit();err!=nil{
76         fmt.Println(err)
77         return
78     }
79     if txnResponse.Succeeded {
80         fmt.Println("抢到锁了")
81     }else {
82         fmt.Println("没抢到锁",txnResponse.Responses[0].GetResponseRange().Kvs[0].Value)
83     }
84     time.Sleep(time.Second * 10 )
85 }

 

oschinahttps://my.oschina.net/u/4402159/blog/3598314