zookeeper 客户端_【go语言】一文轻松实现ZooKeeper的客户端操作

ZooKeeper是分布式协调服务,用处非常广,例如消息系统kafka、大数据hadoop、分布式数据库hbase、搜索引擎solr、分布式资源管理框架mesos等。同类产品有etcd、consul、eureka,大体功能是服务注册和发现,比如用在微服务框架中。ZooKeeper源码是用java来实现的,第三方比较好用的客户端也是java实现的,比如curator和zkclient。

在编写go示例代码前,先安装zookeeper包:

# go get github.com/samuel/go-zookeeper/zk

请看示例代码:

package main
​
import (
  "fmt"
  "github.com/samuel/go-zookeeper/zk"
  "log"
  "os"
  "time"
)
​
// 定义常量
const (
  AUTH_USER = "fullstackcareer"
  AUTH_PWD = "FullStackCareer"
  PATH = "/fullstackcareer"
  DATA1 = "data1"
  DATA2 = "data2"
)
​
// 定义客户端结构体
type ZkClient struct {
  ConnectString []string
  ZkConn *zk.Conn
  zkAcl []zk.ACL
}
​
// 新建客户端
func NewZkClient(connectString []string) *ZkClient {
  client :=ZkClient{
    ConnectString: connectString[:],
    ZkConn:        nil,
    zkAcl:         zk.DigestACL(zk.PermAll, AUTH_USER, AUTH_PWD),
  }
  return &client
}
​
// 关闭客户端
func (client *ZkClient) Close() error {
  if client.ZkConn != nil {
    client.ZkConn.Close()
  }
  return nil
}
​
// 创建连接
func(client *ZkClient) Connect(sessionTimeout time.Duration) error {
  // 判断连接是否存在
  if client.ZkConn != nil {
    client.Close()
  }
​
  // 创建连接
  c, _, err :=zk.Connect(client.ConnectString, sessionTimeout)
  if err != nil {
    return err
  }
​
  // ACL 认证
  auth :=AUTH_USER + ":" + AUTH_PWD
  if err := c.AddAuth("digest", []byte(auth)); err != nil {
    client.Close()
    return err
  }
​
  // 赋值到结构体变量,复用该连接
  client.ZkConn = c
  return nil
}
​
// 创建 znode
func (client *ZkClient) Create(path string, data []byte) error {
  _, err := client.ZkConn.Create(path, data, 0, client.zkAcl)
  return err
}
​
// 判断 znode 是否存在
func (client *ZkClient) Exist(path string) (bool, error) {
  isExist, _, err := client.ZkConn.Exists(path)
  return isExist, err
}
​
// 设置 znode 值
func (client *ZkClient) Set(path string, data []byte, version int32) error {
  _, err :=client.ZkConn.Set(path, data, version)
  return err
}
​
// 获取 znode 的值
func (client *ZkClient) Get(path string) (string, error) {
  data, _, err := client.ZkConn.Get(path)
  return string(data), err
}
​
// 删除 znode
func (client *ZkClient) delete(path string) error {
  err := client.ZkConn.Delete(path, -1)
  return err
}
​
func main() {
  // 传参合法性判断
  if len(os.Args) != 2 {
    fmt.Println("usage: ", os.Args[0], "connectString")
    os.Exit(-1)
  }
  connectString := []string{os.Args[1]}
​
  // 创建客户端
  zkClient := NewZkClient(connectString)
  if zkClient != nil {
    log.Println("创建zookeeper客户端成功")
  } else {
    log.Fatal("创建zookeeper客户端失败")
  }
​
  // 创建连接
  err := zkClient.Connect(60 * time.Second)
  if err != nil {
    log.Fatal("创建zookeeper连接失败")
  } else {
    log.Println("创建zookeeper连接成功")
  }
​
  // 创建 znode
  err = zkClient.Create(PATH, []byte(DATA1))
  if err != nil {
    log.Fatal("创建 " + PATH + " 失败")
  } else {
    log.Println("创建 " + PATH + " 成功")
  }
​
  // 判断 znode 是否存在
  isExist, err := zkClient.Exist(PATH)
  if err == nil {
    if isExist == true {
      log.Println("znode " + PATH + " 存在")
    } else {
      log.Fatal("znode " + PATH + " 不存在")
    }
  }
​
  // 设置 znode 的值
  err = zkClient.Set(PATH, []byte(DATA2), -1)
  if err != nil {
    log.Fatal("设置 znode " + PATH + " 值 " + DATA2 + " 失败")
  } else {
    log.Println("设置 znode " + PATH + " 值 " + DATA2 + " 成功")
  }
​
  // 获取 znode 的值
  data, err := zkClient.Get(PATH)
  if err != nil {
    log.Fatal("获取 znode " + PATH + "值失败")
  } else {
    log.Print("获取 znode " + PATH + "值为 " + data)
  }
​
  // 删除 znode
  err = zkClient.delete(PATH)
  if err != nil {
    log.Fatal("删除 znode " + PATH + " 失败")
  } else {
    log.Println("删除 znode " + PATH + " 成功")
  }
​
  // 关闭客户端
  err = zkClient.Close()
  if err == nil {
    log.Println("关闭客户端成功")
  }
}

编译代码,执行:

# go build zookeeper.go
# ./zookeeper localhost:2181
2020/02/16 17:44:13 创建zookeeper客户端成功
2020/02/16 17:44:13 Connected to [::1]:2181
2020/02/16 17:44:13 authenticated: id=72057621439774727, timeout=40000
2020/02/16 17:44:13 re-submitting `0` credentials after reconnect
2020/02/16 17:44:13 创建zookeeper连接成功
2020/02/16 17:44:13 创建 /fullstackcareer 成功
2020/02/16 17:44:13 znode /fullstackcareer 存在
2020/02/16 17:44:13 设置 znode /fullstackcareer 值 data2 成功
2020/02/16 17:44:13 获取 znode /fullstackcareer值为 data2
2020/02/16 17:44:13 删除 znode /fullstackcareer 成功
2020/02/16 17:44:13 recv loop terminated: err=EOF
2020/02/16 17:44:13 send loop terminated: err=<nil>
2020/02/16 17:44:13 关闭客户端成功

总结

本文的示例代码实现了对ZooKeeper常见的操作,包括创建客户端、创建连接、创建znode、判断znode是否存在、更新znode值、获取znode值、关闭客户端。需要注意的是,文中的代码是利用面向对象的思维设计的,在实际工作中也有参考意义。

1b0f19f93f53a53960c13cbaf5bbec7d.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值