etcd中lease(租约)的使用(类比redis中的expire但是远比expire强大)

少比比直接代码(你可以理解为给key设置过期时间,但是比redis要强大的是它可以自动续租)

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    "go.etcd.io/etcd/mvcc/mvccpb"
    "time"
)

func main() {
var (
        config clientv3.Config
        client *clientv3.Client
        err error
        kv clientv3.KV
        keepResp *clientv3.LeaseKeepAliveResponse
        keepRespChan <-chan *clientv3.LeaseKeepAliveResponse
    )
        //创建租约
    lease := clientv3.NewLease(client)
        //判断是否有问题
        if leaseRes,err := lease.Grant(context.TODO(),10);err != nil {
        fmt.Println(err)
        return
    } else {
                //得到租约id
        leaseId := leaseRes.ID

        //定义一个上下文使得租约5秒过期
        ctx,_:= context.WithTimeout(context.TODO(),5*time.Second)

        //自动续租(底层会每次讲租约信息扔到 <-chan *clientv3.LeaseKeepAliveResponse 这个管道中)
        if keepRespChan,err = lease.KeepAlive(ctx,leaseId);err != nil {
            fmt.Println(err)
            return
        }
                //启动一个新的协程来select这个管道
        go func() {
            for {
                select {
                case keepResp = <- keepRespChan:
                    if keepResp == nil {
                        fmt.Println("租约失效了")
                        goto END//失效跳出循环
                    } else {
                                              //每秒收到一次应答
                        fmt.Println("收到租约应答",keepResp.ID)
                    }

                }
            }
            END:
        }()
                //得到操作键值对的kv
        kv = clientv3.NewKV(client)
                //进行写操作
        if putResp,err = kv.Put(context.TODO(),"/cron/lock/job1","",clientv3.WithLease(leaseId)/*高速etcd这个key对应的租约*/);err != nil {
            fmt.Println(err)
            return
        } else {
            fmt.Println("写入成功",putResp.Header.Revision/*这东西你可以理解为每次操作的id*/)
        }
    }
        //监听这个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("kv没过期",getResp.Kvs)
        time.Sleep(2 * time.Second)


}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 超强、超详细Redis入门教程 转载2017年03月04日 16:20:02 16916 转载自: http://...
    邵云涛阅读 17,535评论 3 313
  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 3,449评论 0 40
  • 文章已经放到github上 ,如果对您有帮助 请给个star[https://github.com/qqxuanl...
    尼尔君阅读 2,296评论 0 22
  • 【本教程目录】 1.redis是什么2.redis的作者3.谁在使用redis4.学会安装redis5.学会启动r...
    徐猿猿阅读 1,885评论 0 35
  • 1.感谢新来的小伙伴,为我分担一些事务性工作,这些天忙,也没好好教他,谢谢他的主动与理解 2.感谢哥哥,还有哥哥师...
    小窗幽记_hj阅读 170评论 0 0