通用技术 代码学习与实践 (二):Spring Boot 集成 Dubbo

小敏 · 2017年12月24日 · 2966 次阅读

在上一章代码学习与实践 (一):Spring Boot 多模块项目创建与配置中,我们配置了一个 dubbo 项目,包含两个模块 springboot-dubbo-server 和 springboot-dubbo-client,并且在 pom 中都添加了对 dubbo 及 zk 的依赖,在 springboot-dubbo-client 模块的 pom 中还添加了对 springboot-dubbo-server 模块的依赖。

下面我们一起来实践下 dubbo 服务端及客户端的简单设置,以及在 dubbo admin 中查看服务的注册及消费情况。

1 环境搭建

dubbo 环境的搭建可参考文章环境搭建 (一):Dubbo 环境搭建,包括基于 docker 的 zookeeper 安装及 dubbo admin 的安装。

2 dubbo 服务提供方配置

2.1 创建 xml 配置文件

不能直接在 spring boot 默认的配置文件 application.properties 中配置 dubbo 的属性,因为 spring boot 官方没有 dubbo 对应的 starter,所以 spring boot 不能解析 dubbo 的属性。有网友编写了 spring-boot-starter-dubbo,让我们可以使用 spring boot 的方式方便地开发 dubbo 程序,有需要的同学可以去了解一些。

本文实践的目的,是为了学习 dubbo 在 spring boot 中的配置,不是更方便地开发,所以我们这里还是选用原始的 xml 配置文件的方式来进行 dubbo 的配置,然后使用@ImportResource注解来加载 xml 配置。

下面是服务提供方的配置文件 provider.xml。

有两种方式可以暴露 dubbo 服务,一是通过注解方式,二是通过 xml 配置方式,区别就在最后几行配置上。

使用注解方式,在类上打@service注解,就必须要用 dubbo:annotation 指定启动扫描路径。下面的 provider.xml 使用就是这种方式。

使用 xml 配置方式用 dubbo:service 申明要暴露的单个接口,就不需要再指定 dubbo:annotation 了。
provider.xml

<?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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 应用配置,服务提供方和消费方都有-->
    <dubbo:application name="DubboWithSpringBoot-Server"/>

    <!-- 注册中心配置,使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://10.165.124.69:2181" timeout="60000" group="dubbo-test"/>

    <!-- 协议配置,由服务提供方指定,消费方被动接受。这里指定在20889端口暴露服务,默认端口在20880-->
    <dubbo:protocol name="dubbo" port="20889"/>

    <!-- 暴露dubbo服务的方式一-->
    <!-- 使用注解方式暴露接口,会自动扫描package下所有包中dubbo相关的注解,这样就不用在xml中再针对每个服务接口配置dubbo:service interface-->
    <dubbo:annotation package="com.practice.springboot.dubbo.server"/>

</beans>

如果要用 xml 配置方式暴露接口,将上面的 dubbo:annotation 一行替换成如下配置即可。

<!-- 暴露dubbo服务的方式二 -->
<!-- 使用xml配置方式申明暴露一个接口服务,在程序启动的时候会自动注册到zookeeper。
     等同于在类上打@service注解,打了注解就必须要用annotation指定启动扫描路径,使用这种方式,就不需要指定annotation了-->
<dubbo:service interface="com.practice.springboot.dubbo.server.ItemService" ref="itemService" group="dubbo-test"/>
<!-- 具体的实现bean,id与上面的ref要一致-->
<bean id="itemService" class="com.practice.springboot.dubbo.server.ItemServiceImpl" />

2.2 创建测试接口及测试类

服务提供方提供一个 checkItemStatus 方法,用来检查一个商品是否可售。
接口定义类 ItemService.java

package com.practice.springboot.dubbo.server;

public interface ItemService {
    //检查商品是否可售
    boolean checkItemStatus(String id);
}

接口实现类 ItemServiceImpl.java

package com.practice.springboot.dubbo.server;

import com.alibaba.dubbo.config.annotation.Service;
@Service  //该Service注解是dubbo的注解,不是spring的。若使用xml配置方式暴露接口,则不需要该注解。
public class ItemServiceImpl implements ItemService {

    @Override
    public boolean checkItemStatus(String id) {
        if (id.contains("111")) {
            return true;
        } else {
            return false;
        }
    }
}

2.3 编写启动类

启动类 SpringbootDubboServerApplication.java

package com.practice.springboot.dubbo.server;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:provider.xml")  //加载xml文件
public class SpringbootDubboServerApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(SpringbootDubboServerApplication.class, args);
        Thread.sleep(Long.MAX_VALUE); //pom中没有加spring-boot-starter-web依赖,启动时没有tomcat容器,会自动退出,所以加了一个sleep防止自动退出
    }
}

