Dubbo source code analysis process starts service provider - Part (End annexed flowchart)

This section will analyze in detail Dubbo service providers start the process, please take a few questions below to read this section, because these issues will be the focus of the next few articles content analysis.

  1. Establish a connection with the registry of when.
  2. When the service provider registration service to the registry.
  3. Heartbeat mechanism service providers and registration centers.

From the above we know that the core of the service provider to start ServiceBean entrance, this section will analyze in detail the source code level to achieve the principle ServcieBean, namely Dubbo service providers start the process, ServiceBean inheritance hierarchy as shown, dubbo: All service attribute tag are encapsulated in such structure of FIG.

Write pictures described here

1, source code analysis ServiceBean # afterPropertiesSet

ServiceBean#afterPropertiesSet

if (getProvider() == null) {  // @1
    Map<String, ProviderConfig> provide
             ConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class,   false, false); // @2
              // ......  具体解析代码省略。
    }
}
复制代码

Step1: If provider is null, indicating dubbo: service provider attribute tag is set, if a Dubbo: tag provider, then take this example, if there are multiple Dubbo: the provider configuration provider attribute can not be null or throws an exception: " Duplicate provider configs ".

ServiceBean#afterPropertiesSet

 if (getApplication() == null
         && (getProvider() == null || getProvider().getApplication() == null)) {
       Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, 
                  ApplicationConfig.class, false, false);
        // ...省略
 }
复制代码

Step2: If the application is empty, the attempt to query dubbo from the BeanFactory: application instance, if there are multiple dubbo: application configuration, an exception is thrown: "Duplicate application configs". Step3: If ServiceBean the module is empty, then attempt to query dubbo from the BeanFactory: module instance, if there are multiple dubbo: module, an exception is thrown: "Duplicate module configs:". Step4: BeanFactory attempt to load from all of the registry, note ServiceBean of List <RegistryConfig> registries property, registered collection center. Step5: try to load a monitoring center from BeanFacotry, the filling MonitorConfig monitor property ServiceBean, if there are multiple dubbo: monitor configuration, throw "Duplicate monitor configs:". Step6: try to load from the BeanFactory all agreements, attention: ServiceBean of List <ProtocolConfig> protocols is a collection that is a service may be exposed to the consumer through a variety of protocols.

ServiceBean#afterPropertiesSet

if (getPath() == null || getPath().length() == 0) {
       if (beanName != null && beanName.length() > 0 && getInterface() != null && getInterface().length() > 0  && beanName.startsWith(getInterface())) {
                setPath(beanName);
       }
 }
复制代码

Step7: Set ServiceBean path property, path attributes is stored in dubbo: service of beanName (dubbo: service id).

ServiceBean#afterPropertiesSet

if (!isDelay()) {
     export();
}
复制代码

Step8: If exposed enable the delay mechanism, a call to service export exposure. First look at the implementation isDelay, and then focuses on the export realization of the principle (principle of the entire implementation services exposed).

ServiceBean#isDelay

private boolean isDelay() {
        Integer delay = getDelay();
        ProviderConfig provider = getProvider();
        if (delay == null && provider != null) {
            delay = provider.getDelay();
        }
        return supportedApplicationListener && (delay == null || delay == -1);
    }
复制代码

If you have set dubbo: service or dubbo: provider attribute delay, or delay configured to -1, expressed enabled delay mechanism, in milliseconds, is set to -1 to indicate initialization Spring container until after exposure to service. Can also be seen from here, the entrance Dubbo exposure processing services to ServiceBean # export --- "ServiceConfig # export.

1.1 source code analysis ServiceConfig # export exposure services

Call chain: ServiceBean # afterPropertiesSet ------> ServiceConfig # export

public synchronized void export() {
        if (provider != null) {
            if (export == null) {
                export = provider.getExport();
            }
            if (delay == null) {
                delay = provider.getDelay();
            }
        }
        if (export != null && !export) {   // @1
            return;
        }

        if (delay != null && delay > 0) {    // @2
            delayExportExecutor.schedule(new Runnable() {
                @Override
                public void run() {
                    doExport();
                }
            }, delay, TimeUnit.MILLISECONDS);
        } else {
            doExport();    //@3
        }
    }
