Golang 实现etcd键值对的写入查看,并在租约时间内存在

etcd版本3.2,开放端口2379

package main

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

func main() {

	const (
		key1 = "/etc/etcd/etcd.conf"
		val2 = "etcd.conf"
		keepTime = 100*time.Second //续租时长
	)
	var (
		config        clientv3.Config
		client        *clientv3.Client
		Newlease      clientv3.Lease
		leaseResp     *clientv3.LeaseGrantResponse
		kv            clientv3.KV
		err           error
		putResp       *clientv3.PutResponse
		getResp       *clientv3.GetResponse
		keepaliveResp *clientv3.LeaseKeepAliveResponse
		keepRespChan  <-chan *clientv3.LeaseKeepAliveResponse
	)

	config = clientv3.Config{
		Endpoints:   []string{"192.168.1.102:2379"},
		DialTimeout: 10 * time.Second,
	}

	if client, err = clientv3.New(config); err != nil {
		fmt.Println(err)
		return
	}
	Newlease = clientv3.NewLease(client) // 创建新的租约
	//申请租约
	if leaseResp, err = Newlease.Grant(context.TODO(), 10); err != nil {
		fmt.Println(err)
		return
	}
	leaseID := leaseResp.ID //得到租约ID
	
	//为续租提供上下文,使得我们可以控制续租时长
	ctx, _ := context.WithTimeout(context.TODO(), keepTime) 
	//续租
	if keepRespChan, err = Newlease.KeepAlive(ctx, leaseID); err != nil {
		fmt.Println(err)
		return
	}
	// 起协程,消费续租 续租会在一个只读的chan中产生LeaseKeepAliveResponse结构体信息
	// 一般每隔一秒发送一次
	// 当 通道 中的LeaseKeepAliveResponse没有时,表明租约终止
	go func() {
		for {
			select {
			case keepaliveResp = <-keepRespChan:
				if keepRespChan == nil {
					fmt.Println("租约终止.")
					goto END
				} else {
					fmt.Println("收到续租应答.", keepaliveResp.ID)
				}
			}
		}
	END:
	}()
	//创建KV
	kv = client.KV
	putResp, err = kv.Put(context.TODO(), key1, val2, clientv3.WithLease(leaseID))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("写入成功: Revision ->", putResp.Header.Revision)
	// 使用循环查看键值对情况
	for {
		if getResp, err = kv.Get(context.TODO(), key1); err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println("值:", getResp.Kvs)
		if getResp.Count == 0 {
			fmt.Println("租约过期了")
			break
		}
		time.Sleep(2 * time.Second)
		fmt.Println(time.Now())
	}
}