Dubbo原理运行图

实现步骤

  1. 创建服务提供者Provider模块

  2. 创建服务消费者Consumer模块

  3. 在服务提供者模块编写 UserServiceImpl 提供服务

  4. 在服务消费者中的 UserController 远程调用UserServiceImpl 提供的服务

  5. 分别启动两个服务,测试

1. 传统Srping和SpringMVC整合

大致思路

  1. 统一包版本 导入spring包
  1. 编写dubbo-service
    1. UserService接口
    2. impl实现接口并加上Service注解
    3. applciationContext包扫描
  1. 编写dubbo-web

    1. UserController

      • Controller注解

      • 注入UserService

      • 设置RequestMapping

    2. springmvc

      • 注解驱动
      • 包扫描
    3. web中编写

      • spring的监听器

      • 前端控制器

      • contextConfigLocation扫描

      • Servletmapping

    4. 在web pom.xml中加入service的依赖

1.1 dubbo-service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>
</properties>

<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>



<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>



<!--依赖service模块-->
<dependency>
<groupId>cn.jyw</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

</dependencies>
1
2
3
4
5
6
7
package cn.jyw.service;

public interface UserService {


public String sayHello();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
package cn.jyw.service.impl;

import cn.jyw.service.UserService;
import org.springframework.stereotype.Service;


@Service
public class UserServiceImpl implements UserService {

public String sayHello() {
return "hello dubbo!~";
}
}
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--注解包扫描-->
<context:component-scan base-package="cn.jyw.service" />

</beans>

1.2 dubbo-web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>
</properties>

<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>



<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>



<!--依赖service模块-->
<dependency>
<groupId>cn.jyw</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

</dependencies>


<build>
<plugins>
<!--tomcat插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8000</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">


<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Springmvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>


</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--注解驱动-->
<mvc:annotation-driven/>
<!--包扫描-->
<context:component-scan base-package="cn.jyw.controller"/>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@RequestMapping("/user")
public class UserController {

//注入Service
@Autowired
private UserService userService;


@RequestMapping("/sayHello")
public String sayHello(){
return userService.sayHello();
}

}

dubbo-service是被依赖的所以需要先maven安装一下

2. 改造成Dubbo项目

大致思路

  1. 统一包版本 导入 spring 包与dubbo包
  1. 提取接口 dubbo-interface
    1. pom.xml声明
    2. UserService接口
  1. 编写dubbo-service

    1. 编写UserServiceImpl接口 使用dubbo的Service注解对外发布

    2. 实现UserService接口

    3. 配置applicationContext 使用的dubbo就配置dubbo

      • 项目名称

      • 注册中心地址

      • 包扫描

    4. web.xml

      • spring监听器
      • contextConfigLocation
    5. pom.xml依赖公共接口模块

  1. 编写Dubbo-web

    1. 编写UserController

      • Controller 与 RequstMapping注解
      • 用Reference远程注入UserService
  2. 编写springmvc.xml

    • 注解驱动
      • 包扫描
      • 配置dubbo
    1. 配置web.xml

