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)


}

你可能感兴趣的:(etcd中lease(租约)的使用(类比redis中的expire但是远比expire强大))