By Liu Jun, nicknamed Lugui at Alibaba.
Apache Dubbo is a remote procedure call or RPC based service framework for programming. It provides an interface proxy-oriented service programming model to shield developers from underlying remote communication details. This is its biggest advantage. Dubbo is also a service governance framework, which provides service governance solutions such as service discovery and traffic scheduling for distributed microservices.
In this article, we are going to explore how to interconnect heterogeneous microservice systems with Dubbo's support for multi-protocol multi-service discovery models in addition to the previously discussed basic capabilities. This can solve communication problems in scenarios where multiple heterogeneous systems co-exist and helps companies smoothly migrate applications among heterogeneous systems, and also helps to support address discovery and traffic scheduling in scenarios where multiple large clusters are deployed across regions.
Dubbo is a microservice development framework. Spring is generally used as the basic development framework for Java applications, whereas Dubbo is often used as a basic development framework for microservices. Dubbo provides an interface-oriented programming model that allows developers to call remote services in the same way as local services. This is the greatest advantage of Dubbo. The following example describes how to develop a service in Java:
1. Define the service.
public interface GreetingsService {
String sayHi(String name);
}
2. The consumer calls the service.
// 和调用本地服务一样,完全透明。
@Reference
private GreetingService greetingService;
public void doSayHello(String name) {
greetingService.sayHi("Hello world!");
}
The following figure illustrates how Dubbo works. The service provider and consumer negotiate the address through a registry and exchange data over the agreed protocol.
Here I want to describe the challenges of building an internal microservice system for a company and how to select the architecture and migrate applications based on Dubbo.
The microservices of a company that are developed based on the same framework like Dubbo are called homogeneous microservices. Microservices that are developed based on different frameworks are called heterogeneous microservices. For a variety of reasons, is still common for a large organization to have multiple microservice systems of different stacks. For example, it may be caused by a legacy system, or it may be that the company is migrating its stacks or it could be that different service departments select different frameworks to meet their special needs, resulting in the long-term co-existence of heterogeneous microservice systems.
1. Coexistence of Heterogeneous Microservice Systems
Different systems usually communicate over different RPC protocols and have independent registry clusters. The challenge is how to implement transparent address discovery and transparent RPC calls in such a scenario. If no measures are taken, each microservice system can only detect the status of its own services and traffic is restricted within each system. If you want to smoothly migrate your application from, say, system A to system B, or to maintain multiple systems for an extended period of time, you must interconnect the different systems interconnected and implement transparent traffic scheduling.
2. Inside the Dubbo System
Homogeneous microservice systems may also face challenges from multi-protocol and multi-registry clusters, especially when the number of microservices increase to a certain level.
In summary, both homogeneous and heterogeneous systems face the problem of address discovery for multi-protocol communication and multi-registry clusters. Currently, Dubbo supports multiple protocols and multiple registries, and can therefore solve the problems of Dubbo-based homogeneous systems. Next, I want to describe Dubbo's support for multi-protocol and multi-registry communication and how Dubbo works in scenarios where homogeneous systems support multiple protocols and are deployed in multiple registries. Then, I will explain how to expand this capability to interconnect heterogeneous microservice systems.
Let's look at the Dubbo multi-protocol, multi-registry mechanism and how it works in two different scenarios.
The above figure shows a set of microservices developed based on Dubbo. Different protocols are used for inter-service communication. Our survey showed that it is very common for a company to use multiple protocols internally.
Application B is the service provider and has published five services, of which:
DemoService1
and DemoService2
are published over Dubbo
.DemoService3
and DemoService4
are published over gRPC
.DemoService0
is published over Dubbo
and gRPC
.Application A is the consumer which consumes DemoService1
and DemoService2
over Dubbo and consumes DemoService0
over gRPC.
Application B is also a consumer which consumes DemoService2
and DemoService4
over gRPC and consumes DemoService0
over Dubbo.
The code configuration is as follows:
1. Provider Application B
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService1" protocol="dubbo"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService2" protocol="dubbo"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService3" protocol="grpc"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService4" protocol="grpc"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService0" protocol="dubbo, grpc"/>
2. Consumer Application A
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService1"/>
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService2"/>
<dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService0"/>
3. Consumer Application C
<dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService3"/> <dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService4"/>
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService0"/>
Currently, Dubbo supports most mainstream RPC protocols, such as Dubbo, REST, Thrift, gRPC, JSON-RPC, and Hessian. Note that these protocols are supported by directly integrating the official release implementations. As such, the stability of protocol resolution is ensured and the Dubbo community can focus its efforts on improving Dubbo's peripheral service governance capabilities. If the Dubbo community provides an implementation for each protocol, too much time and effort would be required to make each protocol stable and available in production.
In addition to the above officially supported protocols, developers can add more protocols at any time based on Dubbo's flexible extension mechanism, including their own protocol extensions.
When the service cluster is small, a centralized cluster deployment solution can effectively solve business problems. However, as applications and user traffic increase, you must introduce a cross-region and multi-cluster deployment solution for business systems and select a deployment solution for registry clusters closely related to business systems. Solutions include:
The following is a specific solution provided by Dubbo for multi-registry cluster scenarios.
In the above figure, two service clusters exist, one deployed in Beijing and the other deployed in Shanghai. Each service cluster has an independent registry cluster. The following describes how to implement transparent RPC service communication between the two service clusters.
1. The service provider publishes services in both registries.
<dubbo:registry id="beijingRegistry" address="zookeeper://{zookeeper.address1}" default="false"/> <dubbo:registry id="shanghaiRegistry" address="zookeeper://${zookeeper.address2}" />
<dubbo:service interface="org.apache.dubbo.samples.multi.registry.api.HelloService" ref="helloService" registry="shanghaiRegistry,beijingRegistry"/>
<dubbo:service interface="org.apache.dubbo.samples.multi.registry.api.DemoService" ref="demoService" registry="shanghaiRegistry,beijingRegistry"/>
2. The service consumer subscribes to one or two registries based on consumption needs.
<dubbo:registry id="beijingRegistry" address="zookeeper://{zookeeper.address1}" default="false" preferred="true" weight="100"/> <dubbo:registry id="shanghaiRegistry" address="zookeeper://${zookeeper.address2}" default="true" weight="20"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.DemoService"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.DemoService" registry="beijingRegistry, shanghaiRegistry"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.HelloService" registry="beijingRegistry"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.HelloService" registry="shanghaiRegistry,shanghaiRegistry"/>
In multi-registry cluster scenarios, the same registry products, such as ZooKeeper and Nacos, are deployed. For registry migration, Dubbo must support more registry products or, most importantly, have good scalability. Currently, Dubbo supports the following registries:
Note that, in Dubbo, service registration and discovery models are based on interfaces. Application-level service registration and discovery models are introduced in Dubbo 2.7.5 and later versions. This helps optimize Dubbo's current service discovery mechanism and improve service capacity. In addition, it is important to interconnect microservice systems, such as Spring Cloud. We will discuss this feature in the next chapter. More information about "Application-level Service Discovery: Service Self-reflection" will be provided in future articles and documentation.
Following the introduction of multi-registry clusters, Dubbo provides load balancing among the registry clusters when selecting the traffic address:
At the Cluster Invoker level, the following address selection policies are supported, applicable to Dubbo 2.7.5 and later versions:
<!-- 来自 preferred="true" 注册中心的地址将被优先选择,只有该中心无可用地址时才 Fallback 到其他注册中心 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" preferred="true" />
<!-- 选址时会和流量中的 zone key 做匹配,流量会优先派发到相同 zone 的地址 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" zone="beijing" />
<!-- 来自北京和上海集群的地址,将以 10:1 的比例来分配流量 -->
<dubbo:registry id="beijing" address="zookeeper://${zookeeper.address1}" weight="100" />
<dubbo:registry id="shanghai" address="zookeeper://${zookeeper.address2}" weight="10" />
Now that we have introduced the possibilities of heterogeneous microservice systems in an organization, let's look at the actual scenarios of heterogeneous microservice systems and how we can interconnect these systems with Dubbo. The following figure describes a specific scenario with interconnected heterogeneous microservice systems.
As shown above, some microservices are built based on Spring Cloud, gRPC, Kubernetes, and on-premises systems. By default, they are isolated from each other and cannot be interconnected. When you want to build a Dubbo-based microservice system, you can use Dubbo's multi-protocol and multi-service discovery model to interconnect microservice systems. Further, as shown by the orange arrows in the figure, you can connect two heterogeneous microservice systems by using the Dubbo system as the bridge layer.
In the following example scenarios, for lack of a uniform standard for address discovery, we assume that different systems are interconnected at the address discovery level. I will mainly introduce the basic migration process and communication protocols. Address discovery will be further discussed in the article Application-level Service Discovery: Service Self-reflection.
For the vast majority of developers, when Dubbo is used to develop a microservice system, the optimal solution is to use the Dubbo protocol for communication between services. In fact, the Dubbo RPC protocol is not the only choice. Dubbo is both a microservice development framework and an RPC protocol, but these are two separate concepts. For example, for a service system developed with a Dubbo framework, you can choose REST, gRPC, or other protocols supported by Dubbo for communication based on your service features and technical plans.
Currently, increasing attention has been paid to HTTP1/2 and gRPC protocols in cloud-native and mesh applications. One reason is that the HTTP1/2 and gRPC protocols are superior to other protocols in terms of standardization, universality, penetrability, and support from network devices and infrastructure. For many enterprises that want to migrate their cloud-native applications, these protocols undoubtedly help subsequently upgrade their architectures.
The following figure shows an intermediate state in the process of migrating applications in a Dubbo system from the Dubbo protocol to the gRPC protocol.
As mentioned above, due to the problem of the service discovery model between Spring Cloud and Dubbo, Dubbo needs to be adapted so the two systems can be interconnected. For more information about this procedure, see Application-level Service Discovery: Service Self-reflection V2.7.5. Here, we assume that the two systems have already been interconnected.
In the Dubbo system, some applications serve as the key nodes for transparently interconnecting the two systems. Some service providers publish services over two protocols, and some consumers only consume services over the specified protocol. Because no changes can be made to the old Spring Cloud system, the key to interconnecting the two systems is the REST protocol. For Dubbo applications:
For applications that consume Spring Cloud services, you must configure the services as follows:
<dubbo:reference interface ="xxx.SpringService" protocol="rest"/>
For applications that provide services for the Spring Cloud system to consume, you must expose the services over the REST protocol or two protocols, if the services are called by applications in the new system, as follows:
<dubbo:service interface="xxx.NewService" protocol="rest,dubbo"/>
As we ourselves use Dubbo, the focus of this article is on how to migrate services from a Spring Cloud system to a Dubbo system. If you have developed or plan to develop microservices based on Dubbo, you can migrate your services from the Dubbo system to a Spring Cloud system in a similar way. Dubbo's multi-protocol and multi-registry model provides the same flexibility for two-way migration.
This scenario is similar to the Spring Cloud migration described in the previous section. The biggest difference is that the REST protocol is supported by Dubbo by default. To deal with the proprietary communication protocol in the existing microservice system, you need to extend the Dubbo protocol to support your protocol.
For coexistence of and migration between heterogeneous microservice systems, the key is to make the protocol
and service discovery models
universal among the heterogeneous systems. With its support for multi-protocol and multi-registry models, Dubbo can be used as a bridge between heterogeneous microservice systems. However, when you have a large number of services, multi-protocol registration will double the number of addresses and therefore affect the address push performance. In the section "Connect Heterogeneous Microservice Systems with Dubbo", I did not detail how to implement transparent service discovery between heterogeneous systems. I will discuss service in more detail in my future articles.
About the Author: Liu Jun is the core maintainer of Apache Dubbo PMC. He has witnessed the whole process from the renewed popularity of Dubbo in the open-source community to the rise of Apache Dubbo. His GitHub account is Chickenlj. Currently, he works in the Alibaba Cloud native applications and platforms team and is engaged in the development of service frameworks and microservices. He is a promoter of the cloud-native application of open-source Dubbo.
208 posts | 12 followers
FollowAlibaba Cloud Native - October 9, 2021
Aliware - August 18, 2021
Alibaba Cloud Native Community - December 19, 2023
Alibaba Cloud Native Community - July 20, 2021
kirito.moe - April 14, 2020
Alibaba Cloud Native Community - November 22, 2023
208 posts | 12 followers
FollowA fully-managed Apache Kafka service to help you quickly build data pipelines for your big data analytics.
Learn MoreMSE provides a fully managed registration and configuration center, and gateway and microservices governance capabilities.
Learn MoreAlibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.
Learn MoreProvides a control plane to allow users to manage Kubernetes clusters that run based on different infrastructure resources
Learn MoreMore Posts by Alibaba Cloud Native