内容简介:对于实现分布式乐观锁非常重要。如果锁了,突然宕机了,锁是需要自动释放的。所以这锁在etcd里是需要生命期的。过期演示:[root@bogon etcd]# go run demo6.go
对于实现分布式乐观锁非常重要。如果锁了,突然宕机了,锁是需要自动释放的。所以这锁在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
......
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- HDFS Lease(租约)逻辑
- 分布式系统中的 lease(租约)机制
- golang 操作etcd租约以及监听kv变化
- 理解golang调度之一 :操作系统调度
- 理解golang调度之二 :Go调度器
- Golang 源码学习调度逻辑(三):工作线程的执行流程与调度循环
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Design Handbook
Baeck, Philippe de 编 / 2009-12 / $ 22.54
This non-technical book brings together contemporary web design's latest and most original creative examples in the areas of services, media, blogs, contacts, links and jobs. It also traces the latest......一起来看看 《Web Design Handbook》 这本书的介绍吧!