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 }
  • 相关阅读:
    极域电子教室 e-Learning Class V4 2010专业版 学生机 卸载方法
    浅谈IT员工管理
    apacheserver下载、安装、配置
    Android BLE开发之Android手机搜索iBeacon基站
    Qt编程18:Qt调色板QPalette的使用
    二叉树的操作
    Android应用开发多语言drawable目录
    Mybatis文档阅读笔记(明日继续更新...)
    《Spark快速大数据分析》—— 第六章 Spark编程进阶
    Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统
  • 原文地址:https://www.cnblogs.com/tymagic/p/10600014.html
Copyright © 2011-2022 走看看