Resolver
gRPC 插件式编程之Resolver
随着微服务越来越盛行,服务间的通信也是绕不开的话题,gRPC 在众多 RPC 框架中算得上佼佼者,不仅其有一个好爸爸,grpc 在扩展方面也给开发者留
有足够的空间,今天我们将走进grpc 扩展之 Resolver,gRPC Resolver 提供了用户自行解析主机的扩展能力,我们在使用 gRPC 时,大家有没有想过,
为什么 gRPC 为什么支持以下几种格式的 target:
- 直连, 链接 target 为目标服务的endpoint
- dns 服务发现
- unix
其中在进入连接之前,gRPC 会根据用户是否提供了 Resolver 来进行目标服务的 endpoint 解析,今天我们来尝试写一个最简单的 etcd 做服务发现的例子
说明
源码阅读的 gRPC 版本为 3.5.1
环境
- etcd 安装
- go
思路
- 我们将为 server 服务,假设名称为
grpc-server
启动多个实例 - 以
grpc-server
为 key 向 etcd put 每个实例的 endpoint- 真正进入 etcd 的 key 为以
grpc-server
+/
+随机值
- 真正进入 etcd 的 key 为以
- 实现 resolver.Builder, 获取
target
- 从 etcd 读取以
grpc-server
为 prefix 的 endpoints - 通知负载均衡器重新 pick 实例
实现
实现 resolver.Builder
type customBuilder struct {
scheme string
}
func NewCustomBuilder(scheme string) resolver.Builder {
return &customBuilder{
scheme: scheme,
}
}
func (b *customBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
var address []resolver.Address
key := target.URL.Host
hosts := pool.GetOr(key, nil)
fmt.Println