      • 加载前端控制器
    • contextConfigLocation
      • servletmapping
  3. pom.xml依赖公共接口模块

2.1 提取接口 dubbo-interface

1
2
3
<groupId>cn.jyw</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
1
2
3
4
public interface UserService {

public String sayHello();
}

2.2 服务提供者Dubbo-service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>

</properties>

<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>



<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>


<!--依赖公共的接口模块-->
<dependency>
<groupId>cn.jyw</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

</dependencies>




<build>
<plugins>
<!--tomcat插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>9000</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
1
2
3
4
5
6
7
8
9
//@Service//将该类的对象创建出来,放到Spring的IOC容器中  bean定义
//从spring包下的service 换成 dubbo包下的service
@Service//将这个类提供的方法(服务)对外发布。将访问的地址 ip,端口,路径注册到注册中心中
public class UserServiceImpl implements UserService {

public String sayHello() {
return "hello dubbo hello!~";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


<!--<context:component-scan base-package="cn.jyw.service" />-->

<!--dubbo的配置-->
<!--1.配置项目的名称,唯一-->
<dubbo:application name="dubbo-service"/>
<!--2.配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.114.130:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="cn.jyw.service.impl" />

</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">


<!-- spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring/applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


</web-app>

2.3 服务消费者Dubbo-web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<dubbo.version>2.7.4.1</dubbo.version>
<zookeeper.version>4.0.0</zookeeper.version>

</properties>

<dependencies>
<!-- servlet3.0规范的坐标 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--spring的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--springmvc的坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>



<!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${zookeeper.version}</version>
</dependency>
<!--ZooKeeper客户端实现 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${zookeeper.version}</version>
</dependency>

<!--依赖公共的接口模块-->
<dependency>
<groupId>cn.jyw</groupId>
<artifactId>dubbo-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>


<!--依赖service模块-->
<!-- <dependency>
<groupId>cn.jyw</groupId>
<artifactId>dubbo-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>-->

</dependencies>


<build>
<plugins>
<!--tomcat插件-->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>8000</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@RestController
@RequestMapping("/user")
public class UserController {

//注入Service
//@Autowired//本地注入

/*
1. 从zookeeper注册中心获取userService的访问url
2. 进行远程调用RPC
3. 将结果封装为一个代理对象。给变量赋值

*/

@Reference//远程注入
private UserService userService;


@RequestMapping("/sayHello")
public String sayHello(){
return userService.sayHello();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">



<mvc:annotation-driven/>
<context:component-scan base-package="cn.jyw.controller"/>


<!--dubbo的配置-->
<!--1.配置项目的名称,唯一-->
<dubbo:application name="dubbo-web" >
<!--同一台机器上端口占用 不过不影响-->
<dubbo:parameter key="qos.port" value="33333"/>
</dubbo:application>
<!--2.配置注册中心的地址-->
<dubbo:registry address="zookeeper://192.168.114.130:2181"/>
<!--3.配置dubbo包扫描-->
<dubbo:annotation package="cn.jyw.controller" />



</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- Springmvc -->   
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

将提供者和消费的结构提取出来,改动只用改动公共接口即可

3. Dubbo高级特性

3.1 序列化

Dubbo序列化

​ 实现序列化接口 implements Serializable

  • dubbo 内部已经将序列化和反序列化的过程内部封装了
  • 我们只需要在定义pojo类时**实现Serializable接口**即可
  • 一般会定义一个公共的pojo模块,让生产者和消费者都依赖该模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package cn.jyw.pojo;

import java.io.Serializable;

/**
* 注意!!!
* 将来所有的pojo类都需要实现Serializable接口
*/
public class User implements Serializable {
private int id;
private String username;
private String password;

public User() {
}

public User(int id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

3.2 地址缓存

注册中心挂了,服务是否可以正常访问?

  • 可以,因为dubbo服务消费者在第一次调用时,会将服务提供方地址缓存到本地,以后在调用则不会访问注册中心
  • 当服务提供者地址发生变化时,注册中心会通知服务消费者
  • 如果服务提供者的地址发生变化,而注册中心又没有反应就会无法正常访问

3.3 超时与重试

Dubbo的超时与重试

基本流程

  1. 用户来访问服务消费者
  2. 服务消费者创建线程单独访问服务提供者调用服务
  3. 服务提供者处理好数据返回结果给服务消费者
  4. 服务消费者封装结果给用户

特殊情况

  • 服务消费者在调用服务提供者的时候发生了阻塞、等待的情形,这个时候,服务消费者会一直等待下去
  • 在某个峰值时刻,大量的请求都在同时请求服务消费者,会造成线程的大量堆积,势必会造成雪崩

dubbo 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接
使用timeout属性配置超时时间,默认值1000,单位毫秒

  • 设置了超时时间,在这个时间段内,无法完成服务访问,则自动断开连接
  • 如果出现网络抖动,则这一次请求就会失败
  • Dubbo 提供重试机制来避免类似问题的发生
  • 通过 retries 属性来设置重试次数。默认为 2 次加上开始的一次一共三次
1
2
3
4
//服务的提供者的Service注解
@Service(timeout = 3000,retries = 2)//当前服务3秒超时,重试2次,一共3次
//服务的消费者的Reference注解
@Reference(timeout = 1000)//远程注入

一般建议将timeout配置在服务的提供者Service这里 服务的消费者Reference可以覆盖Service的超时

3.4 多版本

Dubbo多版本

  • 灰度发布当出现新功能时,会让一部分用户先使用新功能,用户反馈没问题时,再将所有用户迁移到新功能

  • dubbo 中使用version 属性来设置和调用同一个接口的不同版本

1
2
@Reference(version = "v2.0")//远程注入 选择版本
private UserService userService;
1
2
@Service(version = "v1.0")
public class UserServiceImpl implements UserService
1
2
@Service(version = "v2.0")
public class UserServiceImpl2 implements UserService

3.5 负载均衡

@Service(weight = 100)

在服务提供者的@Service上选择权重默认100

@Reference(loadbalance = “random”)//远程注入

在服务消费者的@Reference上选择均衡负载类型

Dubbo负载均衡

负载均衡策略(4种):

  • Random :按权重随机,默认值。按权重设置随机概率

    随机概率为(权重)/(总权重)

  • RoundRobin :按权重轮询

    每次轮询各个机器所占比例根据权重固定

  • LeastActive:最少活跃调用数,相同活跃数的随机

    根据服务提供者的活跃程度进行调用

  • ConsistentHash:一致性 Hash,相同参数的请求总是发到同一提供者

    根据请求参数的值,利用Hash算法得出要去哪个服务提供者(值相同Hash就相同,就会一直去相同的服务提供者)

3.6 集群容错

Dubbo集群容错

@Refernece(cluster = “failove”) //默认重试

集群容错模式:

  • Failover Cluster:失败重试。默认值。当出现失败,重试其它服务器 ,默认重试2次,使用 retries 配置
    一般用于读操作
  • Failfast Cluster :快速失败,只发起一次调用,失败立即报错
    通常用于写操作。
  • Failsafe Cluster :失败安全,出现异常时,直接忽略,返回一个空结果
  • Failback Cluster :失败自动恢复,后台记录失败请求,定时重发
    通常用于消息通知操作。
  • Forking Cluster :并行调用多个服务器,只要一个成功即返回(比较耗性能)
  • Broadcast Cluster :广播调用所有提供者,逐个调用,任意一台报错则报错

3.7 服务降级

服务降级方式:

  • mock= force:return null表示消费方对该服务的方法调用都直接返回null值,不发起远程调用
    用来屏蔽不重要服务不可用时对调用方的影响

  • mock=fail:return null表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常
    用来容忍不重要服务不稳定时对调用方的影响

1
2
@Reference(mock = "fail:return null")//不在调用userservice的服务
private UserService userService;