etcd简介
etcd是go语言实现的分布式、高可用、强一致性、小型kv数据存储服务
可作为分布式存储仓库来存储配置信息,它读写速度快、支持高可用、部署简单、支持http接口
微服务中,各个服务的配置信息,存活状态等如何监控获知?etcd正是扮演这个角色。比如k8s就是使用etcd来做注册配置中心
etcd的应用场景
1. 配置管理 ----- 管理服务节点的注册信息
2. 服务注册 ----- 微服务中各个服务节点的信息注册
3. 服务发现 ----- 动态增添或减少新的服务节点,都可被监测到
4. leader竞选 ----- 若检测到master节点宕机,会根据raft算法在slave中选出某个替换
5. 应用调度
6. 集群监控
7. 分布式队列
8. 分布式锁 ----- 节点竞争临界资源,需通过etcd获取锁才能去操作,其他节点等待
etcd调用基本命令
// 创建/修改key
etcdctl put key value
// 获取key
// etcdctl get key
// etcdctl get key -w json 查看key具体的版本信息,以json形式输出
// 删除key
// etcdctl del key
// 监听key的状态变更,如其他节点的修改,此节点依然可监测到
// etcdctl watch key
Go调用etcd
安装客户端
// 链接地址:https://github.com/etcd-io/etcd/tree/main/client/v3
import clientv3 "go.etcd.io/etcd/client/v3"
调用示例
// 基本 put get 操作
func etcdBasicOperation() {
// 连接
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, "/serviceA/instance1", "{"host": "", "port": 7001}")
cancel()
if err != nil {
fmt.Printf("put to etcd failed, err:%v\n", err)
return
}
// get 获取
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
resp, err := cli.Get(ctx, "/serviceA/instance1")
cancel()
if err != nil {
fmt.Printf("get from etcd failed, err:%v\n", err)
return
}
for _, ev := range resp.Kvs {
fmt.Println(" KeyValue struct---------\n", ev.Key, ev.Value, ev.CreateRevision, ev.ModRevision, ev.Lease)
}
}
监听示例
func useWatch() {
// 连接
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 change 监听 key 的变化
rch := cli.Watch(context.Background(), "key1") // <-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)
}
}
}
python调用etcd
安装
# 链接地址:https://python-etcd3.readthedocs.io/en/latest/
pip install etcd3
调用示例
client = etcd3.client(host="192.168.1.7", port=2379, user='root', password='Root123456')
# put 创建
client.put("/name", "ttest")
# get 获取
v, path = client.get("/name")
print(v.decode("utf-8"))
print(path.key.decode())
# 创建租约
my_lease = client.lease(ttl=30, lease_id=303030) # id只能用数字表示
# 通过 id 打印租期的相关信息
lease_info = client.get_lease_info(303030)
print(lease_info)
# put 创建时并指定租约
client.put('/test', '我只能存活30秒', lease=my_lease)
# watch 监听
iterators, cancel = client.watch('/name') # 返回一个事件迭代器和一个取消触发器
for event in iterators:
print(event.value.decode())
nodejs调用etcd
安装
// 链接地址:https://github.com/microsoft/etcd3
npm install --save etcd3
调用示例
const { Etcd3 } = require('etcd3');
const client = new Etcd3({
hosts: 'http://localhost:2379',
auth: {
username: 'root',
password: '123456',
},
});
(async () => {
// 创建 serviceA 的实例1
await client
.put('/serviceA/instance1')
.value(JSON.stringify({ host: '192.198.1.11', port: 7001 }));
// 创建 serviceA 的实例2
await client
.put('/serviceA/instance2')
.value(JSON.stringify({ host: '192.198.1.11', port: 7002 }));
// 获取 serviceA 的实例1
const sAi1 = await client.get('/serviceA/instance1').string();
console.log('sAi1 ----> ', sAi1);
// 获取前缀为 serviceA 的所有实例
const sA = await client.getAll().prefix('/serviceA').keys();
console.log('sA ----> ', sA);
// 删除
// await client.delete().all();
// 监听
const watcher = await client.watch().key('/service/instance1').create();
watcher.on('put', req => {
console.log('put', req.value.toString());
});
watcher.on('delete', req => {
console.log('delete');
});
//
})();