Dubbo 2.7 will focus on asynchronous support optimization, metadata transformation, the introduction of JDK8 features, Netty4.0 features and MetricsAPI five aspects to improve the efficiency of service invocation and service governance, as well as scalability, and will fix several issues raised by the community.

As Dubbo’s graduation release in the Apache community, Dubbo will have the opportunity to become the next Apache Top-level project (TLP) from Alibaba, following RocketMQ.

 

Optimize support for asynchrony

Full asynchronous programming based on Dubbo is a new feature introduced in 2.7.0 after enhancements to the existing asynchronous mode. The previous version was not very friendly with asynchronous support and had some problems. Version 2.7 will make some targeted enhancements based on CompletableFuture in JDK8, as well as the @dubboAsync annotation, which can be used to generate asynchronous code.

» Asynchronous mode prior to version 2.6.x

The 2.6.x and previous versions provide asynchronous programming capabilities, including asynchronous Consumer calls, parameter callbacks, event notifications, and more. However, the current asynchronous approach has the following problems:

  • Future retrieval is not straightforward enough;
  • The ResponseFuture interface does not support automatic callback, and the ResponseFuture interface supports callback but supports limited asynchronous scenarios, such as Future coordination or combination, etc.
  • Provider side asynchrony is not supported

Take the asynchronous use of Consumer as an example:

1. Define a generic synchronous interface and declare support for asynchronous calls

Get the Future from RpcContext

From this simple example we can see some inconveniences in use:

  • FindFoo’s synchronous interface cannot directly return a Future that represents an asynchronous result, which is obtained by RpcContext.
  • Future only supports blocking get() interfaces to get results.
  • Callbacks can be set up by obtaining the built-in ResponseFuture interface. However, the ResponseFuture API is inconvenient to use and only supports setting callback in other asynchronous scenarios, such as multiple futures working together.

2.7.0 Enhancements based on CompletableFuture

Those of you who are familiar with the evolution of Futuresin Java should know that futuresused in Dubbo 2.6.x and earlier versions were introduced in Java 5, so there are some of the above functional design issues. CompletableFuture, introduced in Java 8, further enriches the Future interface and solves these problems.

Dubbo has been updated with Java 8 support in version 2.7.0, along with enhancements to the current asynchronous functionality based on CompletableFuture.

1. Support directly defining the service interface that returns CompletableFuture. With this type of interface, we can more naturally implement asynchronous programming on the Consumer and Provider side.

2. If you do not want to define the return value of the interface as a Future, or if there is a defined synchronous interface, you can define an additional asynchronous interface and provide methods of type Future.

In this way, a Provider can only implement the sayHi method; The Consumer can retrieve a Future instance by calling sayHiAsync directly, which the Dubbo framework automatically translates into a call to the sayHi method on the Provider side. Providing an asynchronous method definition for each synchronous method is cumbersome, but further, the AnnotationProcessor implementation in the Dubbo ecosystem automatically generates asynchronous method definitions for us.

3. Also, if your original interface definition is not a Future return value, provider-side Async provides a programming interface similar to the Async Servlet in Servlet3.0: rpcContext.startAsync ().

At the beginning of the method body, rpcContext.startAsync () starts asynchro and starts the new thread to execute the business logic asynchronously. After the time-consuming operation is completed, asyncContext.write writes the result back.

4. RpcContext returns CompletableFuture directly

CompletableFuture<String> f = RpcContext.getContext().getCompletableFuture();

All of the above enhancements are compatible with existing asynchronous programming, so asynchronous programs written based on version 2.6.x can run smoothly without any modifications.

Metadata transformation

The transformation of metadata is mainly carried out from the perspective of adapting the microservice registry, configuring the separated model of the center, reducing the pressure on the registry, and improving the service governance capacity and efficiency. The current version of Dubbo has dozens of key/value pairs in the registry URL, containing all metadata for a service. On the basis of large-scale practice, we gradually found some problems with the metadata of such organizations:

  • The URL stored in the registry is too long:

As a result, the storage pressure increases sharply, and the efficiency of pushing change events decreases significantly. At the same time, it puts additional computational pressure on subscribers, especially the memory for large-scale scenarios, which increases significantly.

  • The registry takes on a plethora of service governance configuration functions:

