自定义名称解析

介绍了标准名称解析、自定义名称解析器接口以及如何编写实现。

自定义名称解析

介绍了标准名称解析、自定义名称解析器接口以及如何编写实现。

概述

名称解析从根本上讲是关于服务发现的。在发送 gRPC 请求时,客户端必须确定服务名称对应的 IP 地址。名称解析通常被认为是与 DNS 等同的。但在实践中,DNS 通常会通过扩展来增强,甚至被完全替换,以实现名称解析。

当使用 gRPC 客户端发起请求时,默认使用 DNS 名称解析。不过,也可以使用各种其他名称解析机制:

解析器示例备注
DNSgrpc.io:50051默认假定使用 DNS。
DNSdns:///grpc.org.cn:50051额外的斜杠用于提供授权信息(Authority)
Unix 域套接字unix:///run/containerd/containerd.sock
xDSxds:///wallet.grpcwallet.io
IPv4ipv4:198.51.100.123:50051仅在部分语言中受支持

多种语言支持一个允许用户定义自定义名称解析器的接口,以便你可以自行定义如何解析给定的名称。一旦注册,当目标字符串以 my-resolver: 开头时,方案(scheme)为 my-resolver 的名称解析器就会被启用。例如,对 my-resolver:///my-service 的请求现在将使用 my-resolver 名称解析器的实现。

自定义名称解析器

当你希望增强或替代 DNS 进行服务发现时,可以考虑使用自定义名称解析器。例如,该接口过去曾被用于利用 Apache Zookeeper 来查找服务名称。它也被用于直接与 Kubernetes API 服务器对接,基于 Headless Service 资源进行服务查找。

使用自定义名称解析器而不是标准 DNS 的一个特别有用的原因是该接口是反应式(reactive)的。在标准 DNS 中,客户端在连接开始时查找特定服务的地址,并在连接的生命周期内维持与该地址的连接。然而,自定义名称解析器可以是基于监视(watch-based)的。也就是说,它们可以随着时间的推移从名称服务器接收更新,因此能够智能地应对后端故障以及后端的扩容和缩容。

此外,自定义名称解析器可以为客户端连接提供服务配置(service config)。服务配置是一个 JSON 对象,定义了任意配置,规定了流量应如何路由以及如何在特定服务之间进行负载均衡。最基本的情况下,它可以用于指定诸如特定服务应使用轮询(round robin)负载均衡策略还是优先选择(pick first)策略。但是,当自定义名称解析器与任意服务配置以及 自定义负载均衡策略 结合使用时,可以构建出如 xDS 那样非常复杂的流量管理系统。

目标字符串的生命周期

虽然自定义名称解析器的具体接口在不同语言中有所不同,但总体结构是一致的。客户端在进程启动时将名称解析器提供程序(name resolver provider)的实现注册到进程全局的注册表中。当 gRPC 库遇到旨在用于自定义名称解析器的目标字符串时,就会调用该名称解析器提供程序。基于给定的目标字符串,名称解析器提供程序将返回一个名称解析器实例,该实例将与客户端连接进行交互,根据目标字符串引导请求。

sequenceDiagram
  Client ->> gRPC: Request to my-resolver:///my-service
  gRPC ->> NameResolverProvider: requests NameResolver
  NameResolverProvider -->> gRPC: returns NameResolver
  gRPC ->> NameResolver: delegates resolution
  NameResolver -->> gRPC: addresses

语言支持

语言示例
Java示例
Go示例
C++不支持
Python不支持