Go语言搬砖 操作etcd

1,099 阅读3分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

前言

上一章节介绍了ectd的快速入门,这篇就说说怎么调用它的api来进行操作,本文使用Go语言实践

etcd支持v2和v3两个版本,现在使用的k8s已经使用v3了,且最新版本的k8s都是使用的v3,后续使用肯定都用v3了,紧跟潮流嘛

etcd-v3api地址: github.com/etcd-io/etc…

api-example地址: github.com/etcd-io/etc…

API例子

在粗略查看etcd clien部分源码后,发现该客户端实现的类型以下

image.png

  • Cluster:成员管理
  • KV:K-V键值操作
  • Lease:租约相关操作,租约过期会删除授权的key
  • Watcher:观察订阅,从而监听最新的数据变化
  • Auth:管理etcd的用户和权限,属于管理员操作
  • Maintenance:维护etcd,态状,快照等

针对以上的类型,该文并不会一一全部列出,只演示其中部分

创建客户端

使用的编辑器工具写代码,所以就不用下载了,直接代码引入,按下Alt+Enter 同步一下包既可,因为这是go model管理包的方式

image.png

这次不再使用init和var的方式来专明客户端了,直接写一个函数,后面谁要用,调用该函数既可

创建一个客户端

func CreateCli() *clientv3.Client {
   cli, err := clientv3.New(clientv3.Config{
      Endpoints:   []string{"10.10.1.32:2379"},
      DialTimeout: 5 * time.Second,
   })
   if err != nil {
      log.Fatalln("连接etcd失败: ", err)
   }
   log.Println("etcd-v3api连接成功")
   return cli
}
  • 使用后要关闭客户端,否则会造成goroutines泄漏

Put/Get操作

进行数据操作时,可以传入超时控制context.WithTimeout给api

调用Put和Get方法可以 设置一个k/v值以及取出该值

func PutGet() {
   cli := CreateCli()

   //创建一个5秒的超时控制
   ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5000)

   //Put数据
   _, err := cli.Put(ctx, "hello2", "world2")
   cancelFunc()
   if err != nil {
      log.Println("put数据失败: ", err)
   }
   //Get数据
   ctx2, cancelFunc2 := context.WithTimeout(context.Background(), time.Second*5000)
   resp, err := cli.Get(ctx2, "hello2")
   cancelFunc2()
   if err != nil {
      log.Println("get数据失败: ", err)
   }
   for _, v := range resp.Kvs {
      fmt.Println("get到数据是: ", v)
   }
   defer cli.Close()
}

删除一个key类似,在cli.delete 传入ctx和key的名称既可

Watch操作

因为watch属于监听的操作,不能确定数据啥时候发生变化,所以不需要设置超时控制

func watch() {
   cli := CreateCli()

   //Watch操作
   watch := cli.Watch(context.TODO(), "hello")
   for watchsp := range watch {
      for _, ev := range watchsp.Events {
         log.Println("value发生变化了: ", ev.Type, string(ev.Kv.Key), string(ev.Kv.Value))
      }
   }

   defer cli.Close()
}

将服务启动,然后修改一下数据,会得到相应返回

etcdctl --endpoints=http://127.0.0.1:2379 put hello "word3"

image.png

lease操作

etcd的租约是设置一个存活时间值来控制的。在创建key的时候带上这个参数既生效

func lease() {
   cli := CreateCli()
   //创建一个30的ttl(租约)
   grant, err := cli.Grant(context.TODO(), 30)
   if err != nil {
      log.Println("创建租约失败: ", err)
   }
   // 30秒之后,test2这个key将被删除
   _, err = cli.Put(context.TODO(), "test2", "ddd2", clientv3.WithLease(grant.ID))
   if err != nil {
      log.Println("创建带租约的key", err)
   }

   defer cli.Close()
}

keepAlive操作

还有一种情况,需要一直保持住key的ttl,则可以用使用keepalive方法设置

这个key会一直保持,当你的程序退出时key才会被删除

func keepalive() {
   cli := CreateCli()
   grant, _ := cli.Grant(context.TODO(), 5)
   _, _ = cli.Put(context.TODO(), "test3", "ddd3", clientv3.WithLease(grant.ID))
   alive, _ := cli.KeepAlive(context.TODO(), grant.ID)
   for {
      a := <-alive
      fmt.Println("ttl: ", a.TTL)
   }

   defer cli.Close()
}

状态检查

该方法不仅能操作客户端所在集群状态,还能检查任何指定的集群状态,只需要写ip替换成想要检查的ip既可

func status() {
   cli := CreateCli()

   for _, ep := range endpoints() {
      status, err := cli.Status(context.TODO(), ep)
      if err != nil {
         log.Println(err)
      }
      fmt.Println("端点: ", ep, "状态: ", status)
   }

   cli.Close()
}

func endpoints() []string {
   return []string{"ip:2379"}
}

总结

etcd的api经过以上的demo,可以看出,api的使用非常简洁和方便,很容易的就可以二次开发功能

常用的api,全部在cli是里面

image.png