内容简介:对于实现分布式乐观锁非常重要。如果锁了,突然宕机了,锁是需要自动释放的。所以这锁在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
......
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Building Web Reputation Systems
Randy Farmer、Bryce Glass / Yahoo Press / 2010 / GBP 31.99
What do Amazon's product reviews, eBay's feedback score system, Slashdot's Karma System, and Xbox Live's Achievements have in common? They're all examples of successful reputation systems that enable ......一起来看看 《Building Web Reputation Systems》 这本书的介绍吧!