Dubbo is an open source RPC call framework from Alibaba. The implementation complexity of RPC remote calls can be greatly simplified and the implementation of business capabilities can be more focused. Remote service interfaces can be used just like local API calls.
This article will document some of the key information about Dubbo and show you how to use Dubbo in your code.
1. Key concepts of Dubbo
1.1 Basic principles of DUBBO
A basic networking and schematic diagram of Dubbo is as follows (picture taken from network) :
Node roles:
Provider: exposes the service Provider of the service. Consumer: Service Consumer that invokes the remote service. Registry: A Registry where services are registered and discovered. Monitor: monitors The Times and time of service invocation.
Please refer to the official Dubbo documentation for more details.
1.2 DUBBO’s support for the agreement
1. Dubbo can select a protocol
Dubbo
Protocol, adoptedNIO
Reuse a single long connection, and useThe thread pool
** (recommended) ** [Problem: In large file transfers, a single connection can become a bottleneck]Rmi
Protocols are available with nativeRMI
Interoperable based onTCP
The agreement. [Problem: Occasionally the connection fails and the Stub needs to be rebuilt]Hessian
Protocols are available with nativeHessian
Interoperable based onHTTP
Protocol [requires hessian.jar support, HTTP short connection overhead]
2. Dubbo can be serialized in a variety of ways
Hessian Serialization
, good performance, multi-language supportDubbo Serialization
, by not transmitting the class meta information of POJOs, the performance is good when a large number of POJOs are transmitted.Json Serialization
, plain text, can be parsed across languages, FastJson is used by defaultJava Serialization
Java native support [Problem: poor performance]
3. The default protocol is Dubbo, which is serialized as Hessian
1.3 Differences between service ports and Dubbo protocol ports
When a process starts, it has a port, such as the SpringBoot service. In application. Properties, a server.port value is set.
Dubbo is an independent protocol. When providing services externally, you need to specify a port corresponding to dubbo. The two ports need to be separated, not the same, which is easy for beginners to confuse.
Dubbo port can be specified in two ways:
-
- Specified in the XML
<! Expose service on port 20880 with dubbo
<dubbo:protocol name="dubbo" port="20880" ></dubbo:protocol>
Copy the code
-
- SpringBoot engineering, code specified
@Bean
public ProtocolConfig protocolConfig(a) {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(8811);
protocolConfig.setName("dubbo");
return protocolConfig;
}
Copy the code
2 Dubbo service code implementation
In complex and large distributed systems, service registries are usually required. By default, Dubbo works with Zookeeper as the registry and can be connected to other distributed service registries. It is recommended to use Ali’s open source Nacos as the matching registry for Dubbo. For details, please refer to my other article “Playing with Nacos! Instead of Eureka as configuration center and Registry”.
The following sample code demonstrates a scenario in which a consumer makes a call directly to a service provider without using a registry, with the main focus on how to integrate and use Dubbo.
2.1 SpringBoot integrates Maven dependencies corresponding to Dubbo
The Dubbo package needs to be imported (for example, no registry is used, so zooKeeper-related packages are not needed).
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
Copy the code
2.2 Service Provider Service Provider
2.2.1 Implement defined RPC interfaces that need to be opened to the outside world, and implement specific implementation logic
The @component Component will automatically Spring host the service according to SpringBoot logic and complete the initial load. 2, @ com. Alibaba. Dubbo. Config. The annotation. The Service is the provided dubbo, said this is need to dubbo external services.
As follows:
@Component
@com.alibaba.dubbo.config.annotation.Service(timeout = 5000)
public class RpcDemoServiceImpl implements RpcDemoService {
@Override
public String queryCurrentTime(String queryId) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String formattedDate = simpleDateFormat.format(new Date());
System.out.println(queryId + " called, current time is: " + formattedDate);
return queryId + "|"+ formattedDate; }}Copy the code
2.2.2 The Dubbo directory to be scanned is defined in the Startup class
@springBootApplication specifies that a regular SpringBoot application should be started. 2, @ EnableDubbo open support for Dubbo, and specify the corresponding directory, will scan the specified directory of class, to find all the @ com. Alibaba. Dubbo. Config. The annotation. The Service identification needs to release to Dubbo Service interface classes.
As follows:
@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.vzn.local.dubbo.provider.service"})
public class ProviderApp {
public static void main(String[] args) { SpringApplication.run(ProviderApp.class); }}Copy the code
2.2.3 Specifying Dubbo Settings
Either way, it can be written directly in code or specified in a configuration file.
2.2.3.1 Specified by Bean injection in code
Key definitions of Dubbo are injected via @bean. As with the XML configuration, specific values are set here in the form of the corresponding JAVA object.
ApplicationConfig corresponds to the configuration information of the
2. ProtocolConfig corresponds to the configuration information of the dubbo:protocol /> node in XML.
RegistryConfig corresponds to the configuration information of the
Example code is as follows:
@Configuration
public class DubboConfig {
@Bean
public ApplicationConfig applicationConfig(a) {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-provider");
return applicationConfig;
}
@Bean
public ProtocolConfig protocolConfig(a) {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setPort(8811);
protocolConfig.setName("dubbo");
return protocolConfig;
}
@Bean
public RegistryConfig registryConfig(a) {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("N/A");
registryConfig.setRegister(false);
/ / registryConfig. SetAddress (" zookeeper: / / 127.0.0.1:2181 ");
returnregistryConfig; }}Copy the code
2.2.3.2 throughapplication.properties
In the configuration
spring.application.name=dubbo-provider
server.port=28811
# dubbo config
dubbo.application.id=dubbo-provider
dubbo.application.name=dubbo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=8811
dubbo.registry.address=N/A
Copy the code
At this point, a simple SpringBoot logic that integrates dubbo with code and annotations is ready to boot.
Note:
- The local test DEMO is directly invoked without setting a registry, so the address specified in RegistryConfig is
N/A
;- In actual use, if
zookeeper
As the registry, set this parameter tozookeeper
The correspondingIP
andport
Value. (of course,Or you can chooseNacos
Use as a configuration + registry, recommended)
Service Consumer
2.3.1 Local Reference RPC service interface to implement the corresponding Service class
To implement a simple SpringBoot project, in conventional @ the class of Service identification, the introduction of remote RPC Service corresponding to the local API interface, and through the @ com. Alibaba. Dubbo. Config. The annotation. The Reference annotations are identified, This annotation means that the bean will call the method in the remote real implementation class via RPC and return the execution result.
This is an advantage of Dubbo framework, will all the underlying logic to encapsulate blocked, making business code used in RPC interface, can be carried out in accordance with the local API way direct call, greatly reduces the coding difficulty, allowing developers to focus on their own business, without having to focus on specific how should the RPC calls to the remote server.
Example code is as follows:
@org.springframework.stereotype.Service
public class RpcConsumerService {
// @Reference
// private RpcDemoService rpcDemoService;
// Both parameters specified in the following ways can be called successfully
@Reference(protocol = "dubbo", url = "172.31.236.79:8811", interfaceClass = RpcDemoService.class)
/ / @ Reference [url = "dubbo: / / 172.31.236.79:8811)"
private RpcDemoService rpcDemoService;
public String getTime(String requestId) {
returnrpcDemoService.queryCurrentTime(requestId); }}Copy the code
Description:
The local DEMO code has no registry and is directly connected. Therefore, the url information (specific IP address of the directly connected service and Dubbo protocol port) is specified in @Reference.
2.3.2 Enable Dubbo support in startup class
As follows:
@SpringBootApplication
@EnableDubbo(scanBasePackages = {"com.vzn.local.dubbo.consumer.service"})
public class ConsumerApp {
public static void main(String[] args) { SpringApplication.run(ConsumerApp.class); }}Copy the code
2.3.3 Manually injecting Dubbo configuration information into the code
The following is similar to provider, but slightly different:
@Configuration
public class DubboConfig {
@Bean
public ApplicationConfig applicationConfig(a) {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("dubbo-consumer");
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig(a) {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("N/A");
/ / registryConfig. SetAddress (" zookeeper: / / 127.0.0.1:2181 ");
registryConfig.setClient("curator");
return registryConfig;
}
@Bean
public ConsumerConfig consumerConfig(a) {
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setTimeout(3000);
returnconsumerConfig; }}Copy the code
Or configure it directly in application.properties:
spring.application.name=dubbo-consumer server.port=28812 # dubbo config dubbo.application.id=dubbo-consumer dubbo.application.name=dubbo-consumer dubbo.protocol.name=dubbo dubbo.registry.address=N/A dubbo.registry.client=curator dubbo.server=false dubbo.consumer.timeout=3000Copy the code
The consumer service adds a configuration called ConsumerConfig, which in this example simply defines a call-side timeout value.
2.3.4 Provide a Controller service for test calls
As usual with SpringBoot, a Controller service is provided to trigger test use.
@RestController
@RequestMapping("/demo/dubbo")
public class RpcController {
@Resource(name = "rpcConsumerService")
private RpcConsumerService service;
@GetMapping("/get/time/{requestId}")
public String getTime(@PathVariable("requestId") String requestId) {
String time = service.getTime(requestId);
System.out.println("RPC call the getTime result:" + time);
returntime; }}Copy the code
At this point, a simple SpringBoot implementation of the Dubbo client service is complete, and after startup, the Controller service can be invoked to verify the effect.
2.4 Test call validation
We can start the Provider and Consumer services and then send a notification in the browser to trigger the Consumer service:
http://127.0.0.1:28812/demo/dubbo/get/time/1
Copy the code
Test results:
1 | 14:21:11 2019-12-23. 463Copy the code
It can be found that when the method in consumer is executed, RPC in the Consumer process calls the corresponding method in the provider process and returns the specific execution result of the method. The test verification is completed.
Welcome to pay attention to my public account “Architecture Record”, the first time to push original technical articles, can also interact with the discussion of communication technology.