浅谈 etcd 服务注册与发现
Hello 朋友们,在之前参加云原生活动的时候曾写过一篇文章《浅谈云原生技术组件—etcd》,在其中我主要说明了 etcd 在基于 Kubernetes 云原生微服务框架中的定位,主要是用来做服务的远程配置、KV 存储等等,那么今天就来简要的补充讲解下 etcd 的另一个重要的作用——服务注册和发现,没错,正是和 Zookeeper、Eureka、Consul 等拥有一样角色的开源微服务组件,且毫不逊色于这些,那么我们就开始进行讲解。
1 基于 etcd 的服务注册与发现逻辑架构
1.1 服务注册中心抽象
(图片来自网络)
Service Registry(服务注册表,通常也成为服务注册中心):内部拥有一个数据结构,用于存储已发布服务的配置信息。注册中心的作用一句话概括就是存放和调度服务的配置,实现服务和注册中心,服务和服务之间的相互通信,可以说是微服务中的”通讯录“,它记录了服务和服务地址的映射关系。
Service Requestor(服务调用者):根据服务注册中心调用已有服务。
Service Provider(服务提供者):提供服务到服务注册中心。
1.2 etcd 服务注册发现简易版
2 代码实现
2.1 总体流程
服务提供者:
(1)监听网络
(2)创建 gRPC 服务端,并将具体的服务进行注册
(3)利用服务地址、服务名等注册 etcd 服务配置
(4)gRPC 监听服务
服务消费者:
(1)注册 etcd 解析器
(2)连接 etcd 服务
(3)获取 gRPC 客户端
(4)调用 gRPC 服务
2.2 代码
2.2.1 服务提供方
2.2.2 服务消费方
2.2.3 公共组件
注意要在编译后进行使用哈
2.3 注意事项
在我编写代码进行实现的过程中遇到过种种问题,但是最让人记忆深刻的就是 etcd 与 gRPC 版本不兼容的问题,用了很长时间才搞定,在这里记录下吧:
原因是 etcd3.x 版本不支持 grpc1.27 版本以上,但是 grpc1.27 以下编译成的中间代码又不支持新版本的 proto buffer,这就陷入了一个两难的处境,最后通过 Stack Overflow 才查到:
https://stackoverflow.com/questions/64815927/undefined-grpc-clientconninterface-when-compiling-grpc
解决,在 go.mod 中加入这几行代码:
3 细节剖析
3.1 服务生产端 keepAlive
keepAlive 是一个老生常谈的问题了,下到 TCP/IP、HTTP 连接,上到 Redis 集群、MySQL 集群,都会有该机制,那么 etcd 的 keepAlive 是怎么搞的呢?
下面我们来看下:
etcd 使用 LeaseKeepAlive API 调用创建的双向流来刷新租约。当客户端希望刷新租约时,它通过流发送一个 leasekeepaliverrequest:
ID :keepAlive 有效的租约 ID。
LeaseKeepAliveResponse
作为 keepAlive 的响应:
ID :用新的 TTL 刷新的租约。
TTL :新的生存时间,以秒为单位,租约剩余的时间。
3.2 服务消费端 watch 机制
Watch API 提供了一个基于事件的接口,用于异步监视服务 key 的更改。etcd3 watch 通过持续观察给定的修订(当前的或历史的)来等待键的更改,并将键更新流回客户端。
对每个键的每次更改都用“Event”消息表示。Event 消息提供了更新的数据和更新的类型:
type:PUT 类型表示新数据的更新,DELETE 表示 key 的删除。
kv:与事件相关的键值 PUT 事件包含 kv。
prev_kv:事件发生前修改版本的密钥的键值对。为了节省带宽,它只在 watch 显式启用的情况下填写。
watch 流:
watch 是长时间运行的请求,并使用 gRPC 流来流化事件数据。watch 流是双向的;客户端写入流来建立监视,读取流来接收监视事件。通过使用每个 watch 标识符来标记事件,单个 watch 流可以将多个不同的手表组合在一起。这种多路复用有助于减少核心 etcd 集群上的内存占用和连接开销。
4 总结
微服务是当今互联网领域的广泛概念,也是一种架构演进的结果,微服务的存在让架构设计更加的解耦合,让人员的分工更加明确,当然他的落地实现也并不止步与某一两种方式,在云原生领域的 Kubernetes+etcd,互联网领域常用的 Spring Cloud 全家桶以及 Dubbo 等都是微服务的具体实现,而 etcd 也仅仅是微服务中服务注册中心组件角色的一个代表而已。
参考:
https://etcd.io/docs/v3.5/dev-guide/grpc_naming/
https://www.jianshu.com/p/217d0e3a8d0f
https://www.cnblogs.com/wujuntian/p/12838041.html
https://stackoverflow.com/questions/64815927/undefined-grpc-clientconninterface-when-compiling-grpc
版权声明: 本文为 InfoQ 作者【Barry Yan】的原创文章。
原文链接:【http://xie.infoq.cn/article/650c8c6016b00430fcf90bd86】。文章转载请联系作者。
评论