以前说了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至关于裸奔的状况:命令行
等等,这些部署策略更多针对于线上,由于官方写的很是详细了,我感受再写也就班门弄斧了。
https://doczhcn.gitbook.io/etcd/index/index-1/clusteringcode
这里来实际用代码操做一下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
其实使用起来仍是很是简单,我就不过多赘述了。