dubbo distributed service framework (advanced features)

content

1. Serialization

2. Address cache

3. Timeout

4. Retry

5. Multiple versions

6. Load Balancing

7. Cluster fault tolerance

8. Service downgrade


This article refers to the dark horse programmer dubbo introductory course of station b

Video link: Quick introduction to Dubbo, a dark horse programmer, a must-have dubbo tutorial for Java distributed frameworks


1. Serialization

Serialization is to convert Java objects into stream data, and stream data can be transmitted between two hosts

Dubbo has already encapsulated serialization and deserialization. We only need to make the entity class implement the Serializable interface.

The article is based on my other blog dubbo entry

Getting Started with Dubbo Distributed Service Framework - Xue Yueqing's Blog - CSDN Blog

1. Create a new module as dubbo-pojo and create a User class (do not implement the Serializable interface first)

 public class User {
     private int id;
     private  String name;
     private  String password;
 ​
     public User() {
     }
 ​
     public User(int id, String name, String password) {
         this.id = id;
         this.name = name;
         this.password = password;
     }
 ​
     public int getId() {
         return id;
     }
 ​
     public void setId(int id) {
         this.id = id;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     public String getPassword() {
         return password;
     }
 ​
     public void setPassword(String password) {
         this.password = password;
     }
 }

2. Associate dubbo-pojo in dubbo-interface, because we write an interface to test user in the interface module

 <dependencies>
     <dependency>
         <groupId>com.xue</groupId>
         <artifactId>dubbo-pojo</artifactId>
         <version>1.0-SNAPSHOT</version>
     </dependency>
 </dependencies>

Add a new method to the UserService interface

 /**
  * 查询用户接口
  * @return
  */
 public User findUserById(int id);

3. Implement this method in the dubbo-service module and simply return a test user object

   @Override
     public User findUserById(int id) {
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
         return users[id-1];
     }

4. Added find method in UserController under dubbo-web module

 @RequestMapping("/find")
 public User find(int id) {
     return userService.findUserById(id);
 }

Then do tomcat7:run for testing

Then the test found an error

console error message

 java.lang.IllegalStateException: Serialized class com.xue.pojo.User must implement java.io.Serializable

Need to implement Serializable interface

 public class User implements Serializable

Restart

Successful visit!

2. Address cache

Interview question: The registration center is down, can the service be accessed normally?

Yes, because the dubbo service consumer will cache the service provider address locally when it is called for the first time, and will not access the registry in subsequent calls.

When the service provider address changes, the registry notifies the service consumer

Stop the zookeeper service registry

The visit was successful!

3. Timeout

Problem Description:

The service consumer blocks and waits when calling the service provider. At this time, the service consumer will

Just wait. At a certain peak moment, a large number of requests are requesting service consumers at the same time, which will cause a large number of heaps of threads

Accumulation, is bound to cause an avalanche .

Dubbo uses a timeout mechanism to solve this problem, and sets a timeout period. During this time period, the service cannot be completed.

access, the connection is automatically disconnected.

Use the timeout property to configure the timeout period , the default value is 1000, in milliseconds.

1. Configure the timeout period in the dubbo-service module and simulate the timeout

 @Service(timeout = 3000)
 public class UserServiceImpl implements UserService {
     @Override
     public String demo() {
         return "hello,Dubbo";
     }
 ​
     @Override
     public User findUserById(int id) {
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
         //模拟超时
         try {
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         return users[id-1];
     }
 }

2. Access failure, timeout

Attention :

The timeout period can also be configured on the service consumer @Reference, and it will override the timeout period of the service provider. That is to say, @Reference is configured with 1s, and the service provider is configured with 3s before. The final result is that the timeout occurs after 1s.

 @Reference(timeout = 1000) //远程注入
 private UserService userService;

It is recommended to configure the timeout period in the service provider. After all, this service is written by the service provider, and the configuration of the timeout period should be considered when writing.

4. Retry

A timeout period is set. During this period of time, if the service access cannot be completed, the connection will be automatically disconnected. If network jitter occurs (network

If the network is suddenly disconnected and reconnected, the network is unstable), the request will fail this time.

Dubbo provides a retry mechanism to avoid similar problems. Set the number of retries through the retries property, the default is 2 times . (total

issued three times)

 @Service(timeout = 3000,retries = 2) //当前服务3秒超时,重视2次,一共3次
 public class UserServiceImpl implements UserService {
     int i = 1;
     @Override
     public String demo() {
         return "hello,Dubbo";
     }
 ​
     @Override
     public User findUserById(int id) {
         System.out.println("服务被调用"+i++);
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
         //模拟超时
         try {
             Thread.sleep(5000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         return users[id-1];
     }
 }

Timeout retried

5. Multiple versions

Grayscale release:  When new functions appear, some users will be asked to use the new functions first, and all users will be migrated when there is no problem with user feedback.

Move to new features.

All users will be migrated to V2.0 after the V2.0 version is OK

The version attribute is used in dubbo to set and call different versions of the same interface

 @Service(version = "v1.0")
 public class UserServiceImpl implements UserService {
   
     @Override
     public String demo() {
         return "hello,Dubbo";
     }
 ​
     @Override
     public User findUserById(int id) {
         System.out.println("v1.0版本");
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
     
         return users[id-1];
     }
 }

1. Copy the UserServiceImpl class and change it to v2.0

 @Service(version = "v2.0") 
 public class UserServiceImpl2 implements UserService {
     @Override
     public String demo() {
         return "hello,Dubbo";
     }
 ​
     @Override
     public User findUserById(int id) {
         System.out.println("v2.0版本");
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
      
         return users[id-1];
     }
 }

2. First specify access to v1.0 version, start

 @Reference(version = "v1.0") 
 private UserService userService;

console print v1.0 version

3. Specify access to v2.0 version and restart dubbo-web (no need to restart dubbo-service)

 @Reference(version = "v1.0") 
 private UserService userService;

6. Load Balancing

Load balancing strategy:

1. Random : random by weight, default value. Set random probability by weight.

2. RoundRobin: polls by weight.

3. LeastActive: The least number of active calls, the same number of active calls is random.

4. ConsistentHash: Consistent Hash, requests with the same parameters are always sent to the same provider.

Take the default Random as an example

1. Start weight=100 tomcat port 9000 dubbo port 20880 qos port 22222

 @Service(weight = 100)
 public class UserServiceImpl implements UserService {
 ​
     @Override
     public String demo() {
         return "1......";
     }
 }
 <debbo:protocol port="20880"/>
 ​
 <dubbo:application name="dubbo-service">
    <dubbo:parameter key="qos.port" value="22222"/>
 </dubbo:application>

2. Start weight = 200 tomcat port 9001 dubbo port 20882 qos port 44444 and start tomcat7:run again

(Note that it is not restarting the previous one but starting another one)

 @Service(weight = 200)
 public class UserServiceImpl implements UserService {
 ​
     @Override
     public String demo() {
         return "2......";
     }
 ​
 }

 <debbo:protocol port="20882"/>
 <dubbo:application name="dubbo-service">
         <dubbo:parameter key="qos.port" value="44444"/>
     </dubbo:application>

3. Start weight = 100 tomcat port 9002 dubbo port 20883 qos port 55555 and start tomcat7:run again

 @Service(weight = 100)
 public class UserServiceImpl implements UserService {
 ​
     @Override
     public String demo() {
         return "3......";
     }
 }
 <debbo:protocol port="20883"/>
 ​
 <dubbo:application name="dubbo-service">
    <dubbo:parameter key="qos.port" value="55555"/>
 </dubbo:application>

Configure load balancing strategy random

 @Reference(loadbalance = "random" ) 

Start tomcat7:run of the dubbo-web module

(We started four tomcats one by one)

Access appears 2 indicates the second service provider

Continuous refresh appears 3 indicating that it is a third service provider

Continuous refresh appears 1, indicating that it is the first service provider

7. Cluster fault tolerance

Cluster fault tolerance strategy:

1. Failover Cluster: Retry on failure. (default value) When there is a failure, retry other servers, retries 2 times by default, use

retries configuration. Typically used for read operations

2. Failfast Cluster: Fast failure, only one call is made, and an error is reported immediately upon failure. Typically used for write operations.

3. Failsafe Cluster : Failsafe, when an exception occurs, ignore it directly. Returns an empty result.

4. FailbackCluster: Automatically recover from failure, record the failed request in the background, and resend it regularly.

5. Forking Cluster: Call multiple servers in parallel, and return as long as one succeeds. Broadcast Cluster : Broadcast call

All providers are called one by one, if any one reports an error, an error is reported.

Take the Failover Cluster strategy as an example

1. Start tomcat port 9000 dubbo port 20880 qos port 22222

 @Service()
 public class UserServiceImpl implements UserService {
 ​
      @Override
     public User findUserById(int id) {
         System.out.println(1);
         try {
             Thread.sleep(3000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
 ​
         return users[id-1];
     }
 }
 <debbo:protocol port="20880"/>
 ​
 <dubbo:application name="dubbo-service">
    <dubbo:parameter key="qos.port" value="22222"/>
 </dubbo:application>

2. tomcat port 9001 dubbo port 20881 qos port 44444 restart tomcat7:run

 @Service()
 public class UserServiceImpl implements UserService {
 ​
      @Override
     public User findUserById(int id) {
         System.out.println(2);
         try {
             Thread.sleep(3000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
 ​
         return users[id-1];
     }
 }

 <debbo:protocol port="20881"/>
 <dubbo:application name="dubbo-service">
         <dubbo:parameter key="qos.port" value="44444"/>
     </dubbo:application>

3. tomcat port 9002 dubbo port 20882 qos port 55555 restart tomcat7:run

 @Service()
 public class UserServiceImpl implements UserService {
 ​
      @Override
     public User findUserById(int id) {
         System.out.println(3);  
         User[]users = {new User(1,"雪月清","123")
                 ,new User(2,"张三","456")
                 ,new User(3,"李四","156")};
 ​
         return users[id-1];
     }
 }
 <debbo:protocol port="20882"/>
 ​
 <dubbo:application name="dubbo-service">
    <dubbo:parameter key="qos.port" value="55555"/>
 </dubbo:application>

The visit was successful!

But the tomcat log information of the dubbo-web module has a timeout error,

Log information for three service providers

It is found that all three have been accessed, but both 1 and 2 will time out (we simulated the timeout through process sleep), and the consumer will access 1 timeout,

Then according to the Failover Cluster cluster fault tolerance policy, the retry of access 2 also timed out, and the retry of access 3 was successful!

8. Service downgrade

mock=force:return null means that the consumer's method call to the service directly returns a null value, and does not initiate a remote call. use

To shield the impact on callers when unimportant services are unavailable.

1. Configure the service provider

  @Service()
 public class UserServiceImpl implements UserService {
  @Override
 public User findUserById(int id) {
     System.out.println(3);  
     User[]users = {new User(1,"雪月清","123")
             ,new User(2,"张三","456")
             ,new User(3,"李四","156")};
 ​
     return users[id-1];
 } 
 }

2. Configure the service consumer

 @Reference(mock = "force:return null")

3. Start the service provider and service consumer respectively

became a blank page and the service was blocked

mock=fail:return null  means that the consumer will return a null value after the method call to the service fails, and no exception will be thrown. used to

Tolerate the impact on callers when uncritical services are unstable.

Modify the configuration of the service consumer and the rest remain unchanged and restart

 @Reference(mock = "fail:return null")

(Service provider we simulated a timeout) retried three times after failure, but the page does not see any information


It's been a day and a half, and everyone is stunned. I hope everyone can support it! ! !

Guess you like

Origin blog.csdn.net/qq_52595134/article/details/123412187