Dubbo是由阿里巴巴研发的一个高性能的,基于java的RPC开源的框架 。在停止维护了数年之后,直到去年,阿里巴巴开始重启维护Dubbo ,并在短短的三个月内连续发布 3 个维护版本。现在,Dubbo已经成为Apache基金会孵化项目。以下是官网介绍:

接下来将以Dubbo官网的Quick Start例子来体验构建一个简单的Dubbo应用(使用ZooKeeper作为注册中心)。

1.创建Maven项目

使用IDEA创建一个Maven项目,然后在该项目中创建三个Module:远程服务项目(Interface)服务提供者项目(Provider)服务消费者项目(Client)

工程项目结构如下:

  • Interface:
    • DemoService.java:接口定义
  • Provider:
    • DemoServiceImpl.java:远程接口实现类
    • Provider.java:服务提供启动类
    • resources/provider.xml:Dubbo服务提供相关属性配置
  • Client:
    • Consumer.java:服务消费启动类
    • resources/consumer.xml:Dubbo服务消费相关属性配置

2.引入Dubbo依赖

在服务提供(Provider)和服务消费(Client)项目中加入Dubbo以及相关依赖:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>dubbo-01</artifactId>
        <groupId>com.kingdee.bin</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-01-providers</artifactId>

    <properties>
        <dubbo-version>2.6.2</dubbo-version>
        <curator-version>2.11.0</curator-version>
        <zookeeper-version>3.4.5</zookeeper-version>
        <zkclient-version>0.1</zkclient-version>
    </properties>

    <dependencies>
        <!-- 引入远程服务模块 -->
        <dependency>
            <groupId>com.kingdee.bin</groupId>
            <artifactId>dubbo-01-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- Dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>${dubbo-version}</version>
        </dependency>

        <!-- Curator -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>${curator-version}</version>
        </dependency>

        <!-- zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>${zookeeper-version}</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>${zkclient-version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--compiler插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  • 注:两个项目的pom.xml文件内容一样即可。

3.远程服务接口

在远程服务项目(Interface)中定义一个测试接口,如下:

DemoService.java:

public interface DemoService {

    String sayHello(String name);

}

注:这个项目是用来定义接口规范的,所以也不需要做任何配置,只提供服务的双方进行引用。

4.服务提供者 Provider

在服务提供方实现接口

DemoServiceImpl.java :

public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        return "Hello " + name;
    }

}

用 Spring 配置声明暴露服务

因为Dubbo是使用Spring的Schema进行扩展标签和解析配置的,所以我们可以像使用Spring的XML配置方式一样来进行Dubbo的配置。接下来我们在Provider项目的resources/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://dubbo.apache.org/schema/dubbo"
       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">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="hello-world-app"  />

    <!-- 使用zookeeper广播注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.kingdee.bin.DemoService" ref="demoService" />

    <!-- 和本地bean一样实现服务 -->
    <bean id="demoService" class="com.kingdee.bin.DemoServiceImpl" />

</beans>

加载 Spring 配置

Provider.java:

public class Provider {

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"provider.xml"});
        context.start();
        System.out.println("Provider Started");
        System.in.read(); // 按任意键退出
    }

}

5.服务消费者 Consumer

通过 Spring 配置引用远程服务

在Consumer项目的resources/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://dubbo.apache.org/schema/dubbo"
       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 ">

    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
    <dubbo:application name="consumer-of-helloworld-app"  />

    <!-- 使用zookeeper广播注册中心暴露发现服务地址 -->
    <dubbo:registry address="zookeeper://127.0.0.1:2181" />

    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="demoService" interface="com.kingdee.bin.DemoService" />

</beans>

加载Spring配置,并调用远程服务

Consumer.java :

public class Consumer {

    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"consumer.xml"});
        context.start();
        DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
        String hello = demoService.sayHello("world"); // 执行远程方法
        System.out.println( hello ); // 显示调用结果
    }

}

6.启动项目

  • 运行Registry

    • 因为我们配置的Dubbo注册中心为ZooKeeper,所以在启动项目之前要先安装和运行ZooKeeper(这里不谈论ZooKeeper的安装和运行问题,另外,只需要配置单机ZooKeeper的端口为上面指定的2181即可)。
  • 启动Provider

    • 运行Provider.java的main(),查看zkServer控制台输出:

    Provider已经通过端口:61606(不是唯一)进入注册中心。

  • 启动Consumer

    • 运行Consumer.java的main(),查看zkServer控制台输出:

    同样的,Consumer通过端口:61629(不是唯一)进入注册中心。

    • 程序运行结束后,在IDEA控制台输出了“Hello world”,说明服务消费成功,程序正常退出。
  • 查看ZooKeeper节点信息

    • 待Provider项目停止之前(在字符输入流中阻塞)使用zkCli查看ZooKeeper的节点数据:

    Dubbo在ZooKeeper创建了/dubbo/*.DemoService节点,并且其下还有consumers,configurators,routers和providers四个子节点,其中providers下还有一个以dubbo开头的子节点。说明一点,由于Consumer服务消费完之后便结束了程序,所以在consumers节点下没有子节点。关于Dubbo的ZooKeeper注册中心,接下来将进行简单讲解。

    • 解析provider节点名称:

    dubbo://172.20.8.62:20880/com.kingdee.bin.DemoService?anyhost=true&application=hello-world-app&dubbo=2.6.2&generic=false&interface=com.kingdee.bin.DemoService&methods=sayHello&pid=7692&side=provider&timestamp=1528442391511

7.zookeeper 注册中心

最后来看一下Dubbo是如何在ZooKeeper中建立目录结构以及其注册流程和支持的功能。如下图所示,

流程说明:

  • 服务提供者启动时: 向 /dubbo/com.foo.BarService/providers 目录下写入自己的 URL 地址
  • 服务消费者启动时: 订阅 /dubbo/com.foo.BarService/providers 目录下的提供者 URL 地址。并向 /dubbo/com.foo.BarService/consumers 目录下写入自己的 URL 地址
  • 监控中心启动时: 订阅 /dubbo/com.foo.BarService 目录下的所有提供者和消费者 URL 地址。

支持以下功能:

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置 <dubbo:registry check="false" /> 时,记录失败注册和订阅请求,后台定时重试
  • 可通过 <dubbo:registry username="admin" password="1234" /> 设置 zookeeper 登录信息
  • 可通过 <dubbo:registry group="dubbo" /> 设置 zookeeper 的根节点,不设置将使用无根树
  • 支持 * 号通配符 <dubbo:reference group="*" version="*" />,可订阅服务的所有分组和所有版本的提供者

参考资料:

Dubbo官网

Dubbo中文用户手册-快速启动

Demo下载地址:Dubbo-01

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