复制代码

Code @ 1: Determine whether the service exposed by dubbo: service export = | specify "true false". Code @ 2: If the delay mechanism is enabled, if the delay is greater than 0 indicates the number of milliseconds delay after exposure to service, use ScheduledExecutorService delay scheduling, the final call doExport method. Code @ 3: implementation of specific exposure logic doExport, we need to pay attention to: delay = -1 processing logic (based on Spring event trigger mechanism).

1.2 source code analysis ServiceConfig # doExport exposed Services

Call chain: ServiceBean # afterPropertiesSet --- call ------> ServiceConfig # export ------> ServiceConfig # doExport

ServiceConfig#checkDefault

private void checkDefault() {
        if (provider == null) {
            provider = new ProviderConfig();
        }
        appendProperties(provider);
 }
复制代码

Step1: If dubbo: servce tag is a provider ServiceBean property is empty, the method calls appendProperties filled default attribute, and specific load order:

  1. The system loads the corresponding attribute from the parameter values, the key parameters:. Dubbo.provider attribute name, System.getProperty.
  2. Value of the property configuration file to load. Properties profile, the system can attributes: dubbo.properties.file, if the value is not configured, the default attributes take dubbo.properties profile.

ServiceConfig#doExport

if (ref instanceof GenericService) {
      interfaceClass = GenericService.class;
      if (StringUtils.isEmpty(generic)) {
           generic = Boolean.TRUE.toString();
      }
 } else {
      try {
            interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                        .getContextClassLoader());
       } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
       }
       checkInterfaceAndMethods(interfaceClass, methods);
       checkRef();
       generic = Boolean.FALSE.toString();
 }
复制代码

Step2: calibration and interface attribute ref. If the ref is GenericService, was dubbo generalization to achieve, and then verify the type of interface with the interface ref references are the same.

ServiceConfig#doExport

if (local != null) {
      if ("true".equals(local)) {
            local = interfaceName + "Local";
      }
      Class<?> localClass;
      try {
             localClass = ClassHelper.forNameWithThreadContextClassLoader(local);
       } catch (ClassNotFoundException e) {
            throw new IllegalStateException(e.getMessage(), e);
       }
      if (!interfaceClass.isAssignableFrom(localClass)) {
           throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
       }
 }
复制代码

Step3: dubbo: service local mechanism, has been abandoned, be replaced stub. Step4: processing a local stub Stub, <dubbo: service attributes of the stub can be set to true, this time Stub class name: interface + Stub, stub can also specify a custom full class name. Description As shown in FIG local stub (Dubbo official documents)

Write pictures described here
ServiceConfig#doExport

checkApplication();
checkRegistry();
checkProtocol();
appendProperties(this);
复制代码

Step5: ServiceBean check the application, registry, protocol is empty, and the system attributes (priority), the resource file is filled in its properties. System Properties, configure the resource file attribute is as follows:. Application dubbo.application attribute name, for example dubbo.application.name registry dubbo.registry attribute name, for example dubbo.registry.address protocol dubbo.protocol attribute name, for example dubbo.protocol.. .port service dubbo.service. attribute name, for example dubbo.service.stub

ServiceConfig#doExport

checkStubAndMock(interfaceClass);
复制代码

Step6: check stub, mock classes of rationality, whether the interface implementation class.

ServiceConfig#doExport

doExportUrls();
复制代码

Step7: execution doExportUrls () method exposed service, the next will focus on the analysis method.

ServiceConfig#doExport

ProviderModel providerModel = new ProviderModel(getUniqueServiceName(), this, ref);
ApplicationModel.initProviderModel(getUniqueServiceName(), providerModel);
复制代码

Step8: the service provider registration information to ApplicationModel instance.

1.3 source code analysis ServiceConfig # doExportUrls exposed concrete realization of the service logic

调用链:ServiceBean#afterPropertiesSet------>ServiceConfig#export------>ServiceConfig#doExport

private void doExportUrls() {
        List<URL> registryURLs = loadRegistries(true);  // @1
        for (ProtocolConfig protocolConfig : protocols) {
            doExportUrlsFor1Protocol(protocolConfig, registryURLs);    // @2
        }
 }
复制代码

Code @ 1: First traverse ServiceBean of List <RegistryConfig> registries (configuration information for all registered centers), and then the package address to a URL object, all configuration properties on the registry, and ultimately converted to attribute the url (attribute name = attribute? value), loadRegistries (true), the meaning of the parameters: true, on behalf of the service provider, false: services on behalf of the consumer, if the service provider is configured to detect registry, if configured register = "false", is ignored the address, if it is a service consumer, and configured subscribe = "false" said they did not subscribe to the service from the registry, it does not return, a registration center URL example: registry: //127.0.0.1: 2181 / com. ? alibaba.dubbo.registry.RegistryService application = demo-provider & dubbo = 2.0.0 & pid = 7072 & qos.port = 22222 & registry = zookeeper & timestamp = 1527308268041 Code @ 2: traverse then all protocols configured, according to each agreement, to expose the service registry, then focuses on implementation details doExportUrlsFor1Protocol down method.

1.4 source code analysis doExportUrlsFor1Protocol

调用链:ServiceBean#afterPropertiesSet------>ServiceConfig#export------>ServiceConfig#doExport------>ServiceConfig#doExportUrlsFor1Protocol ServiceConfig#doExportUrlsFor1Protocol

String name = protocolConfig.getName();
if (name == null || name.length() == 0) {
     name = "dubbo";
}
Map<String, String> map = new HashMap<String, String>();
map.put(Constants.SIDE_KEY, Constants.PROVIDER_SIDE);
map.put(Constants.DUBBO_VERSION_KEY, Version.getVersion());
map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
if (ConfigUtils.getPid() > 0) {
    map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
}
appendParameters(map, application);
appendParameters(map, module);
appendParameters(map, provider, Constants.DEFAULT_KEY);
appendParameters(map, protocolConfig);
appendParameters(map, this);
复制代码

Step1: Map with all configuration parameters stored in the agreement, including the protocol name, dubbo version, the current system time stamp, process ID, application configuration, module configuration, the default service provider parameters (ProviderConfig), protocol configuration, service providers Dubbo: service property.

ServiceConfig#doExportUrlsFor1Protocol

