- Reading about name resolving from the doc
- Been running my servers at
localhost:port
all along, so name resolution wasn't needed. If I had use a fully qualified address (like a URI), it would have resolved the address to ipaddress:port using DNS - Support for different URI schemes are implementation dependent. Most gRPC implementations supports
- dns -
dns:[//authority/]host[:port]
- unix domain sockets -
unix:path
,unix://absolute_path
- unix domain sockets in abstract namespace -
unix-abstract:abstract_path
- dns -
- gRPC C-core implementation supports the following schemes in addition to the above
- ipv4 -
ipv4:address[:port][,address[:port],...]
- ipv6 -
ipv6:address[:port][,address[:port],...]
- ipv4 -
- Supports dns, unix and passthrough resolvers - doc
- passthrough sends the target name without the scheme back to gRPC as resolved address.
- Find some places where name resolving is used
- etcd client supports grpc resolver for its name resolution.
- How it connects using the resolver? Note: resolver can be registered with the global register via init() and calling
resolver.Register
or registered for the specific dial usinggrpc.WithResolvers
// Dial an RPC service using the etcd gRPC resolver and a gRPC Balancer:
// example:
func etcdDial(c *clientv3.Client, service string) (*grpc.ClientConn, error) {
etcdResolver, err := resolver.NewBuilder(c);
if err { return nil, err }
return grpc.Dial("etcd:///" + service, grpc.WithResolvers(etcdResolver))
}
grpc-go
says grpc.WithResolvers experimental though
func WithResolvers(rs ...resolver.Builder) DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.resolvers = append(o.resolvers, rs...)
})
}
- Resolvers are built using ResolverBuilder. Builder and Resolver are interfaces
-
The typical workflow is to implement the Builder interface that builds a struct implementing Resolver interface. An example resolver.
type fooResolver struct { target resolver.Target cc resolver.ClientConn addrsStore map[string][]resolver.Address }
-
Update the ClientConn with resolver.State holding the address given by the builder
func (r *fooResolver) start() { // target.Endpoint is deprecated. Use URL.Path instead. // URL.Path gives the path including the leading slash. // So trim the leading slash to get the address. address := strings.TrimPrefix(r.target.URL.Path, "/") r.cc.UpdateState(resolver.State{Addresses: r.addrsStore[address]}) }
-