Etcdv3 client watcher原理分析
Posted 惜暮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Etcdv3 client watcher原理分析相关的知识,希望对你有一定的参考价值。
Etcdv3 client watcher原理分析
背景
最近在实现高可用流控防护组件sentinel的golang版本 ,扩展数据源这一块,在golang生态里面是etcd是非常重要的一个角色。需求是这样,每个集成sentinel的app instance会与etcd建立长连接来做动态数据源的更新。由于动态数据源的类型有多个,在Java版本中,每个动态数据源都会去建立一个长连接,长连接对于etcd来说是非常珍贵的系统资源,所以期待对于一个app instance的多个数据源共享一个长连接。然后利用etcd的watcher机制的实现动态数据源的动态更新。
etcdv3 client watcher整体架构
etcd 的Client和Server是通过 gRPC 来做数据通信的,etcdv3 client使用双向的stream的长连接与Server端保持通信。
etcdv3 client watcher整体架构图如下:
这里主要对整体架构模型做一些解释:
- Client使用一个Watcher实例去监听 Server 的key,这里client与watcher的关系是组合关系,也就是client是包含watcher能力,通过一个watcher实例可以watch 多个 key。
- 每个watcher会持有一个gRPC的长连接(有一些GRPC context相关特殊逻辑存在多个WatcherGrpcStream情况,这里不做说明了。),WatcherGrpcStream里面主要有两个channel,一个用于发送watch reuqest, 一个用于接收watch response。
- WatcherGrpcStream会启动一个协程专门用于通过 gRPC client stream 接收Server端的 watch response,然后将watch response send 到WatcherGrpcStream的watch response channel。
- WatcherGrpcStream 也有一个专门的 协程专门用于从watch response channel 读数据,拿到watch response之后,会根据response里面的watchId 从WatcherGrpcStream的map[watchID] WatcherStream 中拿到对应的WatcherStream,并send到WatcherStream里面的WatchReponse channel。
- 这里的watchId其实是Server端返回给client端的,当client Send Watch request给Server端时候,response会带上watchId, 这个watchId是与watch key是一一对应关系,然后client会建立WatchId与WatcherStream的映射关系。
- WatcherStream是具体的 watch response的处理结构,对于每个watch key,WatcherGrpcStream 也会启动一个专门的协程处理WatcherStream里面的watch response channel。
- WatcherStream里面存在一个 buffer, 作为缓冲内存。WatcherStream的协程会将watch response 从缓冲buffer取出然后放到用户监听的watch response channel。
- 用户只需要 read response channel 就可以拿到watch response。
所以上面主要模型就是两个:
WatcherGrpcStream:负责从stream里面读watch response,然后根据watchId做dispatch到映射的WatcherStream。
WatcherStream:负责处理key对应的watch response, 通过一个缓冲保证处理的吞吐量,然后将response 透传给用户处理。
这里是一些high level的模型解释,下面是通过具体的源码来分析设计。
源码分析
这里先贴出一个watcher机制详细的数据流的走向图:
TODO: 代码分析
以上是关于Etcdv3 client watcher原理分析的主要内容,如果未能解决你的问题,请参考以下文章