温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

etcd租约机制及自动过期的实例分析

发布时间:2022-01-07 21:48:47 来源:亿速云 阅读:850 作者:柒染 栏目:编程语言

这篇文章给大家介绍etcd租约机制及自动过期的实例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

对于实现分布式乐观锁非常重要。如果锁了,突然宕机了,锁是需要自动释放的。所以这锁在etcd里是需要生命期的。
过期演示:

package main import (     "context"     "fmt"     "go.etcd.io/etcd/clientv3"     "time" ) func main() {     var (         config  clientv3.Config         client  *clientv3.Client         err     error         lease clientv3.Lease         leaseGrantResp *clientv3.LeaseGrantResponse         leaseId clientv3.LeaseID         putResp *clientv3.PutResponse         kv clientv3.KV         getResp *clientv3.GetResponse     )     //客户端配置     config = clientv3.Config{         Endpoints:   []string{"0.0.0.0:2379"}, //集群列表         DialTimeout: 5 * time.Second,     }     //建立客户端     if client, err = clientv3.New(config); err != nil {         fmt.Println(err)         return     }     //申请一个lease(租约)     lease = clientv3.NewLease(client)     //申请一个5秒的租约     if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {         fmt.Println(err)         return     }     //拿到租约的id     leaseId = leaseGrantResp.ID     //获得kv api子集     kv = clientv3.NewKV(client)     //put一个kv,让它与租约关联起来,从而实现10秒后自动过期     if putResp, err = kv.Put(context.TODO(), "/cron/lock/job1", "", clientv3.WithLease(leaseId)); err != nil {         fmt.Println(err)         return     }     fmt.Println("写入成功:", putResp.Header.Revision)     //定时看key过期没     for {         if getResp, err = kv.Get(context.TODO(), "/cron/lock/job1"); err != nil {             fmt.Println(err)             return         }         if getResp.Count == 0 {             fmt.Println("kv过期了")             break         }         fmt.Println("还没过期:", getResp.Kvs)         time.Sleep(time.Second)     } }

[root@bogon etcd]# go run demo6.go
写入成功: 27
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
还没过期: [key:"/cron/lock/job1" create_revision:27 mod_revision:27 version:1 lease:7587837741646622005 ]
kv过期了
[root@bogon etcd]#

申请一把分布式锁的时候,是谁抢到了key就是抢到了锁,如果不主动释放这锁,按道理讲不应该让租约过期,租约过期主要是为了程序宕掉之后,锁自动释放,防止程序异常退出。如果程序抢到了这个锁,我们希望锁一直不失效,知道我们主动释放它:

package main import (     "context"     "fmt"     "go.etcd.io/etcd/clientv3"     "time" ) func main() {     var (         config  clientv3.Config         client  *clientv3.Client         err     error         lease clientv3.Lease         leaseGrantResp *clientv3.LeaseGrantResponse         leaseId clientv3.LeaseID         putResp *clientv3.PutResponse         kv clientv3.KV         getResp *clientv3.GetResponse         keepResp *clientv3.LeaseKeepAliveResponse         keepRespChan <-chan *clientv3.LeaseKeepAliveResponse //只读channel     )     //客户端配置     config = clientv3.Config{         Endpoints:   []string{"0.0.0.0:2379"}, //集群列表         DialTimeout: 5 * time.Second,     }     //建立客户端     if client, err = clientv3.New(config); err != nil {         fmt.Println(err)         return     }     //申请一个lease(租约)     lease = clientv3.NewLease(client)     //申请一个5秒的租约     if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {         fmt.Println(err)         return     }     //拿到租约的id     leaseId = leaseGrantResp.ID     //(自动续租)当我们申请了租约之后,我们就可以启动一个续租     if keepRespChan, err = lease.KeepAlive(context.TODO(), leaseId); err != nil {         fmt.Println(err)         return     }     //处理续租应答的协程     go func() {         for {             select {             case keepResp = <-keepRespChan:                 if keepRespChan == nil {                     fmt.Println("租约已经失效")                     goto END                 } else { //每秒会续租一次,所以就会受到一次应答                     fmt.Println("收到自动续租应答:", keepResp.ID)                 }             }         }         END:     }()     //获得kv api子集     kv = clientv3.NewKV(client)     //put一个kv,让它与租约关联起来,从而实现10秒后自动过期     if putResp, err = kv.Put(context.TODO(), "/cron/lock/job1", "", clientv3.WithLease(leaseId)); err != nil {         fmt.Println(err)         return     }     fmt.Println("写入成功:", putResp.Header.Revision)     //定时看key过期没     for {         if getResp, err = kv.Get(context.TODO(), "/cron/lock/job1"); err != nil {             fmt.Println(err)             return         }         if getResp.Count == 0 {             fmt.Println("kv过期了")             break         }         fmt.Println("还没过期:", getResp.Kvs)         time.Sleep(time.Second)     } }

[root@bogon etcd]# go run demo7.go
写入成功: 30
收到自动续租应答: 7587837741646622039
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自动续租应答: 7587837741646622039
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自动续租应答: 7587837741646622039
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
还没过期: [key:"/cron/lock/job1" create_revision:29 mod_revision:30 version:2 lease:7587837741646622039 ]
收到自动续租应答: 7587837741646622039
......

关于etcd租约机制及自动过期的实例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI