etcd常见问题汇总

1、使用etcd clientV3 写入,etcdctl读取不到问题

使用github.com\coreos\etcd\clientv3\example_kv_test.go

func ExampleKV_put() {
  cli, err := clientv3.New(clientv3.Config{
      Endpoints:  endpoints,
      DialTimeout: dialTimeout,
  })
  if err != nil {
      log.Fatal(err)
  }
  defer cli.Close()

  ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
  _, err = cli.Put(ctx, "sample_key", "sample_value")
  cancel()
  if err != nil {
      log.Fatal(err)
  }
}

使用命令行etcdctl 死活获取不到:

./etcdctl  get "sample_key"

提示Error: 100: Key not found

使用命令行set/get是正常的:

./etcdctl set "foo" "bar"
./etcdctl  get "foo"

原因:需要设置etcdctl的api版本号,v2和v3不同版本,数据是不互通的。

export ETCDCTL_API=3

2、keepalive不生效问题

代码如下:

func Register(dir string, value string) {

    var (
        dialTimeout    = 5 * time.Second
        endpoints      = []string{"127.0.0.1:2379"}
    )
    cli, err := clientv3.New(clientv3.Config{
        Endpoints:  endpoints,
        DialTimeout: dialTimeout,
    })
    if err != nil {
        log.Fatal(err)
    }
    defer cli.Close()

    resp, err := cli.Grant(context.TODO(), 5)
    if err != nil {
        log.Fatal(err)
    }

    _, err = cli.Put(context.TODO(), dir, value, clientv3.WithLease(resp.ID))
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.ID)
    fmt.Println("ttl:")
    // the key 'foo' will be kept forever
    ch, kaerr := cli.KeepAlive(context.TODO(), resp.ID)
    if kaerr != nil {
        log.Fatal(kaerr)
    }

    ka := <-ch

    fmt.Println("ttl:", ka.TTL)
    // Output: ttl: 5
    gresp, err := cli.Get(context.TODO(),dir,clientv3.WithLease(resp.ID))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(gresp.Kvs)
    fmt.Println("number of keys:", len(gresp.Kvs))

}

现象:执行完这个方法后keepalive 的节点会立马删除,百思不得其解。
原因:方法执行完后直接close了
defer cli.Close()
解决方法:应该把 cli 设置为全局的,不进行销毁

你可能感兴趣的:(后端)