if (methods != null && !methods.isEmpty()) {
            for (MethodConfig method : methods) {
                appendParameters(map, method, method.getName());
                String retryKey = method.getName() + ".retry";
                if (map.containsKey(retryKey)) {
                    String retryValue = map.remove(retryKey);
                    if ("false".equals(retryValue)) {
                        map.put(method.getName() + ".retries", "0");
                    }
                }
                List<ArgumentConfig> arguments = method.getArguments();
                if (arguments != null && !arguments.isEmpty()) {
                    for (ArgumentConfig argument : arguments) {
                        // convert argument type
                        if (argument.getType() != null && argument.getType().length() > 0) {
                            Method[] methods = interfaceClass.getMethods();
                            // visit all methods
                            if (methods != null && methods.length > 0) {
                                for (int i = 0; i < methods.length; i++) {
                                    String methodName = methods[i].getName();
                                    // target the method, and get its signature
                                    if (methodName.equals(method.getName())) {
                                        Class<?>[] argtypes = methods[i].getParameterTypes();
                                        // one callback in the method
                                        if (argument.getIndex() != -1) {
                                            if (argtypes[argument.getIndex()].getName().equals(argument.getType())) {
                                                appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                                            } else {
                                                throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", type:" + 
                                                      argument.getType());
                                            }
                                        } else {
                                            // multiple callbacks in the method
                                            for (int j = 0; j < argtypes.length; j++) {
                                                Class<?> argclazz = argtypes[j];
                                                if (argclazz.getName().equals(argument.getType())) {
                                                    appendParameters(map, argument, method.getName() + "." + j);
                                                    if (argument.getIndex() != -1 && argument.getIndex() != j) {
                                                        throw new IllegalArgumentException("argument config error : the index attribute and type attribute not match :index :" + argument.getIndex() + ", 
                                                             type:" + argument.getType());
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } else if (argument.getIndex() != -1) {
                            appendParameters(map, argument, method.getName() + "." + argument.getIndex());
                        } else {
                            throw new IllegalArgumentException("argument config must set index or type attribute.eg: <dubbo:argument index='0' .../> or <dubbo:argument type=xxx .../>");
                        }

                    }
                }
            } // end of methods for
        }
复制代码

Step2: If dubbo: service has dubbo: method subtag, the dubbo: configuration properties, and method of its child tags, are stored in the Map, the method name corresponding to the attribute name with a prefix. dubbo: method sub-tab dubbo: argument, which is the key parameter ID method name.

ServiceConfig#doExportUrlsFor1Protocol

if (ProtocolUtils.isGeneric(generic)) {
      map.put(Constants.GENERIC_KEY, generic);
      map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
 } else {
      String revision = Version.getVersion(interfaceClass, version);
      if (revision != null && revision.length() > 0) {
          map.put("revision", revision);
      }
      String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
      if (methods.length == 0) {
           logger.warn("NO method found in service interface " + interfaceClass.getName());
           map.put(Constants.METHODS_KEY, Constants.ANY_VALUE);
      } else {
           map.put(Constants.METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), ","));
      }
}
复制代码

Step3: Adding methods key-value pairs stored dubbo: all the service method name, method name with a plurality of spaced, generalization is achieved if the filling genric = true, methods to "*";

ServiceConfig#doExportUrlsFor1Protocol

if (!ConfigUtils.isEmpty(token)) {
      if (ConfigUtils.isDefault(token)) {
            map.put(Constants.TOKEN_KEY, UUID.randomUUID().toString());
       } else {
            map.put(Constants.TOKEN_KEY, token);
       }
}
复制代码

Step4: The token mechanism is turned on, if on, set key token, the value of static or uuid.

ServiceConfig#doExportUrlsFor1Protocol

if (Constants.LOCAL_PROTOCOL.equals(protocolConfig.getName())) {
       protocolConfig.setRegister(false);
       map.put("notify", "false");
}
复制代码

Step5: If the protocol is local protocol (injvm), is set protocolConfig # register attribute to false, indicating not to register registration service center, stored in the key map as notify, is false, meaning when the listener registry service provider to send when not notice the change (increase service providers, service providers reduce such incidents.

ServiceConfig#doExportUrlsFor1Protocol

// export service
String contextPath = protocolConfig.getContextpath();
if ((contextPath == null || contextPath.length() == 0) && provider != null) {
     contextPath = provider.getContextpath();
}
复制代码

Step6: contextPath protocol settings, if not configured, the default is / interfacename

ServiceConfig#doExportUrlsFor1Protocol

String host = this.findConfigedHosts(protocolConfig, registryURLs, map);
Integer port = this.findConfigedPorts(protocolConfig, name, map);
复制代码

Step7: Resolve IP address and port service providers. Service IP Address Resolution No. smaller the priority order :()

  1. System environment variables, variable names: DUBBO_DUBBO_IP_TO_BIND
  2. System Properties, variable names: DUBBO_DUBBO_IP_TO_BIND
  3. System environment variables, variable names: DUBBO_IP_TO_BIND
  4. System Properties, variable names: DUBBO_IP_TO_BIND
  5. dubbo: host attribute protocol label - "dubbo: host property provider label
  6. The default LAN IP address,). GetHostAddress () obtained by InetAddress.getLocalHost (, if the IP address does not meet the requirements, continue to the next match.

IP address of the criteria for compliance are:

   public static boolean isInvalidLocalHost(String host) {
        return host == null
                || host.length() == 0
                || host.equalsIgnoreCase("localhost")
                || host.equals("0.0.0.0")
                || (LOCAL_IP_PATTERN.matcher(host).matches());
      }
复制代码
  1. Select the first available network card, its implementation is to establish socket, connection to the registry, to obtain the IP address of the socket. Its code:
Socket socket = new Socket();
        try {
              SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
              socket.connect(addr, 1000);
              hostToBind = socket.getLocalAddress().getHostAddress();
              break;
         } finally {
              try {
                      socket.close();
              } catch (Throwable e) {
              }
        }
复制代码

Service Provider :( port number the smaller the resolution order of priority)

  1. System environment variables, variable names: DUBBO_DUBBO_PORT_TO_BIND
  2. System Properties, variable names: DUBBO_DUBBO_PORT_TO_BIND
  3. System environment variables, variable names: DUBBO_PORT_TO_BIND
  4. System Properties, variable names DUBBO_PORT_TO_BIND
  5. dubbo: protocol label port property, dubbo: port property provider label.
  6. Randomly selects a port.

ServiceConfig#doExportUrlsFor1Protocol

URL url = new URL(name, host, port, (contextPath == null || contextPath.length() == 0 ? "" : contextPath + "/") + path, map);
复制代码

Step8: building services provider based on URI protocol name, protocol host, protocol port, contextPath, configuration attributes (application, module, provider, protocolConfig, service and its sub-label). URL run effect diagram:

Write pictures described here
Dubbo protocol as an example to show information about the final URL service providers are as follows: dubbo: //192.168.56.1: 20880 / anyhost = true & application = demo-provider & bind.ip = 192.168.56.1 com.alibaba.dubbo.demo.DemoService & bind? .port = 20880 & dubbo = 2.0.0 & generic = false & interface = com.alibaba.dubbo.demo.DemoService & methods = sayHello & pid = 5916 & qos.port = 22222 & side = provider & timestamp = 1527168070857

ServiceConfig#doExportUrlsFor1Protocol

String scope = url.getParameter(Constants.SCOPE_KEY);
// don't export when none is configured
if (!Constants.SCOPE_NONE.toString().equalsIgnoreCase(scope)) {
     // 接口暴露实现逻辑
}
复制代码

Step9: Get dubbo: scope service attribute tag, which optionally is none (no exposure), local (local), Remote (remote), if the configuration is none, is not exposed. The default is local.

ServiceConfig#doExportUrlsFor1Protocol

// export to local if the config is not remote (export to remote only when config is remote)
if (!Constants.SCOPE_REMOTE.toString().equalsIgnoreCase(scope)) {     // @1
       exportLocal(url);
}
// export to remote if the config is not local (export to local only when config is local)
if (!Constants.SCOPE_LOCAL.toString().equalsIgnoreCase(scope)) {     // @2
        if (logger.isInfoEnabled()) {
              logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
         }
        if (registryURLs != null && !registryURLs.isEmpty()) {   // @3
              for (URL registryURL : registryURLs) {
                    url = url.addParameterIfAbsent(Constants.DYNAMIC_KEY, registryURL.getParameter(Constants.DYNAMIC_KEY));  // @4
                    URL monitorUrl = loadMonitor(registryURL);       // @5
                    if (monitorUrl != null) {
                        url = url.addParameterAndEncoded(Constants.MONITOR_KEY, monitorUrl.toFullString());  
                    }
                    if (logger.isInfoEnabled()) {
                        logger.info("Register dubbo service " + interfaceClass.getName() + " url " + url + " to registry " + registryURL);
                    }
                   Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(Constants.EXPORT_KEY, url.toFullString()));  // @6
                   DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);    
                   Exporter<?> exporter = protocol.export(wrapperInvoker);    // @7
                   exporters.add(exporter);
               }
         } else {
               Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url);
               DelegateProviderMetaDataInvoker wrapperInvoker = new DelegateProviderMetaDataInvoker(invoker, this);
               Exporter<?> exporter = protocol.export(wrapperInvoker);
               exporters.add(exporter);
         }
}
复制代码

Step10: According to scope to expose services, if scope is not configured, the default will be exposed to local and remote, if configured local or remote, it can only be a second election. Code @ 1: If the scope is not remote, the first local exposure (injvm) :, concrete exposed concrete implementation services, will analyze in detail in remote mode. Code @ 2: If the scope is not local, it will be exposed to the remote service. Code @ 3: remote way, detection of all registration centers currently configured, if the registry is not empty, then traverse the registry, the service in order to be registered in different registries. Code @ 4: If dubbo: service of the dynamic properties are not configured to try to take dubbo: registry of dynamic properties, the role of the property whether to enable dynamic registration, if set to false, service registration, its status is displayed as disable, the need to manually enable when the service is not available, it will not automatically remove, also require manual processing, this property is not used in production environments. Code @ 5: According to the Registry url (registry url), build a URL monitoring center, additional monitoring center monitor the URL if the URL does not, then the service provider is empty, its value monitoring center url (encoded).

  • If dubbo spring xml configuration file does not configure the monitoring center (dubbo: monitor), if you build MonitorConfig object from the system properties -Ddubbo.monitor.address, -Ddubbo.monitor.protocol, otherwise look for the two properties from dubbo's profile parameters, if not configured, returns null.
  • If you have configured the additional parameters, dubbo: monitor tag only two attributes: address, protocol, will be followed by an additional interface (MonitorService), and other protocols.

Code @ 6: Invoker created by the dynamic proxy mechanism, implementation class dubbo of remote calls.

Write pictures described here
Dubbo how to build remote call control, not detailed here in depth, focusing on WrapperInvoker the url is: registry: //127.0.0.1:? 2181 / com.alibaba.dubbo.registry.RegistryService application = demo-provider & dubbo = 2.0.0 & export = dubbo % 3A% 2F% 2F192.168.56.1% 3A20880% 2Fcom.alibaba.dubbo.demo.DemoService% 3Fanyhost% 3Dtrue% 26application% 3Ddemo-provider% 26bind.ip% 3D192.168.56.1% 26bind.port% 3D20880% 26dubbo % 3D2.0.0% 26generic% 3Dfalse% 26interface% 3Dcom.alibaba.dubbo.demo.DemoService% 26methods% 3DsayHello% 26pid% 3D6328% 26qos.port% 3D22222% 26side% 3Dprovider% 26timestamp% 3D1527255510215 & pid = 6328 & qos.port = 22222 & registry = zookeeper & timestamp = 1,527,255,510,202, there are two main points of concern:

  • path attribute: com.alibaba.dubbo.registry.RegistryService, the registry is also similar to the service provider.
  • export attributes: URL value of the service provider, and why it needs to focus on this URL? Look at the code @ 7, protocol attributes Protocol $ Adaptive, Dubbo uses when loading the component implementation class SPI (plug-in mechanism, there are about plug-in mechanism, the analysis will focus on the topic in a future article), here we need to know, based on the URL protocol name before the colon will call the appropriate method.
    Write pictures described here
    Whose mappings (start lists and related service agreement implementation class): dubbo = com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol // file is located dubbo-rpc-dubbo / src / main / resources / META-INF / dubbo / internal / com.alibaba.dubbo.rpc.Protocol registry = com.alibaba.dubbo.registry.integration.RegistryProtocol // files located dubbo-registry-api / src / main / resources / META-INF / dubbo / internal / com.alibaba.dubbo.rpc.Protocol Code @ 7: @ 6 based on an analysis of the code, will call RegistryProtocol # export method.

1.5 source code analysis RegistryProtocol # export method

调用链:ServiceBean#afterPropertiesSet------>ServiceConfig#export------>ServiceConfig#doExport------>ServiceConfig#doExportUrlsFor1Protocol------>RegistryProtocol#export

RegistryProtocol#export

@Override
    public <T> Exporter<T> export(final Invoker<T> originInvoker) throws RpcException {
        //export invoker
        final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker);   // @1

        URL registryUrl = getRegistryUrl(originInvoker);       // @2

        //registry provider
        final Registry registry = getRegistry(originInvoker);                          // @3
        final URL registedProviderUrl = getRegistedProviderUrl(originInvoker);     // @4start

        //to judge to delay publish whether or not
        boolean register = registedProviderUrl.getParameter("register", true);  

        ProviderConsumerRegTable.registerProvider(originInvoker, registryUrl, registedProviderUrl);

        if (register) {  
            register(registryUrl, registedProviderUrl);      // @4 end
            ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
        }

        // 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(registedProviderUrl);          // @5 start
        final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
        overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
        registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);            // @5 end
        //Ensure that a new exporter instance is returned every time export
        return new DestroyableExporter<T>(exporter, originInvoker, overrideSubscribeUrl, registedProviderUrl);
    }
