var ( // m is a map from scheme to resolver builder. m = make(map[string]Builder) // defaultScheme is the default scheme to use. defaultScheme = "passthrough" )
// Register 注册 resolver builder 到 m 中,在初始化的时候使用,线程不安全 funcRegister(b Builder) { m[b.Scheme()] = b }
// Get returns the resolver builder registered with the given scheme. // // If no builder is register with the scheme, nil will be returned. funcGet(scheme string) Builder { if b, ok := m[scheme]; ok { return b } returnnil }
// SetDefaultScheme sets the default scheme that will be used. The default // default scheme is "passthrough". funcSetDefaultScheme(scheme string) { defaultScheme = scheme }
// GetDefaultScheme gets the default scheme that will be used. funcGetDefaultScheme()string { return defaultScheme }
// Address 描述一个服务的地址信息 type Address struct { Addr string
// BuildOptions 创建解析器的额外信息 type BuildOptions struct { // DisableServiceConfig indicates whether a resolver implementation should // fetch service config data. DisableServiceConfig bool DialCreds credentials.TransportCredentials Dialer func(context.Context, string) (net.Conn, error) }
// State 与 ClientConn 相关的当前 Resolver 状态。 type State struct { // 最新的 target 解析出来的可用节点地址集 Addresses []Address
ServiceConfig *serviceconfig.ParseResult
Attributes *attributes.Attributes }
// ClientConn 用于通知服务信息更新的 callback type ClientConn interface { // UpdateState updates the state of the ClientConn appropriately. UpdateState(State) error // ReportError notifies the ClientConn that the Resolver encountered an // error. The ClientConn will notify the load balancer and begin calling // ResolveNow on the Resolver with exponential backoff. ReportError(error)
// ParseServiceConfig parses the provided service config and returns an // object that provides the parsed config. ParseServiceConfig(serviceConfigJSON string) *serviceconfig.ParseResult }
// Target represents a target for gRPC, as specified in: // https://github.com/grpc/grpc/blob/master/doc/naming.md. // It is parsed from the target string that gets passed into Dial or DialContext // by the user. And gRPC passes it to the resolver and the balancer. // // If the target follows the naming spec, and the parsed scheme is registered // with gRPC, we will parse the target string according to the spec. If the // target does not contain a scheme or if the parsed scheme is not registered // (i.e. no corresponding resolver available to resolve the endpoint), we will // apply the default scheme, and will attempt to reparse it.
// Target 请求目标地址解析出的对象 type Target struct {
// URL contains the parsed dial target with an optional default scheme added // to it if the original dial target contained no scheme or contained an // unregistered scheme. Any query params specified in the original dial // target can be accessed from here. URL url.URL }
// Builder 创建一个 resolver 并监听更新 type Builder interface { // Build creates a new resolver for the given target. // // gRPC dial calls Build synchronously, and fails if the returned error is // not nil. Build(target Target, cc ClientConn, opts BuildOptions) (Resolver, error) // Scheme returns the scheme supported by this resolver. // Scheme is defined at https://github.com/grpc/grpc/blob/master/doc/naming.md. Scheme() string }
// ResolveNowOptions includes additional information for ResolveNow. type ResolveNowOptions struct{}
// Resolver 解析器监视指定目标的更新,包括地址更新和服务配置更新。 type Resolver interface { // ResolveNow will be called by gRPC to try to resolve the target name // again. It's just a hint, resolver can ignore this if it's not necessary. // // It could be called multiple times concurrently. ResolveNow(ResolveNowOptions) // Close closes the resolver. Close() }
// UnregisterForTesting removes the resolver builder with the given scheme from the // resolver map. // This function is for testing only. funcUnregisterForTesting(scheme string) { delete(m, scheme) }
type consulResolver struct { address string tag string wg sync.WaitGroup cc resolver.ClientConn name string disableServiceConfig bool lastIndex uint64 }