Since Alibaba restarted Dubbo open source in July 2017, the number of Github stars and contributors has greatly improved so far. On February 9, 2018, Ali decided to contribute the Dubbo project to Apache. After a one-week vote, it successfully became Apache’s Incubator project, which is now known as Incubator Dubbo. Dubbo is expected to graduate to Apache’s top level program in April 2019.

Branch is introduced

Dubbo currently has 5 branches as shown in the figure, among which 2.7.1-release is only a temporary branch, which will be ignored and introduced to the other 4 branches.

  • 2.5.x has recently been voted on and the Dubbo community is about to stop its maintenance.
  • 2.6.x is the long-supported version, which is also the version before Dubbo contributed to Apache. Its package name prefix is com.alibaba. JDK version corresponds to 1.6.
  • 3. X-dev is a forward-looking release that complements Dubbo with advanced features such as support for RX features.
  • Master is a long-supported version of 2.7.x that Dubbo contributed to Apache. The package name prefix is org. Apache. JDK version is 1.8.

If you want to explore the source code for Dubbo, you are advised to browse the Master branch.

Dubbo 2.7 new features

Dubbo 2.7.x, the Apache incubator, has many new features in addition to code optimizations. This article will introduce three of the most typical new features:

  • Asynchronous modification
  • Transformation of three major centers
  • Service Governance Enhancements

Asynchronous modification

Several ways to call

In remote method invocation, there are roughly four types of invocation. Oneway is when a client sends a message without receiving a response. For requests that do not care about the response of the server, oneWay communication is appropriate.

Note that the void Hello () method is not part of the Oneway call in the remote method call. Although the void method expresses the semantics of not caring about the return value, the communication layer response is still required at the RPC level.

Sync is the most common and default communication method.

Both futures and callback are asynchronous calls. The difference is that future.get() causes the thread to block on receiving the response. Callback usually sets up a callback thread that executes automatically when a response is received without blocking the current thread.

Dubbo 2.6 Asynchronization

The advantage of asynchrony lies in that the client can call multiple remote services in parallel without starting multithreading, which is less expensive than multithreading. Before introducing the asynchrony transformation in 2.7, let’s review how Dubbo’s asynchrony capability was used in 2.6.

  1. Declare the synchronization interface asasync=true
<dubbo:reference id="asyncService" interface="org.apache.dubbo.demo.api.AsyncService" async="true"/>
Copy the code
public interface AsyncService {
    String sayHello(String name);
}
Copy the code
  1. Get the Future through the context class
AsyncService.sayHello("Han Meimei");
Future<String> fooFuture = RpcContext.getContext().getFuture();
fooFuture.get();
Copy the code

As you can see, this approach is not very consistent with asynchronous programming, and requires retrieving the Future from a context class. If multiple asynchronous calls are made at the same time, context contamination can be easily caused by improper use. Also, the Future does not support callbacks. Dubbo 2.7 addresses these drawbacks.

Dubbo 2.7 Asynchronization

  1. You do not need to declare the asynchronous interface
public interface AsyncService { String sayHello(String name); default CompletableFuture<String> sayHiAsync(String name) { return CompletableFuture.completedFuture(sayHello(name)); }}Copy the code
  1. Callback is used to process the return value
CompletableFuture<String> future = asyncService.sayHiAsync("Han MeiMei"); future.whenComplete((retValue, exception) -> { if (exception == null) { System.out.println(retValue); } else { exception.printStackTrace(); }});Copy the code

Dubbo 2.7 improves its asynchrony by using the CompletableFuture native interface provided by JDK1.8. CompletableFuture supports both Future and callback calls, which users can use according to their preferences and scenarios, making it very flexible.

FAQ for asynchronous design

Q: If the RPC interface defines only synchronous interfaces, is there a way to use asynchronous calls?

A: The only advantage of asynchronous invocation in 2.6 is that it can be made asynchronously without any changes at the interface level, which will remain in 2.7. With Dubbo’s official compiler Hacker, the synchronization method is automatically overridden at compile time. Please discuss and follow the progress here.

Q: As for the design of asynchronous interface, why not provide a compiler plug-in to automatically compile a XxxAsync interface according to the original interface?

A: Dubbo 2.7 has adopted this design, but the expansion of the interface will lead to the incremental publication of the service class, and the change of the interface name will affect some related logic of the service governance. The change of the method to add the Async suffix has A relatively small impact.

Q: Dubbo is divided into client-side asynchrony and server-side asynchrony. Just now you introduced client-side asynchrony, why not mention server-side asynchrony?

Dubbo 2.7 adds support for server-side asynchronism, but in fact Dubbo’s business thread pool model can be understood as an asynchronous call itself. I think the server-side asynchronism feature is weak.

Transformation of three major centers

The three centers are: registry, metadata center, and configuration center.

Prior to version 2.7, Dubbo was only equipped with a registry, and the main registry used was ZooKeeper. The newly added metadata center and configuration center are naturally to solve the corresponding pain points. Here we will explain the reasons for the transformation of the three centers in detail.

Metadata transformation

