The application-level discovery model and metadata information have been introduced in the previous section. Coming to the final section of Dubo-Go application-level service discovery, this section focuses on application information and metadata information, and analyzes how they are combined into Invoker through source code.

The metadata center is relatively static when built within the Consumer. Currently, the information at RegistryURL is used to build Invoker. So how and where do you build it? With regard to building Invoker, the Refer method (Example 1) mentioned in the previous article, we’ve already looked at two parts, and we’ll look at the third.

`func (proto *registryProtocol) Refer(url *common.URL) protocol.Invoker {` `.... '// Gets a list of instances and methods to call. ` `directory, err := extension.GetDefaultRegistryDirectory(registryUrl, reg)` `if err ! = nil {` `logger.Errorf("consumer service %v create registry directory error, error message is %s, and will return nil invoker!" ,` `serviceUrl.String(), err.Error())` `return nil` `}` `.... ` ` `}Copy the code

Sample 1

Before we look at what part 3 does, we need to know what its return value, RegistryDirectory, is. RegistryDirectory is inherited from the Directory Directory interface (example 2) and is used for Consumer to show remote services that exist in the registry and can be invoked. RegistryDirectory represents multiple invokers and can be thought of as a List, but unlike a List, its value can change dynamically, such as when the registry pushes changes. Providers are used to structurally register Invoker information into the registry.

`type Directory interface {`
 `common.Node`
 `List(invocation protocol.Invocation) []protocol.Invoker`
`}`
Copy the code

The sample 2

RegistryDirectory (Example 3) contains the following two functions and updates the Invoker information in the Directory with the obtained application/metadata information.

  • Listen to the remote configuration center

  • Listen to the remote registry

If a client subscribes to a service at the same time, multiple servers may provide it, so a directory service is required. When a new Provider provides a service, it notifies the current directory service, converts the Provider URL obtained from the registry into an Invoker, and places it in the cache.

`type RegistryDirectory struct {` `directory.BaseDirectory` `cacheInvokers []protocol.Invoker` `listenerLock sync.Mutex`  `serviceType string` `registry registry.Registry` `cacheInvokersMap *sync.Map // use sync.map` `consumerURL *common.URL` `cacheOriginUrl *common.URL` `configurators []config_center.Configurator` `consumerConfigurationListener * consumerConfigurationListener < < < consumer configured to monitor ` ` referenceConfigurationListener * referenceConfigurationListener < < < ServiceKey String ' 'forbidden Atomic.Bool' '} '// Registry update event' 'func (dir *RegistryDirectory) Notify(events ... *registry.ServiceEvent) {` `go dir.refreshInvokers(events...) ` ` `}Copy the code

Sample 3

So what does the third part do? Its main functions are to get a list of invoked instances and methods and to construct callable Invokers by subscribing to the registry in the configuration. Then further extension. GetDefaultRegistryDirectory (registryUrl, reg) internal (sample 4) take a look at what it did. First, you need to find the entrance to the method. In sample 4, you see that defaultRegistry() is used for subsequent operations. DefaultRegistry is a variable of private method type, so go directly to where the setting value is called and find defaultRegistry=NewRegistryDirectory. Essentially, the rest of the processing is in: NewRegistryDirectory.

`func GetDefaultRegistryDirectory(config *common.URL, registry registry.Registry) (cluster.Directory, error) {`
 `if defaultRegistry == nil {`
 `panic("registry directory is not existing, make sure you have import the package.")`
 `}`
 `return defaultRegistry(config, registry)`
`}`
Copy the code

The sample of 4

In NewRegistryDirectory, the following main things are done:

  • Obtain the routing chain to be registered by using the URL: chain.newrouterChain (dir.consumerURL);

  • To construct Consumer remote configuration center listener: newConsumerConfigurationListener (dir)

  • Subscribe to the registry and register the update listener: go dir.subscribe(url.suburl)

After the registry is subscribed, the application information for the registry is obtained and combined with local metadata information. After combination, will be an asynchronous write back RegistryDirectory. CacheInvokers, used for subsequent RPC.

There are a few things that NewRegistryDirectory does that I won’t analyze in detail here. Further analysis will be made in the following articles.

Welcome to the community

In the public account [minister technology road] background reply keyword [dubbogo] to join the community.