Dubbo和SpringBoot
建议大家看看官方文档
springboot对应dubbo版本关系
springboot整合Dubbo
灰度发布:指的是新功能发布,部分用户尝试使用,一部分用户继续使用旧的功能,尝试稳定后,慢慢恢复!
服务提供者
pom.xml引入dubbo,由于我使用的是springboot2.1,所以 dubbo必须使用0.2.01
2
3
4
5<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
代替原先的provider.xml,同样的配置写在application.yml中
之前我们对外暴露接口是xml配置,由于以后对外暴露接口太多,
为了方便我们使用@Service
(import com.alibaba.dubbo.config.annotation.Service);1
2
3
4
5
6
7
8
9
10
11dubbo:
application:
name: boot-service-provider
registry:
address: zookeeper:127.0.0.1:2181
protocol:
name: dubbo
port: 20880 # 通信规则
# 连接监控中心
monitor:
protocol: register
然后启动时,千万别忘了开启dubbo注解配置1
2
3
4
5
6
7
8
9
10
11
12
13import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 开启注解的dubbo功能
public class BootServiceProvider {
public static void main(String[] args) {
SpringApplication.run(BootServiceProvider.class,args);
}
}
服务消费者
pom.xml和服务提供者的相同
然后使用application.yml替代原先的consumer.xml配置
以前我们使用@Autowired,现在我们使用@Reference加载接口1
2
3
4
5
6
7
8dubbo:
application:
name: boot-service-consumer
registry:
address: 127.0.0.1
protocol: zookeeper
monitor:
protocol: register
然后启动时,千万别忘了开启dubbo注解配置1
2
3
4
5
6
7
8
9
10
11
12import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
public class BootServiceConsumer {
public static void main(String[] args) {
SpringApplication.run(BootServiceConsumer.class,args);
}
}
然后运行成功!
Dubbo属性配置加载顺序
规则:(方法级优先,接口级次之,全局配置再次之,如果级别一样,消费方优先,提供方次之)
官网告诉我们有三种可以dubbo属性配置的方法,它们互补,优先级顺序为:
Dubbo启动时检查
很多时候,注册中心没有对应的服务的时候,消费者就已经启动了,往往会报错,原因:dubbo默认启动时检查
我们可以在yml关闭启动时检查()1
2
3dubbo:
reference:
check: false
关闭所有服务的不检查1
2
3dubbo:
consumer:
check: false
在启动的时候,如果没有注册中心,会报错,但是我们可以关闭1
2
3dubbo:
registry:
check: false
消费者全局配置(dubbo.provider)
1 | dubbo: |
timeout retries
它们两个配合使用,timeout1
2
3
4dubbo:
consumer:
timeout: 1000 # 单位毫秒,默认是1000 访问大于1秒就会报错
retries: 3 # 第一次尝试失败不算,总共尝试三次
dubbo多版本
就是我们上面提到的灰度发布,我们使用 version版本来控制版本1
2
3dubbo:
provider:
version: 0.0.2
我们在消费者使用时使用*
的方式,会随机切换
本地存根
客户端一般只有接口,具体的实现都在服务器端,但是有时候我们想要做参数的提前校验,以及做缓存之类的
这个时候我们只需要在客户端创建类实现远程调用接口,然后里面必须有一个构造函数1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25import com.itcast.gmall.bean.UserAddress;
import com.itcast.gmall.service.UserService;
import org.springframework.util.StringUtils;
import java.util.List;
public class UserServiceStub implements UserService {
private final UserService userService;
public UserServiceStub(UserService userService) {
this.userService = userService;
}
// 构造函数传入真正的远程代理对象
public List<UserAddress> getUserAddressList(String userId) {
//如果参数不为空就返回
if(!StringUtils.isEmpty(userId)){
List<UserAddress> userAddressList = userService.getUserAddressList(userId);
return userAddressList;
}
return null;
}
}
然后我们需要在消费者端使用stub来设置1
<dubbo:reference interface="com.itcast.gmall.service.UserService" id="userService" stub="gmall.service.impl.UserServiceStub"></dubbo:reference>
只有当我们的stub验证通过后,才会执行服务器端的代码(在开发中,我们通常把存根放在接口工程中)
Dubbo和SpringBoot整合的三种方式
- 使用dubbo自动扫描 @Reference(引入服务),@Service(暴露服务),记得使用@EnableDubbo
- 使用xml配置,那么我们使用@ImportResource配置xml文件,不需要使用@EnableDubbo
- 我们使用XXXConfig注册组件的方式,例如
<dubbo:application></dubbo:application>
,记得使用@EnableDubbo
1 | import com.alibaba.dubbo.config.ApplicationConfig; |
高可用
Zookeeper宕机之后是消费者仍可以继续调用生产者的服务,因为他们仍能通过本地缓存通讯
我们也可以使用@Reference(url=””)实现dubbo直连
Dubbo的负载均衡
Random LoadBalance 基于权重的随机负载均衡机制 dubbo默认负载均衡机制
RoundRobin LoadBalance 基于权重的轮询负载均衡机制
LeastActive LoadBalance 基于最小活跃数负载均衡机制
我们自定义负载均衡机制1
2"roundrobin") (loadbalance =
UserService userService;
服务降级
我们可以在duubo控制台操作服务的屏蔽或者容错
屏蔽:指的是消费者不向生产者发送请求,直接返回空
容错:指的是消费者生产者发送请求失败后不报错,然后返回空
Dubbo容错机制
dubbo默认的容错机制会切换另一台服务器,当然我们也可以借助springcloud的Hystrix来实现自定义容错机制
- 首先在服务提供者端引入依赖
1
2
3
4
5<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
然后在方法上使用@HystrixCommand注解
千万记住开启Hystrix注解模式,在启动类上加上 @EnableHystrix
- 同样的在消费端,我们也要引入相应的依赖,然后在调用方法上使用@HystrixCommand注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16"errorMethod") (fallbackMethod =
public List<UserAddress> initOrder(String userId) {
// TODO Auto-generated method stub
System.out.println("用户id:"+userId);
//1、查询用户的收货地址
List<UserAddress> addressList = userService.getUserAddressList(userId);
for (UserAddress userAddress : addressList) {
System.out.println(userAddress.getUserAddress());
}
return addressList;
}
public List<UserAddress> errorMethod(String userId) {
return Arrays.asList(new UserAddress(1,"出错","出错","出错","出错","出错"));
}
然后我们需要在启动类上添加 @EnableHystrix