What is metadata? Metadata is defined as data that describes data. In service governance, such as service interface names, retries, version numbers, etc., can be understood as metadata. Before 2.7, metadata was lost in the registry, which caused a number of problems:

Large amount of push -> Large amount of storage data -> Large amount of network transfer -> Severe delay

Nearly half of the 30+ parameters registered on the producer side do not need to be passed as a registry; Consumer side registration 25+ parameters, only individual need to be passed to the registry. With the above theoretical analysis in mind, Dubbo 2.7 made a drastic change to publish only the data that truly belongs to service governance into the registry, greatly reducing the load on the registry.

At the same time, the full amount of metadata is published to another component: the metadata center. The metadata center currently supports Redis (recommended) and ZooKeeper. This also sets the stage for Dubbo 2.7’s new Dubbo Admin, which I will write a separate article about later.

Example: Using ZooKeeper as the metadata center

< dubbo: metadata - report address = "zookeeper: / / 127.0.0.1:2181" / >Copy the code

Dubbo 2.6 Metadata

Dubbo: / / 30.5.120.185:20880 / com. Alibaba. Dubbo. Demo. DemoService? Anyhost = true & application = demo - provider & interface=com.alibaba.dubbo.demo.DemoService& methods=sayHello& bean.name=com.alibaba.dubbo.demo.DemoService& Dubbo =2.0.2& executes=4500& generic=false& owner= Kirito & PID =84228& retries=7& Side =provider& timestamp=1552965771067Copy the code

Retrieve a piece of service data from the local ZooKeeper. After decoding, it can be seen that many parameters are indeed unnecessary.

Dubbo 2.7 metadata

In 2.7, the data format in ZooKeeper remains the same as Dubbo 2.6 unless additional configuration is made. This is mainly to ensure compatibility, so that Dubbo 2.6 clients can call Dubbo 2.7 servers. If the overall migration is to 2.7, you can turn on simplified configuration parameters for the registry:

"Dubbo: registry address =" zookeeper: / / 127.0.0.1:2181 "simplified =" true "/ >Copy the code

Dubbo will upload only necessary service governance data, a simplified version of which looks like this:

Dubbo: / / 30.5.120.185:20880 / org. Apache. Dubbo. Demo. API. DemoService? Application = demo - provider & dubbo = 2.0.2 & release = 2.7.0 &  timestamp=1552975501873Copy the code

Non-essential service information is still fully stored in the metadata center:

Metadata center data can be used for service testing, service mocks, and more. The default value for Simplified in the registry configuration is currently false, and will change to true in subsequent iterations because of migration compatibility concerns.

Configuration Center Support

The need for a configuration center is often measured from three perspectives:

  1. Distributed configuration unified management
  2. Dynamic change push
  3. security

Distributed configuration center components such as Spring Cloud Config, Apollo, and Nacos support the above functionality to varying degrees. Configurators and routers were set up in ZooKeeper earlier than 2.7. These nodes are used to manage configuration and routing information, and can be regarded as the prototype of a Dubbo configuration center. In 2.7, Dubbo officially supported configuration centers and currently supports several registries: Zookeeper, Apollo, Nacos (2.7.1-release support).

In Dubbo, the configuration center performs two primary roles

  • Externalize the configuration. Start centralized storage of configurations
  • Service governance. Storage and notification of service governance rules

Example: Using Zookeeper as the configuration center

The < dubbo: config - center address = "zookeeper: / / 127.0.0.1:2181" / >Copy the code

After the configuration center is introduced, pay attention to the overwriting of configuration items, as shown in the figure

Service Governance Enhancements

I prefer to think of Dubbo as a service governance framework rather than just an RPC framework. In 2.7, Dubbo enhanced its service governance capabilities by adding the ability to label routing and abstractions the concepts of application routing and service routing. In the last feature introduction, we focus on the TagRouter.

Comparison of routing layer and load balancing layer in service governance. Router: m: select N, LoadBalance: n: select 1. Difference 2: Routes are used in combination, and only one load balancer can be configured.

For a long time, a common question in the Dubbo community was how Dubbo implemented traffic isolation and grayscale publishing, until 2.7 provided tag routing, which users could use to fulfill the above requirements.

Label routing provides the ability for users to mark requests when the call link is A -> B -> C -> D. The most typical way to mark requests is through attachment (which can be passed on in distributed calls). The call will preferentially request those matching servers, such as A -> B, C -> D, Because no C node is deployed in the cluster, the cluster is degraded to a common node.

So Dubbo only provides a basic interface like rpcContext.getContext ().setAttachment(). Users can use SPI extension, Or an extension of Server Filter to mark test traffic and boot into an isolated/grayscale environment.

The new Dubbo Admin provides configuration items for tag routing:

Dubbo users can perform secondary extension of label routing based on their own systems, or learn from the design of label routing to implement traffic isolation and grayscale publishing in their own systems.

conclusion

This article introduces three important new features of Dubbo 2.7: asynchronous transformation, three hub transformation, and service governance enhancement. Dubbo 2.7 also includes a number of enhancements and feature upgrades, all of which can be viewed in changes.md of the project source code. Finally, we provide a Dubbo 2.7 upgrade document: 2.7 Migration document, welcome to experience.