这里的 classpath 指的是各模块下的 target/classes 目录,该目录不仅包括 java 文件编译后的 class 文件,还包括 resources 目录下的配置文件。以本模块为例,target/classes 包含了以下内容:
alt 文本

3 dubbo 服务消费方配置

3.1 创建 xml 配置文件

创建远程服务代理和暴露 dubbo 服务一样,也有两种方式,一是使用注解方式,二是使用 xml 配置方式。下面的 consumer.xml 中使用的是第一种方式。
consumer.xml

<?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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

       <!-- 应用配置,不要与提供方相同 -->
       <dubbo:application name="DubboWithSpringBoot-Client"/>

       <!-- 注册中心配置,使用zookeeper注册中心暴露服务地址 -->
       <dubbo:registry address="zookeeper://10.165.124.69:2181" timeout="60000" />

       <!--关闭服务消费方所有服务的启动检查。dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成。-->
       <dubbo:consumer check="false" />

       <!-- 使用注解方式创建远程服务代理-->
       <dubbo:annotation package="com.practice.springboot.dubbo.client"/>
</beans>

如果使用 xml 配置方式创建远程服务代理,将 dubbo:annotation 一行替换成如下配置即可。

<!-- 使用xml配置方式创建远程服务代理,id即为provider.xml中暴露的服务的id-->
<!-- 等同于dubbo:annotation 加上代码里的@Reference注解-->
<dubbo:reference id="itemService" interface="com.practice.springboot.dubbo.client.OrderService"/>

3.2 创建测试类

OrderService.java

package com.practice.springboot.dubbo.client;

import com.alibaba.dubbo.config.annotation.Reference;
import com.practice.springboot.dubbo.server.ItemService;
import org.springframework.stereotype.Component;

@Component
public class OrderService {

    //注入服务提供方暴露的接口,通过@Reference注解,dubbo会在扫描的时候自动代理接口,然后通过rpc调用远程服务。
    //如果用xml配置方式,需要将@Reference换成@Autowired。
    @Reference
    ItemService itemService;

    public String checkBuyStatus(String id) {
        boolean flag = itemService.checkItemStatus(id);
        if (flag) {
            return "can buy!";
        } else {
            return "can not buy!";
        }
    }
}

3.3 编写启动类

SpringbootDubboClientApplication.java

package com.practice.springboot.dubbo.client;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@ImportResource("classpath:consumer.xml") //加载xml配置文件
@RestController
public class SpringbootDubboClientApplication {
    @Autowired
    OrderService orderService;

   @RequestMapping("/canbuy")
   public String canBuy(@RequestParam("id") String id){
      return orderService.checkBuyStatus(id);
   }

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

4 测试

我们先后运行 SpringbootDubboServerApplication.java 和 SpringbootDubboClientApplication.java,启动 dubbo 服务提供方和调用方。

在浏览器中输入 dubbo admin 的安装地址,如 127.0.0.1:8089,打开 dubbo admin 界面,在服务治理 - 服务界面,可以看到我们注册的 dubbo 服务。状态 “正常”,表示提供者和消费者都有。如果有乙方没有,在状态栏都会显示出来。
alt 文本

服务治理 - 应用页面,可以看到提供者 DubboWithSpringBoot-Server 和消费者 DubboWithSpringBoot-Client。
alt 文本

在浏览器中调用 canbuy 接口,正常返回结果,说明我们的配置都生效啦~~~
alt 文本

到这里,Spring Boot 集成 Dubbo 的内容都讲完啦。这样一个过程实践下来,再去看代码,就轻松多啦~~至少我们可以很快地完成以下三件事:
1、找到并看懂 dubbo 的配置文件
2、识 dubbo 服务的提供方和消费方
3、在 admin 中查看服务的状态

参考文档

Dubbo 基于注解方式的配置
dubbo 配置文件详解
通过 Dubbo 注解实现 RPC 调用

PS:代码学习与实践系列

代码学习与实践:开篇 - 测试深入了解代码的好处及实践
代码学习与实践 (一):Spring Boot 多模块项目创建与配置
代码学习与实践 (二):Spring Boot 集成 Dubbo

github 代码地址:https://github.com/Tester-Ella/CodeLearnAndPractic

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 0 条回复 时间 点赞
小敏 环境搭建 (一):Dubbo 环境搭建 中提及了此贴 12月24日 16:19
小敏 [该话题已被删除] 中提及了此贴 12月27日 19:43
小敏 [该话题已被删除] 中提及了此贴 12月28日 15:17
小敏 2017,在跌跌撞撞中成长和蜕变 中提及了此贴 12月28日 16:25
小敏 代码学习与实践 (二):Spring Boot 集成 Dubbo 中提及了此贴 01月15日 11:00
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册