content
This article refers to the dark horse programmer dubbo introductory course of station b
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! ! !