golang使用etcd

etcd

etcd 是一个分布式开源的kv数据库,它可以监听某个键的变化,可作为注册中心、分布式锁等

1. 下载安装etcd

官网: https://github.com/etcd-io/etcd/releases

选择对应的系统下载,解压即可,下面以 Linux系统做演示

wget https://github.com/etcd-io/etcd/releases/download/v3.3.18/etcd-v3.3.18-linux-amd64.tar.gz

tar -zxvf etcd-v3.3.18-linux-amd64.tar.gz

2. 启动 etcd

etcd 默认监听在 localhost,所以为了在公网上可以访问到它,需要更改下它启动的监听地址

 nohup ./etcd --listen-client-urls 'http://0.0.0.0:2379' --advertise-client-urls 'http ://0.0.0.0:2379' &

看一下输出日志,显示下面信息即为启动成功

cat nohup.out

3. 简单使用

目前都是使用 V3版本的API,所以我们需要加一个环境变量,告诉etcd要使用V3版本的API

export ETCDCTL_API=3

3.1 增删该查

# 添加key
./etcdctl put "name" "pibigstar"
# 查询key
./etcdctl get "name"
# 删除key
./etcdctl del "name"
# 根据前缀查询key
./etcdctl get "na" --prefix
# 监听key
./etcdctl watch "name"

4. Go操作etcd

文档: https://github.com/etcd-io/etcd/tree/master/clientv3

4.1 安装sdk

go get go.etcd.io/etcd/clientv3

4.2 Go操作

package test

import (
	"context"
	"github.com/coreos/etcd/clientv3"
	"runtime"
	"testing"
	"time"
)
var (
	ctx = context.TODO()
)

func TestEtcd(t *testing.T) {
	cli, err := clientv3.New(clientv3.Config{
		// 集群列表
		Endpoints:   []string{"ip:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		t.Error(err)
	}
	defer cli.Close()

	// 监听值
	go func() {
		watch := cli.Watch(ctx, "name")
		res := <- watch
		t.Log("name发生改变", res)
	}()

	// 存值
	if resp, err := cli.Put(ctx, "name", "Hello", clientv3.WithPrevKV()); err != nil {
		t.Error(err)
	} else {
		t.Log("旧值: ",string(resp.PrevKv.Value))
	}
	// 取值
	if resp, err := cli.Get(ctx, "name", clientv3.WithPrefix()); err != nil {
		t.Error(err)
	} else {
		t.Log("count: ",resp.Count)
		t.Log("value: ",resp.Kvs)
	}

	// 改值
	if resp, err := cli.Put(ctx, "name", "pibigstar", clientv3.WithPrevKV()); err != nil {
		t.Error(err)
	} else {
		t.Log("旧值: ",string(resp.PrevKv.Value))
	}
	// 删值
	if resp, err := cli.Delete(ctx, "name"); err != nil {
		t.Error(err)
	} else {
		t.Log(resp.PrevKvs)
	}

	// 带租期的key
	lease := clientv3.NewLease(cli)
	// 申请一个5秒的租约(5s后key会被删除)
	if response, err := lease.Grant(ctx, 5); err != nil {
		t.Error(err)
	} else {

		// 自动续约
		if responses, err := lease.KeepAlive(ctx, response.ID); err == nil {
			go func() {
				for   {
					select {
					case keepResp := <-responses:
						if keepResp == nil {
							t.Log("租约已失效或context已取消")
							runtime.Goexit()
						} else {
							t.Log("自动续约...")
						}
					}
				}
			}()
		}

		if _, err := cli.Put(ctx, "age", "18", clientv3.WithLease(response.ID)); err != nil {
			t.Error(err)
		}
	}
}
发布了237 篇原创文章 · 获赞 215 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/junmoxi/article/details/103438548