SpringBoot整合Dubbo

339 阅读6分钟

本文已参与【新人创作礼】活动,一起开启掘金创作之路。 ​

目录

1.说明需求

2.工程架构 

3.引入pom文件

注意starter版本适配:

 4.gmall-interface (公共接口层)

1)bean模型

2)service接口

5.gmall-user用户模块(服务方)

1)实现用户查询的方法

2)yml文件

 6.gmall-order-web(消费方)

1)实现生成订单的方法

2)controller层

3)yml文件

7.dubbo注解解释

8.Dubbo配置

1)配置原则

2)重试次数 

3)超时时间

4)版本号

 9.高可用

1)zookeeper宕机与dubbo直连


1.说明需求

某个电商系统,订单服务(消费方)需要调用用户服务(服务方)获取某个用户的所有地址;

我们现在需要创建两个服务模块进行测试

模块功能
订单服务(消费方)生成订单
用户服务(服务方)返回用户地址

测试预期结果:

        订单服务在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。

2.工程架构 

​编辑

服务接口尽可能大粒度,每个服务方法应代表一个功能,而不是某功能的一个步骤,否则将面临分布式事务问题,Dubbo 暂未提供分布式事务支持。 

3.引入pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.atguigu</groupId>
    <artifactId>boot-user-service-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-user-service-provider</name>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.atguigu</groupId>
            <artifactId>gmall-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <!-- 引入dubbo -->
        <!-- Dubbo Spring Boot Starter -->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

注意starter版本适配:

​编辑

 4.gmall-interface (公共接口层)

1)bean模型

@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserAddress implements Serializable {
    private Integer id;
    private String userAddress;
    private String userId;
    private String userName;
    private String phoneNum;
    private String isDefault; //是否默认地址,Y-是  N-否
}

2)service接口

public interface OrderService {
    /**
     * 生成订单
     * @param userId
     * @return
     */
    public UserAddress initOrder(String userId);
}

public interface UserService {
    /**
     * 按照用户id返回所有的收货地址
     * @param userId
     * @return
     */
    public UserAddress getUserAddressList(String userId);
}

5.gmall-user用户模块(服务方)

1)实现用户查询的方法

@Service //dubbo注解
public class UserServiceImpl implements UserService {
    @Override
    public UserAddress getUserAddressList(String userId) {
        //生成用户信息
        ArrayList<UserAddress> userAddresses = new ArrayList<>();
        UserAddress address1 = new UserAddress(1, "北京", "1","李老师","11111111", "Y");
        UserAddress address2 = new UserAddress(2, "南京", "2", "宋老师","22222222", "N");
        userAddresses.add(address1);
        userAddresses.add(address2);

        //模拟查询
        UserAddress userAddress = userAddresses.get(Integer.parseInt(userId));
        return userAddress;
    }
}

2)yml文件

dubbo:
  application:
    name: user-service-provider
  registry:
    address: 192.168.16.106:2181
    protocol: zookeeper
  protocol:
    name: dubbo
    port: 20880
  scan:
    base-packages: com.atguigu.gmall
  monitor:
    protocol: registry

application.name就是服务名,不能跟别的dubbo提供端重复

registry.protocol 是指定注册中心协议

registry.address 是注册中心的地址加端口号

protocol.name 指定通信规则,使用dubbo协议(有很多协议)

protocal.port:服务暴露在20880端口(默认)

base-package  注解方式要扫描的包

monitor.protocal:所有服务配置连接监控中心,进行监控统计,监控中心协议

如果为protocol="registry",表示从注册中心发现监控中心地址,否则直连监控中心。

Simple Monitor 挂掉不会影响到 Consumer 和 Provider 之间的调用,所以用于生产环境不会有风险。

 6.gmall-order-web(消费方)

1)实现生成订单的方法

@Service //spring注解
public class OrderServiceImpl implements OrderService {
    @Reference //dubbo注解
    UserService userService;

    /**
     * 初始化订单,查询用户所有的地址并返回
     * @param userId
     */
    @Override
    public UserAddress initOrder(String userId) {
        //1.查询用户的收货地址
        UserAddress userAddress = userService.getUserAddress(userId);

        return userAddress;
    }
}

2)controller层

@Controller
public class OrderController {
    @Autowired
    OrderService orderService;

    @ResponseBody
    @RequestMapping("/initOrder")
    public UserAddress initOrder(@RequestParam("uid") String userId){
        return orderService.initOrder(userId);
    }
}

3)yml文件

server:
  port: 8081
dubbo:
  application:
    name: boot-order-service-consumer
  registry:
    address: 192.168.16.106:2181
    protocol: zookeeper
  scan:
    base-packages: com.atguigu.gmall
  monitor:
    protocol: registry

7.dubbo注解解释

@Service:指定需要暴露的服务

@Reference:生成远程服务代理

【如果没有在配置中写dubbo.scan.base-package,还需要使用@EnableDubbo注解】

8.Dubbo配置

说明:以下xml文件均可被注解代替,我这样写只是为了更清楚的解释

1)配置原则

​编辑

JVM 启动 -D 参数优先,这样可以使用户在部署和启动时进行参数重写,比如在启动时需改变协议的端口。

XML 次之,如果在 XML 中有配置,则 dubbo.properties 中的相应配置项无效。

Properties 最后,相当于缺省值,只有 XML 没有配置时,dubbo.properties 的相应配置项才会生效,通常用于共享公共配置,比如应用名。

2)重试次数 

重试次数配置如下:
<dubbo:service retries="2" />
或
<dubbo:reference retries="2" />
或
<dubbo:reference>
    <dubbo:method name="findFoo" retries="2" />
</dubbo:reference>

幂等:对数据库执行多次的效果和一次的效果一样(设置重试次数)【查询】【删除】【修改】效果一样

非幂等:(不能设置重试次数)

3)超时时间

由于网络或服务端不可靠,会导致调用出现一种不确定的中间状态(超时)。为了避免超时导致客户端资源(线程)挂起耗尽,必须设置超时时间。

①Dubbo消费端

全局超时配置
<dubbo:consumer timeout="5000" />

指定接口以及特定方法超时配置
<dubbo:reference interface="com.foo.BarService" timeout="2000">
    <dubbo:method name="sayHello" timeout="3000" />
</dubbo:reference>

②Dubbo服务端

全局超时配置
<dubbo:provider timeout="5000" />

指定接口以及特定方法超时配置
<dubbo:provider interface="com.foo.BarService" timeout="2000">
    <dubbo:method name="sayHello" timeout="3000" />
</dubbo:provider>

配置原则

dubbo推荐在Provider上尽量多配置Consumer端属性

1、作服务的提供者,比服务使用方更清楚服务性能参数,如调用的超时时间,合理的重试次数,等等

2、在Provider配置后,Consumer不配置则会使用Provider的配置值,即Provider配置可以作为Consumer的缺省值。否则,Consumer会使用Consumer端的全局设置,这对于Provider不可控的,并且往往是不合理的

配置的覆盖规则:

  1. 方法级配置别优于接口级别,即小Scope优先

  2. Consumer端配置 优于 Provider配置 优于 全局配置,

  3. 最后是Dubbo Hard Code的配置值(见配置文档)

​编辑

4)版本号

当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用

可以按照以下的步骤进行版本迁移:

  1. 在低压力时间段,先升级一半提供者为新版本
  2. 再将所有消费者升级为新版本
  3. 然后将剩下的一半提供者升级为新版本
老版本服务提供者配置:
<dubbo:service interface="com.foo.BarService" version="1.0.0" />

新版本服务提供者配置:
<dubbo:service interface="com.foo.BarService" version="2.0.0" />

老版本服务消费者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" />

新版本服务消费者配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" />

如果不需要区分版本,可以按照以下的方式配置:
<dubbo:reference id="barService" interface="com.foo.BarService" version="*" />

 9.高可用

1)zookeeper宕机与dubbo直连

现象:zookeeper注册中心宕机,还可以消费dubbo暴露的服务。

健壮性

  1. 监控中心宕掉不影响使用,只是丢失部分采样数据
  2. 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务
  3. 注册中心对等集群,任意一台宕掉后,将自动切换到另一台
  4. 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯
  5. 服务提供者无状态,任意一台宕掉后,不影响使用
  6. 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

高可用:通过设计,减少系统不能提供服务的时间;

//Dubbo直连,绕过注册中心
@Reference(url = "192.168.16.106:20882") 

\