etcd 服务注册与发现(一)
1 Preface
最近 C++ 后台微服务组件,考虑使用etcd集群,替换 zookeeper 集群。
这篇先讨论实现服务的注册与发现,节点的上线和下线通知。后面讨论服务的负载均衡。
etcd基于raft协议,通过复制日志文件的方式来保证数据的强一致性。 在etcd之前,常用的是基于 paxos 协议的 zookeeper。
2 etcd 介绍
etcd是一个golang编写的分布式、高可用的一致性键值存储系统,用于提供可靠的分布式键值(key-value)存储、配置共享和服务发现等功能。 etcd可以用于存储关键数据和实现分布式调度,在现代化的集群运行中能够起到关键性的作用。
2.1 etcd 应用场景
- 服务注册,发现
- 负载均衡等
3 服务注册与发现-方案
我们的微服务采用C++编写,一种思路是考虑使用 etcd v3 C/C++ Client API 和ectd 直接通信;
另一个思路就是考虑兼容zookeeper。
3.1 方案一: 使用etcd Client API
etcd 采用golang 编写,v3版本通信采用grpc API,即(HTTP2+protobuf);
官方只维护了go语言版本的client库, 可以找到C/C++ 非官方的client 开发库:
C libraries
- apache/celix/etcdlib - Supports v2
- jdarcy/etcd-api - Supports v2
- shafreeck/cetcd - Supports v2
C++ libraries
- edwardcapriolo/etcdcpp - Supports v2
- suryanathan/etcdcpp - Supports v2 (with waits)
- nokia/etcd-cpp-api - Supports v2
- nokia/etcd-cpp-apiv3 - Supports v3
那么现阶段,可以使用的有nokia/etcd-cpp-apiv3,使用etcd-cpp-apiv3和etcd进行通信。
编译
etcd-cpp-apiv3 依赖 boost(v1.61.0),cpprestsdk,grpc, protobuf,微软的cpprestsdk在centos没有安装包,需要先编译安装。
|
|
观察一个节点的状态:
|
|
优点:
不需要引入一个独立的服务组件。
缺点:
(1) 将etcd client 内嵌在uv服务中, 增加了耦合性;
(2) 需要引入多个第三方库:boost, cpprestsdk, grpc等。
3.2 方案二: 采用zetcd, 将zookeeper请求转换为etcd请求
zetcd 兼容zookeeper协议,可采用zetcd和etcd 进行通信,而客户端仍然采用zookeeper client API。
1 先启动 etcd 服务
etcd
2 然后启动zetcd
go get github.com/etcd-io/zetcd/cmd/zetcd
zetcd –zkaddr 0.0.0.0:2181 –endpoints localhost:2379
参数说明:
- –zkaddr 侦听一个地址为zookeeper 客户端提供服务
- –endpoints etcd3供客户端连接的地址,如果是多个地址,用英文逗号分隔
3 我们可以用zkctl
测试工具,监控节点状态:
go get github.com/etcd-io/zetcd/cmd/zkctl
zkctl watch /xc/demo
4 启动我们的服务,并配置zookeeper的地址为zetcd 侦听的IP地址:
uvframe start /etc/uvframe/demo.xml
uvframe start /etc/uvframe/demo01.xml
测试结果
经过上面的测试,可以正常通过 UVZookeeper + zetcd,实现服务的注册与发现,以及节点的掉线/上线通知。
优点:
1 使用现有UvZookeeper模板类,即可做到服务的注册与发现。
2 使用独立的组件能够松耦合。
缺点:
需要引入一个独立第三方组件zetcd。
4 总结
上面我们调研了2种方案对接etcd,由于之前我们把 zookeeper client 集成到了 libuv 的 loop 中, 第二个方案能够兼容我们现有的业务模块,而无需修改代码。 通过 zetcd,我们的服务既支持 zookeeper 集群,又能采用etcd集群。
5 Reference
- etcd
- zetcd
- nokia/etcd-cpp-apiv3 - Supports v3
《全文完》