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)
}
}
}