Responsible for synchronization of initial configuration and storage of various run-time configuration rules. This increases the pressure on registries, and limits the flexibility of configuration rules and the ability to leverage the power of more specialized microservice configuration centers.

  • Attribute function positioning is not clear:

Methods, PID and owner all seem to be attributes registered for service query. However, when we actually develop or operate the service management and control system, we find that such simple information is difficult to meet the demand of query governance. We need richer registration data for more attributes. In the case of Methods, the list of methods is long, but when we tried to develop the service test /mock functionality in OPS, we found that the required data, such as method signatures, were still not available.

To summarize the above, we split the metadata in the URL into three parts:

  • Metadata information

The complete definition of an interface: contains the name of the interface, the method contained in the interface, and the information about the input and output parameters contained in the method. This is very important for service testing and service mocks.

  • Execute data on link

Parameters need to be passed from the provider to the consumer so that the consumer can sense them. Such as token and timeout.

  • The service has configuration &Ops requirements

Used only on the provider or consumer side, such as executes, Document, etc.

Support Configuration Center

The configuration center is a dynamic version of Dubo.properties that supports global, application-level, and service-level granularity. Through the above metadata transformation, configuration center support, plus the original registry, the Dubbo system will exist:

  • Registration Center:

Ideally, the registry would only be used for the synchronization of critical service information (core links), further reducing the storage stress on the registry, improving address synchronization efficiency, and alleviating the current memory computing stress on the Consumer side due to URL redundancy in mass push.

  • Configuration center:

To solve the coupling problem between current configuration and address information, the abstract dynamic configuration layer enables developers to connect to more common and professional configuration centers in microservice scenarios, such as Nacos, Apollo, Consul, Etcd, etc. It provides more flexible and diversified configuration rules, including service and application configurations of different granularity, richer routing rules, and dynamic parameter rules for centralized management.

  • Service Query Governance Center (including metadata)

For purely service query related data, including Consumer’s service subscription data, are usually immutable after registration and do not need synchronization between nodes. For example, methods, owner and other keys can be seen in the current URL, as well as all Consumer side urls.

As a result, we have introduced a storage module in 2.7.0 for this part of the data, which will be closely integrated with the new version of Dubo-OPS as the data base for rich service query, testing and other functions, so this part of the data will be further enriched. In general, this will be optional for users and will be implemented extensible, as we plan to support Redis, Zookeeper, etc.

Routing rules

Dubbo provides some extensibility routing rules, among which the representative ones are conditional routing and script routing. Problems existing in 2.6.x and the following versions:

A. Routing rules are stored in the registry

B. Only service-granularity routes are supported. Application levels cannot define routing rules

C. Route caching is supported, but it is not scalable

D. Multiple routing rules can be defined for a service or application. Service governance cannot be controlled

E. Each rule generates a Router instance and dynamically loads it

We redesigned the routing configuration from the registry to the configuration center based on the problem. The boundaries between configuration and service discovery are clarified. Added RouterChain for reconstructing the logic of routing rules, adding application-level routes, and optimizing Tag routes. Service-level routes are accurate to a single service, avoiding the problem of unclear routing rules.

Let’s briefly outline the collaboration between each class.

  • RegistryDirectory, which contains a complete address list, connects directly to the registry and receives registry address changes dynamically.
  • The RouterChain, a list assembled by the Router, is the entry to the routing action. It receives the incoming address list and returns the filtered address list to the caller. The specific filtering action is delegated to the Router
  • Router: receives and parses routing rules, receives the IP address list, completes filtering according to routing rules, and returns the filtered IP address list. It is also a ConfigurationListener, which receives routing rule updates at any time.
  • ConfigurationListener, a callback interface that dynamically configures changes
  • DynamicConfiguration, DynamicConfiguration SPI, supports extended implementations including Zookeeper, Apollo, Nacos, etc

Dubbo will release version 2.7.0 soon, exactly one year after the reboot was announced. This year, Dubbo released a total of 13 versions, with 24 PPMC/ committers and 144 contributors in the community. 5 developer salons were held in Beijing, Shanghai, Shenzhen, Chengdu and Hangzhou. However, there is no end to the road of technology open source, and we welcome more developers to participate. And come to Dubbo Meetup to share and build Dubbo ecology together.