By Cairong Sun
This article provides real project examples and code demonstrations to explain step-by-step how to achieve interoperability between Apache Dubbo and Spring Cloud with minimal cost. It also guides on how to implement hybrid deployment and migration of different microservice systems, helping readers solve practical architecture and business problems.
If you are facing the following business scenarios during microservice development, this article can be helpful:
• You already have a set of microservice applications built on Dubbo. Now, you need to publish some services in the form of REST HTTP (non-interface, method mode) for standard HTTP clients like Spring Cloud client to call. It is preferred to add configuration and annotations to the existing Dubbo service without rewriting the code.
• You have a microservice system built on Spring Cloud, and you have also built a Dubbo-based microservice system. You want these two systems to coexist, meaning they need to call services published by each other. Dubbo applications should be able to call HTTP interfaces published by Spring Cloud, and Dubbo applications can also publish HTTP interfaces for Spring Cloud to call.
• Due to certain reasons, you are planning to migrate from one microservice system to another, with a smooth transition in the intermediate process.
For the above scenarios, we can utilize the built-in REST programming paradigm of Dubbo 3. This enables Dubbo to not only consume HTTP interface services but also publish REST-style HTTP services without changing any code. The coding process supports REST programming paradigms commonly used in the industry, such as JAX-RS and Spring MVC. This allows for seamless communication between Dubbo and Spring Cloud systems.
This section demonstrates how to utilize Dubbo to access Spring Cloud services, including automatic address discovery and protocol transmission. The example assumes that you already have a Spring Cloud microservice system. In this case, Nacos is used as the registry, but the approach is also applicable to other supported registries like Zookeeper and Consul.
To enable Dubbo applications to call services published by Spring Cloud, we will introduce the Dubbo framework. The complete source code for this example can be found in the samples/dubbo-call-sc [3].
The structure of the Spring Cloud application in the example is as follows:
The application configuration file is as follows:
server:
port: 8099
spring:
application:
name: spring-cloud-provider-for-dubbo
cloud:
nacos:
serverAddr: 127.0.0.1:8848 # Registry.
The following is a simple Controller definition that publishes an HTTP endpoint: /users/list/.
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/list")
public List<User> getUser() {
return Collections.singletonList(new User(1L, "spring cloud server"));
}
}
Start SpringCloudApplication, and test whether the application is started by accessing http://localhost:8099/users/list through cURL or a browser.
The Dubbo client is also a standard Dubbo application. The basic structure of the project is as follows:
In this structure, one of the more critical points is the following interface definition (Under normal circumstances, the following interface can be directly copied from the original Spring Cloud client application as it is without any modification).
If there was no Spring Cloud consumer application based on OpenFeign, you need to define an interface by yourself. In this case, you do not need to use OpenFeign annotations, and it is enough to use Spring MVC standard annotations.
Use the DubboReference annotation to register a UserServiceFeign interface as a Dubbo service.
@DubboReference
private UserServiceFeign userService;
Next, we can call the service in the Dubbo standard way.
List<User> users = userService.users();
Start the Dubbo application through DubboConsumerApplication and verify that the call to the Spring Cloud service is successful.
In the following example, I will show you how to open the services published by the Dubbo server to the Spring Cloud client for calling.
For the relevant source code of the example, see samples/sc-call-dubbo[4].
A Dubbo server is a typical Dubbo application with a simple code structure.
Compared with the common Dubbo service definition, we need to add the following standard Spring MVC annotations to the interface:
@RestController
@RequestMapping("/users")
public interface UserService {
@GetMapping(value = "/list")
List<User> getUsers();
}
In addition to the preceding annotations, other processes, such as service publishing, are the same. You can use DubboService annotations to publish a service:
@DubboService
public class UserServiceImpl implements UserService {
@Override
public List<User> getUsers() {
return Collections.singletonList(new User(1L, "Dubbo provider!"));
}
}
In terms of service configuration, it should be noted that we need to configure the service protocol to rest protocol: rest. The address discovery mode uses register-mode: instance:
dubbo:
registry:
address: nacos://127.0.0.1:8848
register-mode: instance
protocol:
name: rest
port: 8090
Start the Dubbo application and verify whether the service runs normally by accessing the following address: http://localhost:8090/users/list.
Use OpenFeign to develop a standard Spring Cloud application to call the Dubbo service published above. The code structure of the project is as follows:
In this structure, we define an OpenFeign interface to call the Dubbo REST service published above.
@FeignClient(name = "dubbo-provider-for-spring-cloud")
public interface UserServiceFeign {
@RequestMapping(value = "/users/list", method = RequestMethod.GET)
List<User> getUsers();
}
Define the following controller as the test entry of OpenFeign and RestTemplate:
public class UserController {
private final RestTemplate restTemplate;
private final UserServiceFeign userServiceFeign;
public UserController(RestTemplate restTemplate,
UserServiceFeign userServiceFeign) {
this.restTemplate = restTemplate;
this.userServiceFeign = userServiceFeign;
}
@RequestMapping("/rest/test1")
public String doRestAliveUsingEurekaAndRibbon() {
String url = "http://dubbo-provider-for-spring-cloud/users/list";
System.out.println("url: " + url);
return restTemplate.getForObject(url, String.class);
}
@RequestMapping("/rest/test2")
public List<User> doRestAliveUsingFeign() {
return userServiceFeign.getUsers();
}
}
According to the preceding controller definition, we can access the following addresses for verification:
• OpenFeign: http://localhost:8099/dubbo/rest/test1.
• RestTemplage: http://localhost:8099/dubbo/rest/test2.
We can use the multi-protocol publishing mechanism of Dubbo to configure multi-protocol publishing for some services. Next, we will add the Dubbo TCP protocol release to the Dubbo Server service mentioned above to achieve the following deployment effect: this Dubbo application can serve both the Dubbo microservice system and the Spring Cloud microservice system.
To achieve this effect, we only need to add multi-protocol configuration to the original configuration:
dubbo:
protocols:
- id: rest
name: rest
port: 8090
- id: dubbo
name: dubbo
port: 20880
At the same time, the service annotation is also configured with multi-protocol publishing:
@DubboService(protocol="rest,dubbo")
public class UserServiceImpl implements UserService {}
In this way, we published the UserService service with the Dubbo and REST protocols (multi-port multi-protocol mode). The Dubbo protocol serves the Dubbo system, and the REST protocol serves the Spring Cloud system.
Note: Dubbo provides single-port and multi-port methods for multi-protocol publishing, which is helpful for services in different deployment environments. Before determining the multi-protocol publishing method that you need, read the following multi-protocol configuration [5] document carefully.
Based on the REST programming paradigm, multi-protocol publishing, Dubbo can assist in easily releasing Dubbo services using the HTTP protocol. This allows backend services to communicate efficiently through RPC and seamlessly connect with the HTTP service system. The provided example demonstrates the coding process for the coexistence and interoperability of Dubbo and Spring Cloud systems.
The official release of this feature will be available in Dubbo version 3.3.0, which also includes a significant upgrade to the Triple protocol. Stay tuned.
[1] Blog Post (In Chinese)
https://cn.dubbo.apache.org/zh-cn/blog/2023/01/05/dubbo-%e8%bf%9e%e6%8e%a5%e5%bc%82%e6%9e%84%e5%be%ae%e6%9c%8d%e5%8a%a1%e4%bd%93%e7%b3%bb-%e5%a4%9a%e5%8d%8f%e8%ae%ae%e5%a4%9a%e6%b3%a8%e5%86%8c%e4%b8%ad%e5%bf%83/
[2] REST User Reference Manual (In Chinese)
https://cn.dubbo.apache.org/zh-cn/overview/reference/proposals/protocol-http/
[3] samples/dubbo-call-sc
https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-springcloud/dubbo-call-sc
[4] samples/sc-call-dubbo
https://github.com/apache/dubbo-samples/tree/master/2-advanced/dubbo-samples-springcloud/sc-call-dubbo
[5] Multi-protocol Configuration (In Chinese)
https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/multi-protocols/
Kruise Rollout: A Scalable Traffic Scheduling Scheme Based on Lua Scripts
How to Select Open Source Microservices? Detailed Comparison of Spring Cloud, Dubbo, gRPC, and Istio
506 posts | 48 followers
FollowAlibaba Cloud Native Community - November 22, 2023
Alibaba Cloud Native Community - September 12, 2023
Alibaba Cloud Native Community - August 21, 2023
Alibaba Developer - January 20, 2022
Alibaba Cloud Native Community - February 22, 2023
Aliware - April 10, 2020
506 posts | 48 followers
FollowMSE provides a fully managed registration and configuration center, and gateway and microservices governance capabilities.
Learn MoreCustomized infrastructure to ensure high availability, scalability and high-performance
Learn MoreAccelerate and secure the development, deployment, and management of containerized applications cost-effectively.
Learn MoreAccelerate software development and delivery by integrating DevOps with the cloud
Learn MoreMore Posts by Alibaba Cloud Native Community