淺入深出ETCD之【集羣部署與golang客戶端使用】

前言

以前說了etcd的簡介,命令行使用,一些基本原理。此次來講說現實一點的集羣部署和golang版本的客戶端使用。由於在實際使用過程當中,etcd的節點確定是須要2N+1個進行部署的,因此有必要說明一下集羣的部署。linux

集羣部署

網上有不少集羣部署的教程,有的很複雜,其實對於咱們實際使用來講,其實配置並不複雜,下面舉例一種最簡單的集羣配置。(簡單到你想不到~)git

下載

https://github.com/etcd-io/etcd/releases
仍是在github上面找到須要下載的版本
我使用的是etcd-v3.3.13-linux-amd64.tar.gz
使用wget下載到linux你喜歡的目錄,或者本地下載完成以後上傳都可。github

部署

首先我找了三臺機器,對應ip爲
192.168.4.224
192.168.4.225
192.168.4.226
PS:提醒一下記得開發對應防火牆的端口golang

而後將下載的文件解壓,以後進入解壓後的目錄,分別使用下面的命令啓動。(注意下面的命令對應的是三臺不一樣的機器,你須要修改對應爲你本身的ip)bash

$ ./etcd --name infra0 --initial-advertise-peer-urls http://192.168.4.224:2380 \
--listen-peer-urls http://192.168.4.224:2380 \
--listen-client-urls http://192.168.4.224:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.4.224:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://192.168.4.224:2380,infra1=http://192.168.4.225:2380,infra2=http://192.168.4.226:2380 \
--initial-cluster-state new

$ ./etcd --name infra1 --initial-advertise-peer-urls http://192.168.4.225:2380 \
--listen-peer-urls http://192.168.4.225:2380 \
--listen-client-urls http://192.168.4.225:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.4.225:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://192.168.4.224:2380,infra1=http://192.168.4.225:2380,infra2=http://192.168.4.226:2380 \
--initial-cluster-state new

$ ./etcd --name infra2 --initial-advertise-peer-urls http://192.168.4.226:2380 \
--listen-peer-urls http://192.168.4.226:2380 \
--listen-client-urls http://192.168.4.226:2379,http://127.0.0.1:2379 \
--advertise-client-urls http://192.168.4.226:2379 \
--initial-cluster-token etcd-cluster-1 \
--initial-cluster infra0=http://192.168.4.224:2380,infra1=http://192.168.4.225:2380,infra2=http://192.168.4.226:2380 \
--initial-cluster-state new

至此,三個節點的集羣部署完成。😂😂😂沒錯就是這麼easy,沒有網上說的那麼複雜。mvc

配置文件

若是你嫌棄每次使用這麼長的命令進行啓動,你能夠將它寫爲配置文件:加密

# 當前節點名稱
name: infra1
# etcd數據保存目錄
data-dir: /usr/local/etcd

# 供外部客戶端使用的url
listen-client-urls: http://192.168.4.225:2379,http://127.0.0.1:2379
# 廣播給外部客戶端使用的url
advertise-client-urls: http://192.168.4.225:2379

# 集羣內部通訊使用的URL
listen-peer-urls: http://192.168.4.225:2380
# 廣播給集羣內其餘成員訪問的URL
initial-advertise-peer-urls: http://192.168.4.225:2380

# 集羣的名稱
initial-cluster-token: etcd-cluster-1
# 初始集羣成員列表
initial-cluster: infra0=http://192.168.4.224:2380,infra1=http://192.168.4.225:2380,infra2=http://192.168.4.226:2380

#初始集羣狀態
initial-cluster-state: new

而後指定配置文件的路徑進行啓動就能夠了url

./etcd --config-file=conf.yml

其餘部署策略

以上的部署一方面,我我的部署時使用的最簡單方式,更簡單的多是使用yum進行etcd的下載。
固然上述方式也存在一些問題,如今的etcd至關於裸奔的狀況:命令行

  • 沒有鑑權就想到於任何人知道ip和端口就能夠鏈接上你的etcd,因此當前可能只適用於內網使用,服務經過內網ip進行訪問(這個能夠經過添加權限和用戶來完成)
  • 當前通訊是沒有加密的
  • 當前etcd是利用靜態ip來進行配置的,我認爲這也是實際中用到最普通的狀況,可是etcd還提供發現機制來進行部署和配置,更加靈活

等等,這些部署策略更多針對於線上,由於官方寫的很是詳細了,我感受再寫也就班門弄斧了。
https://doczhcn.gitbook.io/etcd/index/index-1/clusteringcode

Golang客戶端使用

這裏來實際用代碼操做一下etcd,仍是和以前使用命令行同樣,get/put/del/watch/lease用一下這些操做,其餘操做請查看doc
https://godoc.org/github.com/coreos/etcd/clientv3

客戶端下載

這裏不建議使用go get進行下載,真的太慢了,能夠直接從github上面下載以後放到對應目錄快一些。https://github.com/etcd-io/etcd
下載解壓以後放到gopath下對應:go/src/go.etcd.io/etcd

代碼

package main

import (
    "context"
    "fmt"
    "go.etcd.io/etcd/clientv3"
    "go.etcd.io/etcd/mvcc/mvccpb"
    "time"
)

func main() {
    // 配置客戶端鏈接
    client, err := clientv3.New(clientv3.Config{
        // Endpoints:   []string{"127.0.0.1:2379"},
        Endpoints:   []string{"192.168.4.224:2379", "192.168.4.225:2379", "192.168.4.226:2379"},
        DialTimeout: 5 * time.Second,
    })
    if err != nil {
        panic(err)
    }
    defer client.Close()

    // 啓動watch監聽
    watch := client.Watch(context.TODO(), "aaa")
    go func() {
        for {
            watchResponse := <- watch
            for _, ev := range watchResponse.Events {
                switch ev.Type {
                case mvccpb.DELETE:
                    fmt.Printf("監聽到del:%s\n", ev.Kv.Key)
                case mvccpb.PUT:
                    fmt.Printf("監聽到put:%s, %s\n", ev.Kv.Key, ev.Kv.Value)
                }
            }
        }
    }()

    // 新增
    putResponse, err := client.Put(context.TODO(), "aaa", "xxx")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(putResponse.Header.String())

    // 查詢
    getResponse, err := client.Get(context.TODO(), "aaa")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(getResponse.Kvs)

    // 刪除
    deleteResponse, err := client.Delete(context.TODO(), "aaa")
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(deleteResponse.Header.String())

    // 申請租約
    grantResponse, err := client.Grant(context.TODO(), 10)
    if err != nil {
        fmt.Println(err)
        return
    }

    // 使用租約
    response, err := client.Put(context.TODO(), "aaa", "xxx", clientv3.WithLease(grantResponse.ID))
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(response.Header.String())
    
    // 等待租約自動過時
    time.Sleep(time.Second * 20)
}

大體能獲得如下輸出

監聽到put:aaa, xxx
cluster_id:14841639068965178418 member_id:10276657743932975437 revision:53 raft_term:4
[key:"aaa" create_revision:53 mod_revision:53 version:1 value:"xxx" ]
監聽到del:aaa
cluster_id:14841639068965178418 member_id:10276657743932975437 revision:54 raft_term:4
監聽到put:aaa, xxx
cluster_id:14841639068965178418 member_id:10276657743932975437 revision:55 raft_term:4
監聽到del:aaa

其實使用起來仍是很是簡單,我就不過多贅述了。

相關文章
相關標籤/搜索