preface

Hello everyone, today we start sharing – Dubbo special Dubbo local calls. In the previous chapter, we introduced Dubbo asynchronous call, learned what asynchronous call is and how to use the daily scenarios and implementation principle. At the same time, we know that Dubbo asynchronous call can switch our request and business processing threads, so that the full use of NIO mechanism greatly provides thread utilization. In this section we will continue to cover Dubbo local calls. The first thing we need to know is what is a local call? The difference with remote call and what are the use scenarios and implementation principles. So let’s get started fast!

1. Introduction to Dubbo local invocation

In the previous demo examples we have used remote invocations, that is, invoking remotely exposed services over network communication. Local calls are service calls made within the same JVM that are remote calls made without network communication. In Dubbo, the protocol for local calls is injVM ://. Unlike method calls on local objects, Dubbo local calls go through the Filter chain, which includes the Filter chain on the service consumer side and the Filter chain on the service provider side. Through this mechanism, local consumers and other consumers are unified treatment, unified monitoring, unified service governance. Here is an example diagram to illustrate the difference between a local call and a remote call:

You can see from the figure above that the RPC call is a remote call to the service over the network, whereas our local call is a thread call in the same JVM process. This is the biggest difference between the two. Local calls do not need to fetch metadata from the registry, while remote calls require metadata.

Since 2.2.0, every service is exposed locally by default, and can be referenced locally without any configuration. If you do not want the service to be exposed remotely, you only need to set the protocol to INJVM on the provider.

2. Multiple ways of use

The local call to Dubbo provides several configurations:

  1. use<dubbo:protocol/>Specify the global default configuration
<dubbo:protocol name="injvm" />
Copy the code
  1. use<dubbo:provider/>Specify provider configuration
<dubbo:provider protocol="injvm" />
Copy the code
  1. use<dubbo:service/>The tag specifies a service configuration
<dubbo:service protocol="injvm" />
Copy the code
  1. Through the use ofscope="local"configuration

Injvm can be used as a priority for local calls as follows:

  1. Global specified
<dubbo:consumer injvm="true" /><! -- Specify all consumers -->
<dubbo:provider injvm="true" /><! -- Specify all service providers -->
Copy the code
  1. The specified service
<dubbo:reference injvm="true" /><! Specify a service reference -->
<dubbo:service injvm="true" /><! -- Specify a service exposure -->
Copy the code

3. Application scenarios

We’ve seen from the previous discussion that local calls are actually made within the same central JVM instead of making remote calls. We use them less often in our daily work, but one usage is similar to the Mock calls I’ll cover later. When we need to call a remote service, the remote service is not developed, then we can use injVM protocol to implement a similar service locally, when calling this service to call our local implementation service. When the remote service development is complete, we switch to the remote service invocation so that we can achieve emulation-like effects.

4. Example demonstration

Let’s demonstrate this with an example of getting a list of books. The project structure is as follows:

Here we have only one configuration file dubo-xml. XML because both the server and the consumer are in the same JVM. The core configuration file is as follows:


      
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <dubbo:application name="demo-provider"/>

    <dubbo:protocol name="injvm"/>

    <bean id="target" class="com.muke.dubbocourse.localinvoker.spring.BookFacadeImpl"/>

    <! -- Exposed service for Dubbo service -->
    <dubbo:service interface="com.muke.dubbocourse.common.api.BookFacade" ref="target" />

    <! -- Reference local service -->
    <dubbo:reference id="bookFacade" interface="com.muke.dubbocourse.common.api.BookFacade" scope="local"></dubbo:reference>

</beans>

Copy the code

In the configuration file above, we can use to expose the local service and use scope=”local” to reference the local exposed service.

5. Implementation principle

The following is a simplified call flow chart. The main point is to determine whether local or remote services are exposed based on our configuration such as and scope=”local”.

Let’s do a simple analysis in code:

When we need to expose a service will eventually trigger org. Apache. Dubbo. Config. ServiceConfig# export method calls, the core code is as follows:

public synchronized void export(a) {
     
        / /...
        // Get the registry, detect configuration local stubs, and local calls
        checkAndUpdateSubConfigs();

        / /...
        // Determine whether to delay retention
        if (shouldDelay()) {
            DELAY_EXPORT_EXECUTOR.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
        } else {
            // Service reserved
            doExport();
        }

        / /...
    }
Copy the code

The org. Apache. Dubbo. Config. ServiceConfig# checkAndUpdateSubConfigs method has the following code:

 private void checkAndUpdateSubConfigs(a) {
        / /..

        // Check whether the protocol is injvm. For example, 
      
        if(! isOnlyInJvm()) {// Get the registry configuration
            checkRegistry();
        }
        
       / /...
    }
Copy the code

The isOnlyInJvm() method in this code determines whether the protocol is configured as InjVM, and if it is injVM, the registry configuration is not obtained. Then start calling below

Org. Apache. Dubbo. Config. ServiceConfig# doExportUrlsFor1Protocol method, its core code is as follows:

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
        String name = protocolConfig.getName();
  			Protocol No configuration mode uses the Dubbo protocol
        if (StringUtils.isEmpty(name)) {
            name = DUBBO;
        }

				/ /...
				
  			For example: scope="local"
        String scope = url.getParameter(SCOPE_KEY);
        // scope does not equal none
        if(! SCOPE_NONE.equalsIgnoreCase(scope)) {// scope does not equal remote to expose local services
            if(! SCOPE_REMOTE.equalsIgnoreCase(scope)) { exportLocal(url); }// scope does not equal local to expose the remote service
            if(! SCOPE_LOCAL.equalsIgnoreCase(scope)) {if (CollectionUtils.isNotEmpty(registryURLs)) {
                    for (URL registryURL : registryURLs) {
                        Injvm protocol does not expose remote services
                        if (LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
                            continue;
                        }
                       
												// Create a remote invocation proxy objectInvoker<? > invoker = PROXY_FACTORY.getInvoker(ref, (Class) interfaceClass, registryURL.addParameterAndEncoded(EXPORT_KEY, url.toFullString())); DelegateProviderMetaDataInvoker wrapperInvoker =new DelegateProviderMetaDataInvoker(invoker, this);

                        Exporter<?> exporter = PROTOCOL.export(wrapperInvoker);
                        exporters.add(exporter);
                    }
                } else {
                    
                  / /...
                }
                / /...}}this.urls.add(url);
    }
Copy the code

The main logic of the above code is to determine whether local exposure and remote exposure are required, and if remote exposure is required, service metadata information is registered to the registry.

6. Summary

In this section, we focus on local calls in Dubbo. We also introduce common configurations and some usage scenarios. Combined with our simplified flow chart and source code analysis, we can be roughly summarized into two configuration classes: one is to use injVM protocol for configuration, one is to use Scope for configuration.

The highlights of this lesson are as follows:

  1. Understand local calls in Dubbo

  2. Understand common usage

  3. Learn about local call usage scenarios

  4. Understand how local calls work

The author

Personally engaged in the financial industry, I have worked in chongqing’s first-class technical team of Yiji Pay, Sijian Technology and an online car hailing platform, and now I am working in a bank responsible for the construction of unified payment system. I have a strong interest in the financial industry. It also practices big data, data storage, automated integration and deployment, distributed microservices, responsive programming, and artificial intelligence. At the same time, he is also keen on technology sharing, creating public accounts and blog sites to share knowledge system. Concern public number: young IT male get latest technical article push!

Blog: Youngitman.tech

Wechat Official Account: