茂展的分享博客

Dubbo和SpringBoot

Dubbo和SpringBoot

建议大家看看官方文档
springboot对应dubbo版本关系
springboot与dubbo版本关系

springboot整合Dubbo

灰度发布:指的是新功能发布,部分用户尝试使用,一部分用户继续使用旧的功能,尝试稳定后,慢慢恢复!

服务提供者

pom.xml引入dubbo,由于我使用的是springboot2.1,所以 dubbo必须使用0.2.0

1
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
11
dubbo:
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
13
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubbo // 开启注解的dubbo功能
@SpringBootApplication
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
8
dubbo:
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
12
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@EnableDubbo
@SpringBootApplication
public class BootServiceConsumer {

public static void main(String[] args) {
SpringApplication.run(BootServiceConsumer.class,args);
}
}

然后运行成功!

Dubbo属性配置加载顺序

规则:(方法级优先,接口级次之,全局配置再次之,如果级别一样,消费方优先,提供方次之)
官网告诉我们有三种可以dubbo属性配置的方法,它们互补,优先级顺序为:
dubbo属性配置加载顺序

Dubbo启动时检查

很多时候,注册中心没有对应的服务的时候,消费者就已经启动了,往往会报错,原因:dubbo默认启动时检查
我们可以在yml关闭启动时检查()

1
2
3
dubbo:
reference:
check: false

关闭所有服务的不检查

1
2
3
dubbo:
consumer:
check: false

在启动的时候,如果没有注册中心,会报错,但是我们可以关闭

1
2
3
dubbo:
registry:
check: false

消费者全局配置(dubbo.provider)

1
2
3
dubbo:
provider:
timeout: 2000 # 单位秒

timeout retries

它们两个配合使用,timeout

1
2
3
4
dubbo:
consumer:
timeout: 1000 # 单位毫秒,默认是1000 访问大于1秒就会报错
retries: 3 # 第一次尝试失败不算,总共尝试三次

dubbo多版本

就是我们上面提到的灰度发布,我们使用 version版本来控制版本

1
2
3
dubbo:
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
25
import 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
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.alibaba.dubbo.config.ApplicationConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {

@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("boot-service-consumer");
return applicationConfig;
}
}

高可用

Zookeeper宕机之后是消费者仍可以继续调用生产者的服务,因为他们仍能通过本地缓存通讯
我们也可以使用@Reference(url=””)实现dubbo直连

Dubbo的负载均衡

Random LoadBalance 基于权重的随机负载均衡机制 dubbo默认负载均衡机制
RoundRobin LoadBalance 基于权重的轮询负载均衡机制
LeastActive LoadBalance 基于最小活跃数负载均衡机制

我们自定义负载均衡机制

1
2
@Reference(loadbalance = "roundrobin")
UserService userService;

服务降级

我们可以在duubo控制台操作服务的屏蔽或者容错
屏蔽:指的是消费者不向生产者发送请求,直接返回空
容错:指的是消费者生产者发送请求失败后不报错,然后返回空
dubbo服务降级操作

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
    @HystrixCommand(fallbackMethod = "errorMethod")
    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

dubbo底层原理我建议阅读官方文档

------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