preface
reference material:
<Spring Microservices in Action>
Principles and practice of Spring Cloud Alibaba microservice
"Spring cloud framework development tutorial in Silicon Valley of station B" Zhou Yang
Apache Dubbo is a distributed service framework, which mainly realizes high-performance and transparent calls between multiple systems;
Dubbo related content the author wrote an introductory note before: Dubbo quick start notes - environment and configuration . The introductory notes emphasize some basic features of Dubbo to integrate with Zookeeper. Therefore, we will focus on the connection, difference and integration between Dubbo and Spring Cloud;
1. Dubbo Basics
1.1 what is Dubbo
- Apache Dubbo is a distributed service framework, which mainly realizes high-performance and transparent calls between multiple systems;
- In short, it is an RPC framework, but different from the ordinary RPC framework, it provides service governance functions, such as service registration, monitoring, routing, fault tolerance, etc;
1.2 architecture diagram of Dubbo
1.3 differences between spring cloud and Dubbo
- reference resources: https://segmentfault.com/a/1190000038320266
Comparison item | Dubbo | Spring Cloud |
---|---|---|
communication protocol | Based on TCP protocol transmission, Netty is used to cooperate with Hession serialization to complete RPC communication | Communication of calling remote procedure based on HTTP protocol + REST interface |
Service invocation mode | RPC | REST API |
location | The product of SOA Era | Microservice architecture Era |
Focus | Reuse of services and solving the problem of information island; Service governance | Decoupling to reduce the coupling between services; Microservice governance package |
modular | Service registration center, service provider, service consumer and control center | Distributed one-stop framework |
- HTTP requests will have larger packets and occupy more bandwidth. However, REST is more flexible than RPC. The dependence of service providers and callers only depends on a contract, and there is no strong dependence at the code level, which is more appropriate in the microservice environment emphasizing rapid evolution;
- The specific comparison of module components is as follows:
assembly | Dubbo | Spring Cloud (Netflix) |
---|---|---|
Registration Center | It used to be Zookeeper, but now it promotes Nacos | Spring Cloud Eureka |
Service monitoring | Dubbo-monitor | Spring Boot Admin |
Fuse | 6 fault tolerance modes | Spring Cloud Hystrix |
load balancing | Four load balancing strategies | Spring Cloud Ribbon |
service degradation | Mock mechanism | The @ HystrixCommand annotation for Hystrix |
gateway | nothing | Spring Cloud Zuul |
to configure | nothing | Spring Cloud Config |
Service tracking | nothing | Spring Cloud Sleuth |
data stream | nothing | Spring Cloud Stream |
Batch task | nothing | Spring Cloud Task |
Message bus | nothing | Spring Cloud Bus |
1.4 characteristics of Dubbo
- It supports service publishing of multiple protocols. The default is dubbo: / /. It can also support rest: / /, webservice: / /, thrift: / /, etc;
- Support a variety of different registration centers, such as Nacos, ZooKeeper and Redis, and will also support Consul, Eureka, Etcd, etc. in the future;
- Support a variety of serialization technologies, such as avro, fst, fastjson, hessian2, kryo, etc;
- It has perfect functions in service governance, such as cluster fault tolerance, service routing, load balancing, service degradation, service flow limitation, service monitoring, security verification, etc;
- Chinese documents;
1.5 Dubbo's six fault-tolerant modes
Fault tolerant mode | Mode name | explain | Applicable scenario |
---|---|---|---|
Failover Cluster | [default] fail to switch automatically | When the service call fails, it will switch to other machines in the cluster for retry. The default number of retries is 2. The number of retries can be modified through the attribute retries=2 | It is usually used for read operation (query), because transactional operation will cause data duplication |
Failfast Cluster | Rapid failure | When the service call fails, an error is reported immediately, that is, only one call is initiated | It is usually used for some idempotent write operations (addition, deletion and modification), such as adding data; To avoid the problem of repeated data insertion in the case of uncertain results |
Failsafe Cluster | Fail safe | When an exception occurs, the exception is ignored directly | Use Failover Cluster(retries = "0") to handle (add, delete, modify) operations |
Failback Cluster | Automatic reply after failure | When an exception occurs in the service call, record the failed request in the background and resend it regularly | It is suitable for message notification operation to ensure that the request will be sent successfully |
Forking Cluster | Parallel submission | Call multiple services in the cluster in parallel, and return as long as one of them succeeds. You can set the maximum number of parallels by forks=2 | |
Broadcast Cluster | Broadcast notification | Broadcast calls all service providers. If any service reports an error, it means that the service call fails | It is usually used to notify all service providers to update cache or local resource information |
-
The fault-tolerant mode can be extended by itself;
-
The configuration is also very simple. Just add a cluster parameter in the @ Service interface;
@Service(cluster = "failfast") //Change the fault tolerance mode to fast failure public class TestServiceImpl implements TestService { @Override public String test() { ... } }
1.6 Dubbo's four load balancing strategies
Load balancing strategy | Policy name | explain |
---|---|---|
Random LoadBalance | Random algorithm | You can set a larger weight value for servers with better performance. The larger the weight value, the greater the probability of randomness |
RoundRobin LoadBalance | polling | Set the polling proportion according to the weight after the Convention |
LeastActive LoadBalance | Least active call | Slower nodes will receive fewer requests |
ConsistentHash LoadBalance | Consistency Hash | Requests with the same parameters are always sent to the same service provider |
-
The load balancing policy can be extended based on the SPI mechanism in Dubbo;
-
The configuration is also very simple. Just add a loadbalance parameter in the @ Service interface;
@Service(loadbalance = "roundrobin") //Change the load balancing policy to polling public class TestServiceImpl implements TestService { @Override public String test() { ... } }
1.7 host binding rules
- Host binding refers to the IP address published by Dubbo service. By default, Dubbo will find and bind the host IP address in the following order:
- Find Dubbo in environment variable_ IP_ TO_ The IP address configured by the bind attribute;
- Find Dubbo protocol. The IP address configured by the host attribute is empty by default. If it is not configured or the IP address is illegal, continue to look down;
- Via localhost Gethostaddress obtains the local IP address. If the acquisition fails, continue to look down;
- If the address of the registry is configured, use Socket communication to connect to the address of the registry, and use the for loop through Socket getLocalAddress(). Gethostaddress() scans each network card to obtain the IP address of the network card;
- The IP address obtained is not the address written to the registry. By default, the IP address written to the registry takes precedence over Dubbo in the environment variable_ IP_ TO_ The registry property the configured IP address. If this attribute is not configured, the previously obtained IP address will be selected and written to the registry;
- Problem: using the default host binding rules, the P address obtained may be incorrect;
- Reason: Dubbo's strategy to detect the local IP address is to call localhost first Gethostaddress. The principle of this method is to map the IP address by obtaining the host name of the local machine. If it points to a wrong IP address, the wrong address will be registered on the ZooKeeper node as the address published by the service;
- Solution:
- Configure the correct IP address mapping corresponding to the machine name in / etc/hosts;
- Add Dubbo to the environment variable_ IP_ TO_ Bind or DUBBO_IP_TO_REGISTRY property, Value is the bound host address;
- Through Dubbo Protocolhost sets the host address;
2. Build Dubbo service provider
- Similarly, to use Zookeeper here, you need to download the Zookeeper server first: for details, see another article by the author: Microservice architecture | 3.3 Apache Zookeeper registry;
2.1 building service interface module
-
Dubbo officially recommends that the service interface be marked as a Jar package and released to the warehouse;
-
In this way, the service consumer can rely on the Jar package to complete remote communication through interface call. For service providers, they also need to rely on the Jar package to complete the implementation of the interface;
-
The method is as follows:
-
Create a new spring cloud Dubbo sample API module and add POM XML dependency file;
<!-- Dubbo --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency>
-
Create a new interface under the service package:
public interface TestService { String test(String message); }
-
Execute the mvn install command to install the interface jar package to the local warehouse;
2.2 add POM XML dependency file
<!-- Spring Cloud Core package--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <!-- Dubbo Spring Cloud Starter --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <!-- Sample API Interface declaration--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-dubbo-sample-api</artifactId> </dependency> <!-- Spring Cloud Nacos Service Discovery --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency>
2.3 modify application YML profile
spring: application: name: spring-cloud-dubbo-provider cloud: zookeeper: discovery: register: true #Indicates that the service is to be registered in the registry connect-string: localhost:2181 #zookeeper server location dubbo: protocol: name: dubbo port: 20880
2.4 add comments on the main program class
- @DubboComponentScan: scan all annotations under the package where the main program class is located and its sub packages, and register the class under @ Servicr annotation into the container;
2.5 implement the interface defined in 2.1
@Service public class TestServiceImpl implements TestService { @Value("${dubbo.application.name}") private String serviceName; @Override public String test(String message) { return serviceName; } }
- You can add two attributes in the @ Service annotation to configure cluster and loadbalance, which are used to configure fault-tolerant mode and load balancing policy respectively;
- For details, see "6 fault tolerance modes of 1.5 Dubbo" and "4 load balancing strategies of 1.6 Dubbo" in this chapter
3. Build Dubbo service consumers
3.1 add POM XML dependency file
- With the service provider;
<!-- Spring Cloud Core package--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> </dependency> <!-- Dubbo Spring Cloud Starter --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <!-- Sample API Interface declaration--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-dubbo-sample-api</artifactId> </dependency> <!-- Spring Cloud Nacos Service Discovery --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> </dependency>
3.2 modify application YML profile
spring: application: name: spring-cloud-dubbo-consumer cloud: zookeeper: discovery: register: false #Indicates that the service should not be registered in the registry connect-string: localhost:2181 dubbo: cloud: subscribed-services: spring-cloud-dubbo-provider #Represents the application name list of the service provider subscribed by the service caller. The default value is "*", which is not recommended
3.3 modify business class
- Use the @ Reference annotation in the service class to inject TestService;
@RestController public class TestController{ @Reference private TestService testService; @GetMapping("/message") public String testController(){ return testService.test("message"); }
4. Use Mock configuration on the consumer side to realize service degradation
- In this example, the service degradation policy will be configured for the TestService interface defined in 2.1;
- The configuration of degradation strategy is based on service consumers;
4.1 implement a service degradation method for the interface
public class MockTestService implements TestService { @Override public String test(String message) { return "Currently inaccessible"; } }
4.2 add mock parameter to @ Reference annotation
@RestController public class TestController{ @Reference(mock = "com.dlhjw.springcloud.mock.MockTestService", cluster="failfast") private TestService testService; @GetMapping("/message") public String testController(){ return testService.test("message"); }
- Modify the @ Reference annotation in the TestController class and add the mock parameter;
- The attribute cluster="failfast" is set, because the default fault tolerance policy will initiate two retries, and the waiting time is long;
5. Dubbo uses Zookeeper as the registration center (Spring Boot)
- Only the automatic configuration of Spring Boot is used here;
- There are two configuration methods, one is to use xml, the other is using yml;
- For details on the configuration of. xml, see another article by the author: Dubbo | Dubbo quick start notes - environment and configuration;
5.1 download Zookeeper server
- For details of downloading Zookeeper server, please refer to another article by the author: Microservice architecture | 3.3 Apache Zookeeper registry;
5.2 introduction of POM XML dependency file
- Service providers and service consumers need to introduce the same dependencies;
<!-- Zookeeper Correlation dependency --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.5.3-beta</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.1</version> </dependency> <!-- Dubbo Correlation dependency --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.5</version> </dependency> <!-- Spring Boot rely on --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
5.3 service providers
5.3.1 modify application YML profile
spring: application: name: springboot-dubbo-demo dubbo: #Service provider information application: name: springboot-provider protocol: name: dubbo port: 20880 registry: address: zookeeper://Localhost: 2181 #zookeeper address #scan: #base-packages: com.dlhjw.dubbo.service.impl #Specify the scanning benchmark package of Dubbo service implementation class, which is equivalent to @ DubboComponentScan on the main program class
5.3.2 add notes on the main program class
- @DubboComponentScan: the function is the same as @ ComponentScan of Spring Boot, but the @ Service annotation provided by Dubbo should be scanned here;
- @DubboComponentScan(basePackages = "com.dlhjw.dubbo.service.impl")
- If the above application has been configured, there is no need to add it here;
5.3.3 write business class
- Create an interface and its implementation class:
public interface TestService { void testDubbo(); }
@Service(version = "1.0.0",timeout = 3000) public class TestServiceImpl implements TestService{ @Override public void testDubbo() { } }
- Note: @ Service annotation is com alibaba. dubbo. config. annotation. Under Service package;
5.4 service consumers
5.4.1 modify application YML profile
dubbo: #Information of service consumers application: name: springboot-consumer registry: #zookeeper address address: zookeeper://localhost:2181
5.4.2 add notes on the main program class
5.4.3 writing business classes
- Here, you can directly call the TestService provided by the service provider in the controller interface;
@Reference(version = "1.0.0",timeout = 300) private TestService testService;
- @The Reference annotation can obtain a remote proxy object;
6. Dubbo uses Nacos as the registry (Spring Boot)
- Only the automatic configuration of Spring Boot is used here;
- Only examples of service providers are provided here, which are similar to service consumers;
6.1 download Nacos server
- For details of downloading Nacos server, please refer to another article of the author: Microservice architecture | 3.2 Alibaba Nacos registry;
6.2 engineering structure
- Create a new parent project spring cloud Nacos sample, which contains two modules: Nacos sample API and Nacos sample provider;
- Declare the interface in the Nacos sample API;
public interface IHelloService{ String sayHello(String name); }
6.3 introduction of POM XML dependency file
- Add dependent files in Nacos sample provider:
<!-- Interface definition class --> <dependency> <groupId>com.gupaoedu.book.nacos</groupId> <version>1.0-SNAPSHOT</version> <artifactId>nacos-sample-api</artifactId> </dependency> <!-- Nacos of starter assembly --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-discovery-spring-boot-starter</artifactId> <version>0.2.4</version> <exclusions> <exclusion> <groupId>com.alibaba.spring</groupId> <artifactId>spring-context-support</artifactId> </exclusion> </exclusions> </dependency> <!-- Dubbo of starter assembly --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.7.5</version> </dependency>
6.4 modify application YML profile
dubbo: application: name: spring-boot-dubbo-nacos-sample registry: address: nacos://127.0.0.1:8848 # based on Nacos protocol protocol: name: dubbo port: 20880
6.5 add comments on the main program class
- @DubboComponentScan: the package scanning annotation of dubbo;
6.6 write business class
- Implement the interface defined in 6.2;
@Service public class HelloServiceImpl implements IHelloService{ @Override public String sayHello(String name){ return "He1lo World:"+name; } }
6.7 start up test
- Start the service, access the Nacos console, enter "service management" - > "service list", and you can see all services registered on Nacos;
7. Dubbo uses Nacos as the registry (Spring Cloud)
- Only examples of service providers are provided here, similar to service consumers;
7.1 download Nacos server
- For details of downloading the Nacos server, see another article by the author: Microservice architecture | 3.2 Alibaba Nacos registry;
7.2 engineering structure
- Create a new parent project, spring cloud Nacos sample, which contains two modules: spring cloud Nacos sample API and spring cloud Nacos sample provider;
- Declare the interface in the Nacos sample API;
public interface IHelloService{ String sayHello(String name); }
7.3 add POM XML dependency
- Display the specified version of the declaration dependency in the parent project;
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.11.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.1.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>
- Add dependent files in spring cloud Nacos sample provider:
<!-- Spring Cloud Core package --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </exclusion> </exclusions> </dependency> <!-- Spring Cloud of Dubbo rely on --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> </dependency> <!-- api modular --> <dependency> <groupId>com.gupaoedu.book.springcloud</groupId> <artifactId>spring-cloud-dubbo-sample-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- be based on Nacos Service registration and discovery --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> <version>2.1.1.RELEASE</version> </dependency>
7.4 add application YML dependency file
- The main difference between this integration method and Spring Boot is POM XML configuration file and application YML dependent files;
spring: application: name: spring-cloud-nacos-sample cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #Nacos service registry address dubbo: scan: base-packages: com.gupaoedu.book.nacos.bootstrap #The function is equivalent to @ DubboComponentScan protocol: name: dubbo port: 20880 registry: address: spring-cloud://localhost # mounts the service to the Spring Cloud registry
7.5 no additional comments are required on the main program class
7.6 writing business
- Implement the interface defined in 7.2;
@Service public class HelloServiceImpl implements IHelloService{ @Override public String sayHello(String name){ return "He1lo World:"+name; } }