复制代码

Code @ 1: Start the service provider service, listening on the specified port, ready to serve the consumer's request, here is actually extracted from WrapperInvoker export attribute in the url (url registry) is described url service provider, and then start the service provider By.

Write pictures described here
From the figure above, we can see, will be called to complete the boot dubbo DubboProtocol # export services, utilizing netty to build a mini-server, listen port, ready to accept the service consumer network requests, this section is to sort out its startup process, specific implementation details will explain in later chapters, where we just know, <dubbo: protocol name = "dubbo" port = "20880" />, which will then monitor the port, and then dubbo: service added to the service handler command processor, when a message is connected to the consumer ports, unpacked by the network, the need to call the service and other information analysis processing parameters, transferred to the service implementation class corresponding to the processing. Code @ 2: Get real URL registration centers, such as URL zookeeper registry: zookeeper: //127.0.0.1: 2181 / com.alibaba.dubbo.registry.RegistryService application = demo-provider & dubbo = 2.0.0 & export = dubbo%? 3A% 2F% 2F192.168.56.1% 3A20880% 2Fcom.alibaba.dubbo.demo.DemoService% 3Fanyhost% 3Dtrue% 26application% 3Ddemo-provider% 26bind.ip% 3D192.168.56.1% 26bind.port% 3D20880% 26dubbo% 3D2.0.0% 26generic% 3Dfalse% 26interface% 3Dcom.alibaba.dubbo.demo.DemoService% 26methods% 3DsayHello% 26pid% 3D10252% 26qos.port% 3D22222% 26side% 3Dprovider% 26timestamp% 3D1527263060882 & pid = 10252 & qos.port = 22222 & timestamp = 1527263060867 Code @ 3: The registry URL, acquires the specified registration center from the registry factory implementation class: ZooKeeper registry implementation class is: ZookeeperRegistry Code @ 4: Get register attribute service provider URL, if true, call ZookeeperRegistry # register a method of registration service registration center to registration center (actually implemented by its parent FailbackRegistry). Code @ 5: service provider to subscribe themselves to the registration center, mainly to re-expose the service provider to send the URL changes, of course, will dubbo: reference check of property is set to false.

Here on the question article mentioned at the beginning of a solution 1, Question 2 made will be analyzed in detail with the registry heartbeat mechanism in the following sections.

Text may seem not very intuitive, is now tidy Dubbo service provider to start a flow chart is as follows:

Write pictures described here

This article focuses combed Dubbo service provider to start the process, we will be analyzed in detail in the next section in which the service provider in Dubbo specified port listening service startup process.


Author: Ding Wei, "RocketMQ Technology Insider" author, RocketMQ community preacher, public number: Middleware interest circle defenders, has been published a set of Java source code analysis, Java and contracting (JUC), Netty, Mycat, Dubbo, RocketMQ, Mybatis and other source columns. Click on the link can join middleware knowledge of the planet , to explore high concurrency, distributed service architecture, AC source.

Here Insert Picture Description

Guess you like

Origin juejin.im/post/5df8d0b8f265da339b4ffd83