
实现步骤
创建服务提供者Provider模块
创建服务消费者Consumer模块
在服务提供者模块编写 UserServiceImpl 提供服务
在服务消费者中的 UserController 远程调用UserServiceImpl 提供的服务
分别启动两个服务,测试
1. 传统Srping和SpringMVC整合
大致思路
- 统一包版本 导入spring包
- 编写dubbo-service
- UserService接口
- impl实现接口并加上Service注解
- applciationContext包扫描
编写dubbo-web
UserController
Controller注解
注入UserService
设置RequestMapping
springmvc
web中编写
spring的监听器
前端控制器
contextConfigLocation扫描
Servletmapping
在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> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <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>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>${zookeeper.version}</version> </dependency>
<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> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <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>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>${zookeeper.version}</version> </dependency>
<dependency> <groupId>cn.jyw</groupId> <artifactId>dubbo-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
</dependencies>
<build> <plugins> <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">
<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> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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 {
@Autowired private UserService userService;
@RequestMapping("/sayHello") public String sayHello(){ return userService.sayHello(); }
}
|
dubbo-service是被依赖的所以需要先maven安装一下
2. 改造成Dubbo项目
大致思路
- 统一包版本 导入 spring 包与dubbo包
- 提取接口 dubbo-interface
- pom.xml声明
- UserService接口
编写dubbo-service
编写UserServiceImpl接口 使用dubbo的Service注解对外发布
实现UserService接口
配置applicationContext 使用的dubbo就配置dubbo
web.xml
- spring监听器
- contextConfigLocation
pom.xml依赖公共接口模块
编写Dubbo-web
编写UserController
- Controller 与 RequstMapping注解
- 用Reference远程注入UserService
编写springmvc.xml
配置web.xml
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> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <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>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <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> <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 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">
<dubbo:application name="dubbo-service"/> <dubbo:registry address="zookeeper://192.168.114.130:2181"/> <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">
<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> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <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>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <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> <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 {
@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:application name="dubbo-web" > <dubbo:parameter key="qos.port" value="33333"/> </dubbo:application> <dubbo:registry address="zookeeper://192.168.114.130:2181"/> <dubbo:annotation package="cn.jyw.controller" />
</beans>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <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 序列化

实现序列化接口 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;
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 利用超时机制来解决这个问题,设置一个超时时间,在这个时间段内,无法完成服务访问,则自动断开连接
使用timeout属性配置超时时间,默认值1000,单位毫秒
- 设置了超时时间,在这个时间段内,无法完成服务访问,则自动断开连接
- 如果出现网络抖动,则这一次请求就会失败
- Dubbo 提供重试机制来避免类似问题的发生
- 通过 retries 属性来设置重试次数。默认为 2 次
加上开始的一次一共三次
1 2 3 4
| @Service(timeout = 3000,retries = 2)
@Reference(timeout = 1000)
|
一般建议将timeout配置在服务的提供者Service这里 服务的消费者Reference可以覆盖Service的超时
3.4 多版本

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上选择均衡负载类型

负载均衡策略(4种):
Random :按权重随机,默认值。按权重设置随机概率
随机概率为(权重)/(总权重)
RoundRobin :按权重轮询
每次轮询各个机器所占比例根据权重固定
LeastActive:最少活跃调用数,相同活跃数的随机
根据服务提供者的活跃程度进行调用
ConsistentHash:一致性 Hash,相同参数的请求总是发到同一提供者
根据请求参数的值,利用Hash算法得出要去哪个服务提供者(值相同Hash就相同,就会一直去相同的服务提供者)
3.6 集群容错

@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") private UserService userService;
|