1. The role of service registry discovery

    In a high-availability production environment, services are provided in clusters. IP addresses in clusters may change at any time or nodes may be added or reduced during maintenance. Therefore, clients need to be able to detect changes in servers and obtain the connection information of the latest service nodes in the cluster.

  2. Service registry discovery

1) Service registration: When the service provider starts, the exposed interface will be registered in the registry, which will save the IP address, interface and other connection information of the service node. To detect the valid status of the server, a bidirectional heartbeat mechanism is usually established.

2) Service subscription: When the service caller is started, the client goes to the registry to find and subscribe to the IP of the service provider, which is then cached locally and used for subsequent remote calls. If registry information changes, it is usually updated by push.

  1. The specific process of service registration discovery

    Mainstream service registration tools include Nacos, Consul, Zookeeper, etc. Service discovery based on Zookeeper: The ZooKeeper cluster serves as a registry cluster. During service registration, the service node only needs to write registration information to the ZooKeeper node. The Watcher mechanism of ZooKeeper is used to complete service subscription and service delivery.

    A). Create A service root path in ZooKeeper, which can be named according to the interface name (for example: / micro/service/com. Itcast. XxService), on the path to create a service provider to the caller directory (server and client), were used to store the provider and the caller node information.

    B). When the server initiates registration, it will create a temporary node in the directory of the service provider, which stores registration information, such as IP address, port, service name and so on.

    C). The client when a subscription, you will be in the service call directory to create a temporary node, the node in the information of the caller, and watch the provider directory (/ service/com. Demo. XxService/server) all service node in the data. When the server changes, such as an offline or outage, ZooKeeper notifies the subscribing client.

  2. Features of the ZooKeeper solution

    ZooKeeper is characterized by strong consistency. When data on each ZooKeeper node is updated, other ZooKeeper nodes are notified to perform the update. It requires to ensure that the data of each node can be completely consistent in real time, which will lead to the performance decline of ZooKeeper cluster. ZK adopts CP mode (to ensure strong consistency). If you want to pay attention to performance, you can consider using AP mode (to ensure final consistency) registry components, such as Nacos.

  3. Dubbo registry discovery source code analysis

    1. Dubbo Spring Cloud (Dubbo Spring Cloud) :RegistryProtocol doRefer method:

      private <T> Invoker<T> doRefer(Cluster cluster, Registry registry, Class<T> type, URL url) {
          RegistryDirectory<T> directory = new RegistryDirectory<T>(type, url);
          directory.setRegistry(registry);
          directory.setProtocol(protocol);
          // all attributes of REFER_KEY
          Map<String, String> parameters = new HashMap<String, String>(directory.getUrl().getParameters());
          URL subscribeUrl = new URL(CONSUMER_PROTOCOL, parameters.remove(REGISTER_IP_KEY), 0, type.getName(), parameters);
          if(! ANY_VALUE.equals(url.getServiceInterface()) && url.getParameter(REGISTER_KEY,true)) {
              directory.setRegisteredConsumerUrl(getRegisteredConsumerUrl(subscribeUrl, url));
              registry.register(directory.getRegisteredConsumerUrl());
          }
          directory.buildRouterChain(subscribeUrl);
          directory.subscribe(subscribeUrl.addParameter(CATEGORY_KEY,
                  PROVIDERS_CATEGORY + "," + CONFIGURATORS_CATEGORY + "," + ROUTERS_CATEGORY));
      
          Invoker invoker = cluster.join(directory);
          ProviderConsumerRegTable.registerConsumer(invoker, url, subscribeUrl, directory);
          return invoker;
      }
      
      Copy the code
    2. Dubbo Spring Cloud (Dubbo Spring Cloud) :RegistryProtocol export method:

       public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
          // Get registration information
      	URL registryUrl = getRegistryUrl(originInvoker);
          // Obtain the service provider information
         URL providerUrl = getProviderUrl(originInvoker);
       
          // Subscribe the override data
          // FIXME When the provider subscribes, it will affect the scene : a certain JVM exposes the service and call
          // the same service. Because the subscribed is cached key with the name of the service, it causes the
          // subscription information to cover.
          final URL overrideSubscribeUrl = getSubscribedOverrideUrl(providerUrl);
          final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
         overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
       
          providerUrl = overrideUrlWithConfig(providerUrl, overrideSubscribeListener);
          //export invoker
         final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker, providerUrl);
       
          // Get the subscription registry
          final Registry registry = getRegistry(originInvoker);
          final URL registeredProviderUrl = getRegisteredProviderUrl(providerUrl, registryUrl);
          ProviderInvokerWrapper<T> providerInvokerWrapper = ProviderConsumerRegTable.registerProvider(originInvoker,
                  registryUrl, registeredProviderUrl);
          //to judge if we need to delay publish
          boolean register = registeredProviderUrl.getParameter("register".true);
          if (register) {
              // Enter the server information registration process
              register(registryUrl, registeredProviderUrl);
              providerInvokerWrapper.setReg(true);
         }
       
          // Deprecated! Subscribe to override rules in 2.6.x or before.
      	// Server information subscription processing
         registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
       
          exporter.setRegisterUrl(registeredProviderUrl);
          exporter.setSubscribeUrl(overrideSubscribeUrl);
          //Ensure that a new exporter instance is returned every time export
          return new DestroyableExporter<>(exporter);
      }
      Copy the code

This article was created and shared by Mirson. For further communication, please add to QQ group 19310171 or visit www.softart.cn