Custom Name Resolution

Explains standard name resolution, the custom name resolver interface, and how to write an implementation.

Custom Name Resolution

Explains standard name resolution, the custom name resolver interface, and how to write an implementation.

Overview

Name resolution is fundamentally about service discovery. When sending a gRPC request, the client must determine the IP address of the service name. Name resolution is often thought to be the same as DNS. In practice however, DNS is usually augmented with extensions or completely replaced to enable name resolution.

When making a request with a gRPC client, by default, DNS name resolution is used. However, various other name resolution mechanisms may be used:

ResolverExampleNotes
DNSgrpc.io:50051By default, DNS is assumed.
DNSdns:///grpc.io:50051The extra slash is used to provide an authority
Unix Domain Socketuds:///run/containerd/containerd.sock
xDSxds:///wallet.grpcwallet.io
IPv4ipv4:198.51.100.123:50051Only supported in some languages

Several languages support an interface to allow the user to define their own name resolvers, so that you may define how to resolve any given name. Once registered, a name resolver with the scheme my-resolver will be picked up when a target string begins with my-resolver:. For example, requests to my-resolver:///my-service would now use the my-resolver name resolver implementation.

Custom Name Resolvers

You might consider using a custom name resolver whenever you would like to augment or replace DNS for service discovery. For example, this interface has been used in the past to use Apache Zookeeper to look up service names. It has also been used to directly interface with the Kubernetes API server for service lookup based on headless Service resources.

One reason why it might be particularly useful to use a custom name resolver rather than standard DNS is that this interface is reactive. Within standard DNS, a client looks up the address for a particular service at the beginning of the connection and maintains its connection to that address for the lifetime of the connection. However, custom name resolvers may be watch-based. That is, they can receive updates from the name server over time and therefore respond intelligently to backend failure as well as backend scale-ups and backend scale-downs.

In addition, a custom name resolver may provide the client connection with a service config. A service config is a JSON object that defines arbitrary configuration specifying how traffic should be routed to and load balanced across a particular service. At its most basic, this can be used to specify things like that a particular service should use the round robin load balancing policy vs. pick first. However, when a custom name resolver is used in conjunction with arbitrary service config and a custom load balancing policy, very complex traffic management systems such as xDS may be constructed.

Life of a Target String

While the exact interface for custom name resolvers differs from language to language, the general structure is the same. The client registers an implementation of a name resolver provider to a process-global registry close to the start of the process. The name resolver provider will be called by the gRPC library with a target strings intended for the custom name resolver. Given that target string, the name resolver provider will return an instance of a name resolver, which will interact with the client connection to direct the request according to the target string.

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

Language Support

LanguageExample
JavaExample
GoExample
C++Not supported
PythonNot supported