Dubbo for the First Experience of RPC Framework
Version description: dubbo 2.7.2
Dubbo is an RPC framework of Ali Open Source, which was mentioned recently when learning micro services. So we have an introductory experience of Dubbo. Here we mainly experience several configurations of Dubbo, such as XML configuration, API configuration, annotation configuration, and integration of Dubbo in Springboot. We also experience several registries, such as simple, zk, redis, multicast.
Dubbo's official website is rich in content and supports Chinese. Address: http://dubbo.apache.org/zh-cn/docs/user/quick-start.html
1 Dubbo configuration usage
1.1 Configuration based on native API
Official Documents: http://dubbo.apache.org/zh-cn/docs/user/configuration/api.html
How to say, when referring to the official website, we stepped on a lot of pits, because the registry provided by the official website can not be used, is the first contact, has taken many detours, and oneself is a rectum, we have to implement a registry by oneself, and then refer to the example of Simple registry given by the official website, there are two compelling points. I'm obsessive-compulsive, first of all, using XML configuration to create registry services, and I just want to implement it through native API, the other one.
<! - Simple registry implementation, self-expanding to achieve cluster and state synchronization - > <bean id="registryService" class="org.apache.dubbo.registry.simple.SimpleRegistryService" />
The class org. apache. dubbo. registry. simple. SimpleRegistry Service mentioned above, I can't find it. It's been a day of tangling over these two issues. It was finally solved and found in the Dubbo source test file on github. Ten thousand CNMs are running in my heart. Returning to the topic, using native API to configure is actually creating their own instance, passing in configuration parameters, starting services. Here is a step-by-step explanation.
1.1.1 Project preparation
First create a module called dubbo-demo-api, and then create three sub-modules under that module
dubbo-demo-api/ ├── dubbo-demo-api-api ├── dubbo-demo-api-consumer ├── dubbo-demo-api-provider └── pom.xml
- dubbo-demo-api-api: Provide demo interface
- dubbo-demo-api-consumer: service consumers
- dubbo-demo-api-provider: service provider
1.1.2 dubbo-demo-api-api module
This module mainly provides the interface for demonstration, and creates the DemoService interface under the learn.demo.dubbo.api.api package, as follows
package learn.demo.dubbo.api.api; /** * Created by shirukai on 2019-06-20 09:23 * DemoService Interface */ public interface DemoService { String sayHello(String name); }
1.1.3 dubbo-demo-api-provider module
This module is to create a dubbo provider service. First, we need to introduce dubbo dependencies
<!-- dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.2</version> </dependency>
Then introduce api module
<dependency> <groupId>learn.demo</groupId> <artifactId>dubbo-demo-api-api</artifactId> <version>1.0</version> <scope>compile</scope> </dependency>
1.1.3.1 Implementing DemoService Interface
The DemoService interface we defined in the API module above is implemented under the package learn.demo.dubbo.api.provider. Create a class named DemoServiceImpl, which reads as follows:
package learn.demo.dubbo.api.provider; import learn.demo.dubbo.api.api.DemoService; /** * Created by shirukai on 2019-06-20 09:25 * DemoService Interface Implementation */ public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "This service base in API.\nHello " + name; } }
1.1.3.2 Implementation of Simple Registry
Here, before implementing Provider, we first implement the following Simple Registry. We also mentioned that when we talk about Simple Registry on the official website, we use Spring's XML configuration to generate beans and then create services. Moreover, the Simple Registry Service class mentioned in the article can not be found. After the ninety-eighty-one difficulty, we can use API here. Implement a Simple Registry. There are several classes needed: AbstractRegistry Service, SimpleRegistry Exporter, SimpleRegistry Service. These classes can be found on dubbo's GitHub at https://github.com/apache/dubbo/tree/master/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo.
We can create the org.apache.dubbo.registry package in our own project and then copy the three classes into it.
Create the SimpleRegistryService Provider class under the learn.demo.dubbo.api.provider package to provide Registry services. The code is as follows:
package learn.demo.dubbo.api.provider; import org.apache.dubbo.registry.SimpleRegistryExporter; /** * Created by shirukai on 2019-06-20 09:32 * <p> * Simple Registry Service Provider * Simple Registry Based on Registry Service Interface * Code location: * https://github.com/apache/dubbo/tree/master/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo */ public class SimpleRegistryServiceProvider { public static void main(String[] args) throws Exception { // Exposure registry service, port 9090 SimpleRegistryExporter.export(9090); // Arbitrary Input Exit System.in.read(); } }
1.1.3.3 Implementation of DemoService Provider
Using Dubbo's native API to implement the producer, the general process is as follows:
- To create application configuration Application Config, we can set application name, qos port and so on.
- Create registry configuration Registry Config, you can set the type of registry, address, port, user name, password, etc.
- Create a Service Config service configuration. This instance is important and has a connection to the registry.
- Exposure service export
The contents are as follows:
package learn.demo.dubbo.api.provider; import learn.demo.dubbo.api.api.DemoService; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.ServiceConfig; /** * Created by shirukai on 2019-06-20 09:30 * <p> * DemoService Producer * The Demo registry uses a custom registry, SimpleRegistry Service * So before starting the service, you need to start the registry first. */ public class DemoServiceProvider { public static void main(String[] args) throws Exception { // Application Configuration ApplicationConfig applicationConfig = new ApplicationConfig("api-demo-service-provider"); // qos default port 2222222 needs to be manually modified when multiple services are started locally at the same time applicationConfig.setQosPort(22222); // Registry Configuration RegistryConfig registryConfig = new RegistryConfig("127.0.0.0:9090"); // Service configuration. This instance is very heavy. It encapsulates the connection to the registry. Please cache it yourself, otherwise it may cause memory and connection leaks. ServiceConfig<DemoService> service = new ServiceConfig<>(); service.setApplication(applicationConfig); service.setRegistry(registryConfig); service.setInterface(DemoService.class); service.setRef(new DemoServiceImpl()); // Exposure services service.export(); // Enter and exit arbitrarily System.in.read(); } }
1.1.4 dubbo-demo-api-consumer module
dubbo service consumers still need to introduce jar packages of dubbo and custom api.
<!-- dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.2</version> </dependency> <dependency> <groupId>learn.demo</groupId> <artifactId>dubbo-demo-api-api</artifactId> <version>1.0</version> <scope>compile</scope> </dependency>
The implementation of consumer is similar to the provider step
- Create Application Config for Application Configuration
- Create a configuration center to configure Registry Config
- Create Service Reference Config
- Get an interface instance
The code is as follows:
package learn.demo.api.consumer; import learn.demo.dubbo.api.api.DemoService; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; /** * Created by shirukai on 2019-06-20 09:53 * DemoService Consumer */ public class DemoServiceConsumer { public static void main(String[] args) { // Application Configuration ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-demo-api-consumer"); applicationConfig.setQosPort(22223); // Configure the registry RegistryConfig registryConfig = new RegistryConfig("127.0.0.1:9090"); ReferenceConfig<DemoService> reference = new ReferenceConfig<>(); reference.setApplication(applicationConfig); reference.setRegistry(registryConfig); reference.setInterface(DemoService.class); // Access to services DemoService service = reference.get(); // Service invocation String message = service.sayHello("dubbo !"); System.out.println(message); } }
1.2 XML-based configuration
Above we introduced the configuration of Dubbo using API, which is convenient to integrate other systems, but the implementation is tedious. So the government provides Spring's XML-based configuration, which relies on Spring to create services by loading beans. Official Documents: http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html
1.2.1 Project preparation
First create a module called dubbo-demo-xml, and then create three sub-modules under that module
dubbo-demo-xml/ ├── dubbo-demo-xml-api ├── dubbo-demo-xml-consumer ├── dubbo-demo-xml-provider └── pom.xml
- dubbo-demo-xml-api: Provide demo interface
- dubbo-demo-xml-consumer: service consumers
- dubbo-demo-xml-provider: service provider
1.2.2 dubbo-demo-xml-api module
Same as dubbo-demo-api-api.
1.2.3 dubbo-demo-xml-provider module
Ibid. introduce api and dubbo dependencies.
1.2.3.1 DemoServiceImpl
Implement the defined api interface.
package learn.demo.dubbo.xml.provider; import learn.demo.dubbo.xml.api.DemoService; /** * Created by shirukai on 2019-06-20 10:19 * Experimental DemoService Interface */ public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "This service base in XML.\nHello " + name; } }
1.2.3.2 dubbo-provider.xml
Create dubbo-provider.xml configuration file under resource/spring to configure the provider service of dubbo. Specific parameters refer to the official website.
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- provider's application name, used for tracing dependency relationship --> <dubbo:application name="demo-xml-provider"> <!-- Appoint qos Port, configuration priority is lower than dubbo.properties--> <dubbo:parameter key="qos.port" value="22222"/> </dubbo:application> <!-- Radio-based Registration Center --> <dubbo:registry address="multicast://224.5.6.7:1234"/> <!-- use dubbo protocol to export service on port 20880 --> <dubbo:protocol name="dubbo"/> <!-- service implementation, as same as regular local bean --> <bean id="demoService" class="learn.demo.dubbo.xml.provider.DemoServiceImpl"/> <!-- declare the service interface to be exported --> <dubbo:service interface="learn.demo.dubbo.xml.api.DemoService" ref="demoService"/> </beans>
1.2.3.3 DemoServiceProvider
Provider implementation is relatively simple, using ClassPath Xml Application Context to get the application context from xml, and then start.
package learn.demo.dubbo.xml.provider; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by shirukai on 2019-06-20 10:18 * Doubbo Service Provider Based on XML */ public class DemoServiceProvider { public static void main(String[] args) throws Exception { // Getting the application context from the XML configuration file ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml"); context.start(); System.in.read(); } }
1.2.4 dubbo-demo-xml-consumer module
Similarly, api and dubbo dependencies need to be introduced into pom.
1.2.4.1 dubbo-consumer.xml
Use XML to configure consumer services. Create dubbo-consumer.xml under resource/spring, as follows
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="demo-xml-consumer"/> <!-- Use of the Broadcasting Registry --> <dubbo:registry address="multicast://224.5.6.7:1234"/> <!-- generate proxy for the remote service, then demoService can be used in the same way as the local regular interface --> <dubbo:reference id="demoService" check="false" interface="learn.demo.dubbo.xml.api.DemoService"/> </beans>
1.2.4.2 DemoServiceConsumer
Use ClassPathXml Application Context to get the application context, and get the corresponding Bean of DemoService interface in the context, then call the interface method.
package learn.demo.dubbo.xml.consumer; import learn.demo.dubbo.xml.api.DemoService; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by shirukai on 2019-06-20 11:07 * Consumption of Dubbo Services Based on XML */ public class DemoServiceConsumer { public static void main(String[] args){ ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml"); context.start(); DemoService demoService = context.getBean("demoService", DemoService.class); String message = demoService.sayHello("world"); System.out.println(message); } }
1.2.4.3 Supplement, About dubbo Configuration
Dubbo configuration, we can configure through the dubbo.properties file, if I want to modify the qos port, you can only create dubbo.properties file, and then add the following configuration:
# dubbo related configuration file dubbo.application.qos.port=22223
1.3 Annotation-based Configuration
Official website: http://dubbo.apache.org/zh-cn/docs/user/configuration/annotation.html
dubbo's configuration of annotations is the same as xml, except that we don't need to configure xml, add @Service annotations to the interface implementation classes that need to be exposed, and then inject the relevant configuration into Spring through @Configuration.
1.3.1 Project preparation
First create a module called dubbo-demo-xml, and then create three sub-modules under that module
dubbo-demo-annotation/ ├── dubbo-demo-annotation-api ├── dubbo-demo-annotation-consumer ├── dubbo-demo-annotation-provider └── pom.xml
- dubbo-demo-annotation-api: Provide demo interface
- dubbo-demo-annotation-consumer: service consumers
- dubbo-demo-annotation-provider: service provider
1.3.2 dubbo-demo-annotation-api module
Same as dubbo-demo-api-api module.
1.3.3 dubbo-demo-annotation-provider module
1.3.3.1 DemoServiceImpl
Ibid., implement the DemoService interface, but use @Service to mark that the implementation class exposes the service through Provider.
package learn.demo.dubbo.annotation.provider; import lear.demo.dubbo.annotation.api.DemoService; import org.apache.dubbo.config.annotation.Service; /** * Created by shirukai on 2019-06-20 14:04 * DemoService Implementation class */ @Service public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "The service base in Annotation.\nHello" + name; } }
1.3.3.2 dubbo-provider.properties
Dubbo providers are configured by dubbo-provider. properties. Create the dubbo-provider.properties file under resource/spring, as follows
dubbo.application.name=dubbo-demo-annotation-provider dubbo.application.qos.port=22222 dubbo.protocol.name=dubbo dubbo.protocol.port=20880
1.3.3.3 DemoServiceProvider
As with xml configuration, you need to get the application context, just using Annotation Config Application Context, and you need to inject dubbo configuration into Spring through @Configuration, and develop the package path that needs to be scanned, as well as the path where the configuration file is located. The contents are as follows:
package learn.demo.dubbo.annotation.provider; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; /** * Created by shirukai on 2019-06-20 14:06 * DemoService Providers */ public class DemoServiceProvider { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProviderConfiguration.class); context.start(); System.in.read(); } @Configuration @EnableDubbo(scanBasePackages = "learn.demo.dubbo.annotation.provider") @PropertySource("classpath:/spring/dubbo-provider.properties") static class ProviderConfiguration { @Bean public RegistryConfig registryConfig() { RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("multicast://224.5.6.7:1234"); return registryConfig; } } }
1.3.4 dubbo-demo-annotation-consumer module
1.3.4.1 dubbo-consumer.properties
Configure the relevant configuration of Dubbo consumer through dubbo-consumer.properties, such as service name, registry address, etc.
dubbo.application.name=dubbo-demo-annotation-consumer dubbo.registry.address=multicast://224.5.6.7:1234
1.3.4.2 DemoServiceComponent
Create DemoService components through @Component and inject interface instances provided by remote Dubbo through @Reference.
package learn.demo.dubbo.annotation.consumer.comp; import lear.demo.dubbo.annotation.api.DemoService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.stereotype.Component; /** * Created by shirukai on 2019-06-20 14:22 * DemoService assembly */ @Component("demoServiceComponent") public class DemoServiceComponent implements DemoService { @Reference private DemoService demoService; @Override public String sayHello(String name) { return demoService.sayHello(name); } }
1.3.4.3 DemoServiceConsumer
dubbo-related configuration is injected through @Configuration, and application context is obtained through Annotation Config Application Context.
package learn.demo.dubbo.annotation.consumer; import lear.demo.dubbo.annotation.api.DemoService; import learn.demo.dubbo.annotation.consumer.comp.DemoServiceComponent; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; /** * Created by shirukai on 2019-06-20 14:10 * DemoService Consumer */ public class DemoServiceConsumer { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConsumerConfiguration.class); context.start(); DemoService service = context.getBean("demoServiceComponent", DemoServiceComponent.class); String message = service.sayHello("world"); System.out.println(message); } @Configuration @EnableDubbo(scanBasePackages = "learn.demo.dubbo.annotation.consumer.comp") @PropertySource("classpath:/spring/dubbo-consumer.properties") @ComponentScan(value = {"learn.demo.dubbo.annotation.consumer.comp"}) static class ConsumerConfiguration { } }
2 SpringBoot Integration Dubbo
SpringBoot integrates the simplicity of Dubbo with no more simplicity, no additional configuration is required, just a few dependency packages are introduced.
2.1 Project preparation
First create a module called dubbo-demo-spring boot, and then create three sub-modules under that module
dubbo-demo-springboot/ ├── dubbo-demo-springboot-api ├── dubbo-demo-springboot-consumer ├── dubbo-demo-springboot-provider └── pom.xml
- Dubbo-demo-spring boot-api: Provides demo interface
- Dubbo-demo-spring boot-consumer: service consumers
- Dubbo-demo-spring boot-provider: service provider
2.2 dubbo-demo-spring boot-api module
Like previous api modules, the DemoService interface is defined.
2.3 Dubbo-demo-spring boot-provider module
2.3.1 Introducing Dependency
Because this project is a spring boot project, add the spring boot module to parent
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
Introducing spring boot starter
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
Introducing Dubbo spring boot starter
<!-- Dubbo Spring Boot Starter --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.1</version> </dependency>
Introducing dubbo dependencies
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.2</version> </dependency>
Introducing api dependencies
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.2</version> </dependency>
2.3.2 application.properties
Create application.properties configuration file in resource, add dubbo configuration
spring.application.name=dubbo-spring-boot-provider # dubbo dubbo.scan.base-packages=learn.demo.dubbo.springboot.provider dubbo.protocol.name=dubbo dubbo.protocol.port=12345 dubbo.registry.address=multicast://224.5.6.7:1234
2.3.3 DemoServiceImpl
Implement the DemoService interface and mark such service instances exposed by dubbo with the @Service annotation of dubbo
package learn.demo.dubbo.springboot.provider; import learn.demo.dubbo.springboot.api.DemoService; import org.apache.dubbo.config.annotation.Service; /** * Created by shirukai on 2019-06-20 15:08 */ @Service(version = "1.0.0") public class DemoServiceImpl implements DemoService { @Override public String sayHello(String name) { return "The service of dubbo from springboot.\nHello " + name; } }
2.3.4 DemoServiceProvider
Dubbo service provides implementation, mainly starting SpringBoot.
package learn.demo.dubbo.springboot.provider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Created by shirukai on 2019-06-20 15:08 */ @SpringBootApplication public class DemoServiceProvider { public static void main(String[] args) { SpringApplication.run(DemoServiceProvider.class, args); } }
2.4 dubbo-demo-spring boot-consumer module
2.3.1 Introducing Dependency
Like provider, spring boot-starter, dubbo-spring-boot-starter, dubbo, api dependencies are introduced. In addition, a REST interface is provided, so web service-related dependencies need to be introduced.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2.3.2 application.properties
spring.application.name=dubbo-spring-boot-consumer # dubbo dubbo.scan.base-packages=learn.demo.dubbo.springboot.consumer dubbo.registry.address=multicast://224.5.6.7:1234
2.3.4 DemoController
Provide a REST interface and invoke RPC services
package learn.demo.dubbo.springboot.consumer.controller; import learn.demo.dubbo.springboot.api.DemoService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * Created by shirukai on 2019-06-20 16:03 */ @RestController public class DemoController { @Reference(version = "1.0.0") private DemoService demoService; @GetMapping(value = "/sayHello") public String sayHello(@RequestParam("name") String name) { return demoService.sayHello(name); } }
2.3.5 DemoServiceConsumer
The Dubbo Consumser service starts and SpringBoot starts normally.
package learn.demo.dubbo.springboot.consumer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Created by shirukai on 2019-06-20 16:00 */ @SpringBootApplication public class DemoServiceConsumer { public static void main(String[] args) { SpringApplication.run(DemoServiceConsumer.class, args); } }