zoukankan      html  css  js  c++  java
  • golang使用etcd实现分布式锁

     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 }
  • 相关阅读:
    idea快捷键总结
    将对象序列化和反序列化
    在Springmvc中获取properties属性
    配置springmvc在其他类中(spring容器外)获取注入bean
    redis学习之三配置文件redis.conf 的含义
    redis学习之二from github
    敏捷开发方法XP的12个最佳实践
    IIS-网站发布之后访问HTTP 错误 403.14
    IIS-将iis直接指向.net代码会出现错误
    HTTP 错误 500.24
  • 原文地址:https://www.cnblogs.com/tymagic/p/10600014.html
Copyright © 2011-2022 走看看