golang操做etcd簡單講解

golang操做etcd簡單講解

關於etcd的詳細介紹和實戰清查看如下文章git

其餘操做請查看etcd/clientv3官方文檔github

參考連接:golang

本文僅對go操做etcd的put,get,watch過程作一下簡單介紹。json

安裝第三方庫

go get go.etcd.io/etcd/clientv3

因爲go版本等問題,可能會在安裝時報錯,具體解決方案能夠查看如下文章:c#

https://learnku.com/articles/43758數據結構

https://my.oschina.net/u/2321997/blog/4258724/printmvc

https://colobu.com/2020/04/09/accidents-of-etcd-and-go-module/app

put操做

package main

import (
	"context"
	"fmt"
	"time"

	"go.etcd.io/etcd/clientv3"
)

func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		// handle error!
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
    fmt.Println("connect to etcd success")
	defer cli.Close()
	// put
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	_, err = cli.Put(ctx, "q1mi", "dsb")
	cancel()
	if err != nil {
		fmt.Printf("put to etcd failed, err:%v\n", err)
		return
	}
}

上述代碼的邏輯步驟是:ide

  1. 調用clientv3包中的New函數,傳入參數配置對象,返回一個客戶端的client(結構體)。
  2. 構造上下文context
  3. client調用裏面字段kv接口的方法put將數據存到etcd

client的數據結構爲:函數

type Client

type Client struct {
    Cluster
    KV
    Lease
    Watcher
    Auth
    Maintenance

    // Username is a user name for authentication.
    Username string
    // Password is a password for authentication.
    Password string
    // contains filtered or unexported fields
}

kv接口的數據結構:

type KV

type KV interface {  
    Put(ctx context.Context, key, val string, opts ...OpOption) (*PutResponse, error)
    Get(ctx context.Context, key string, opts ...OpOption) (*GetResponse, error)
    Delete(ctx context.Context, key string, opts ...OpOption) (*DeleteResponse, error)
    Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)
    Do(ctx context.Context, op Op) (OpResponse, error)
    Txn(ctx context.Context) Txn
}

get操做

package main

import (
	"context"
	"fmt"
	"time"

	"go.etcd.io/etcd/clientv3"
)

func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		// handle error!
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
    fmt.Println("connect to etcd success")
	defer cli.Close()
	// get
	ctx, cancel = context.WithTimeout(context.Background(), time.Second)
	resp, err := cli.Get(ctx, "q1mi")
	cancel()
	if err != nil {
		fmt.Printf("get from etcd failed, err:%v\n", err)
		return
	}
	for _, ev := range resp.Kvs {
		fmt.Printf("%s:%s\n", ev.Key, ev.Value)
	}
}

上述代碼的邏輯步驟是:

  1. 同普通同樣,先對client初始化
  2. 建立上下文
  3. 直接調用cli.Get

這裏說一下返回值得數據結構:*GetResponse

type RangeResponse struct {
   Header *ResponseHeader `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
   // kvs is the list of key-value pairs matched by the range request.
   // kvs is empty when count is requested.
   Kvs []*mvccpb.KeyValue `protobuf:"bytes,2,rep,name=kvs,proto3" json:"kvs,omitempty"`
   // more indicates if there are more keys to return in the requested range.
   More bool `protobuf:"varint,3,opt,name=more,proto3" json:"more,omitempty"`
   // count is set to the number of keys within the range when requested.
   Count                int64    `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
   XXX_NoUnkeyedLiteral struct{} `json:"-"`
   XXX_unrecognized     []byte   `json:"-"`
   XXX_sizecache        int32    `json:"-"`
}

get返回的信息會存儲在RangeResponse結構體的Kvs字段,這是一個KeyValue結構體的指針類型切片,所以取值時要遍歷這個切片。

watch操做

package main

import (
	"context"
	"fmt"
	"time"

	"go.etcd.io/etcd/clientv3"
)

// watch demo

func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		fmt.Printf("connect to etcd failed, err:%v\n", err)
		return
	}
	fmt.Println("connect to etcd success")
	defer cli.Close()
	// watch key:q1mi change
	rch := cli.Watch(context.Background(), "q1mi") // <-chan WatchResponse
	for wresp := range rch {
		for _, ev := range wresp.Events {
			fmt.Printf("Type: %s Key:%s Value:%s\n", ev.Type, ev.Kv.Key, ev.Kv.Value)
		}
	}
}

上述代碼的邏輯步驟是:

  1. 同普通同樣,先對client初始化
  2. 建立上下文注意這裏並無用with系列函數建立上下文,而是直接用根節點context,這麼作能夠保證一直監控,知道有變化發生。
// If the context is "context.Background/TODO", returned "WatchChan" will
// not be closed and block until event is triggered, except when server
// returns a non-recoverable error (e.g. ErrCompacted).
  1. 直接調用cli.Watch

對返回值說明:

cli.Watch返回一個WatchResponse類型通道。

type WatchChan

type WatchChan <-chan WatchResponse

type WatchResponse

type WatchResponse struct {
	Header pb.ResponseHeader
	Events []*Event

	// CompactRevision is the minimum revision the watcher may receive.
	CompactRevision int64

	// Canceled is used to indicate watch failure.
	// If the watch failed and the stream was about to close, before the channel is closed,
	// the channel sends a final response that has Canceled set to true with a non-nil Err().
	Canceled bool

	// Created is used to indicate the creation of the watcher.
	Created bool
	// contains filtered or unexported fields
}

返回值存儲在WatchResponse例的Event字段中,這個一個指針類型的切片,所以取值時要遍歷此切片。

相關文章
相關標籤/搜索