自定义名称解析

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

概述

名称解析从根本上来说是服务发现。当发送 gRPC 请求时,客户端必须确定服务名称的 IP 地址。名称解析通常被认为与 DNS 相同。然而,在实践中,DNS 通常会被扩展或完全替换,以支持名称解析。

在使用 gRPC 客户端发起请求时,默认情况下使用 DNS 名称解析。然而,也可以使用其他名称解析机制:

解析器 示例 备注

DNS

grpc.io:50051

默认情况下假设使用 DNS

DNS

dns:///grpc.io:50051

使用额外的斜杠提供 authority。

Unix 域套接字

uds:///run/containerd/containerd.sock

xDS

xds:///wallet.grpcwallet.io

IPv4

ipv4:198.51.100.123:50051

仅在某些语言中受支持。

上面的三个斜杠(///)可能与您习惯的双斜杠(如 https://grpc.io)格式不同。这些目标字符串遵循 RFC-3986 URI 格式。在三个斜杠之间的字符串(如果有第三个斜杠)是 authorityauthority 字符串标识一个包含所有资源 URI 的服务器。在传统的 HTTP 请求中,URI 的 authority 是请求发送的服务器。在其他情况下,authority 将是名称解析服务器的身份,而资源本身则存在于其他服务器上。有些名称解析器不需要 authority,在这种情况下,authority 字符串为空,结果是三个连续的斜杠。

多个语言支持一个接口,允许用户定义自己的名称解析器,从而定义如何解析给定的名称。注册后,当目标字符串以 my-resolver: 开头时,将使用名为 my-resolver 的名称解析器实现。例如,对 my-resolver:///my-service 的请求将使用 my-resolver 名称解析器实现。

自定义名称解析器

当您希望增强或替换 DNS 进行服务发现时,可以考虑使用自定义名称解析器。例如,这个接口曾被用来通过 Apache Zookeeper 查找服务名称。它也曾被用来直接与 Kubernetes API 服务器交互,基于无头服务(headless Service)资源进行服务查找。

使用自定义名称解析器而不是标准 DNS 的一个原因是,这个接口是响应式的。在标准 DNS 中,客户端在连接开始时查找特定服务的地址,并在连接的生命周期内保持与该地址的连接。然而,自定义名称解析器可以是基于监听的(watch-based),即它们可以接收来自名称服务器的更新,从而智能响应后端故障、后端扩展(scale-up)和后端缩减(scale-down)。

此外,自定义名称解析器还可以为客户端连接提供服务配置(service config)。服务配置是一个 JSON 对象,定义了指定如何将流量路由到特定服务并进行负载均衡的任意配置。最基本的用途是指定某个服务应使用轮询负载均衡策略(round robin)或选择第一个可用(pick first)。然而,当自定义名称解析器与任意服务配置和 自定义负载均衡策略 结合使用时,可以构建非常复杂的流量管理系统,如 xDS。

目标字符串的生命周期

尽管不同语言中自定义名称解析器的接口有所不同,但总体结构是相同的。客户端在进程开始时向进程全局注册名称解析器提供者(name resolver provider)。gRPC 库会使用目标字符串调用该名称解析器提供者。根据目标字符串,名称解析器提供者将返回一个名称解析器实例,该实例与客户端连接交互,根据目标字符串引导请求。

image 2024 12 24 09 41 52 726

语言支持

语言 示例

Java

Java 示例

Go

Go 示例

C++

尚不支持

Python

尚不支持