dubbo實戰之一:準備和初體驗

歡迎訪問我的GitHub

https://github.com/zq2599/blog_demos

內容:所有原創文章分類彙總及配套源碼,涉及Java、Docker、Kubernetes、DevOPS等;

《dubbo實戰》系列導航

  1. 準備和初體驗
  2. 與SpringBoot集成
  3. 使用Zookeeper註冊中心
  4. 管理控制檯dubbo-admin

關於dubbo

  1. Apache Dubbo (發音<font color="blue">ˈdʌbəʊ</font>) 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動註冊和發現;
  2. 以下是來自官方的架構圖:

在這裏插入圖片描述

版本簡介和選定

  • 截止寫此文時,Dubbo 社區主力維護的有 2.6.x 和 2.7.x 兩大版本;
  • 2.6.x 主要以 bugfix 和少量 enhancements 爲主,因此能完全保證穩定性;
  • 2.7.x 作爲社區的主要開發版本,得到持續更新並增加了大量新 feature 和優化,同時也帶來了一些穩定性挑戰;
  • 綜上所述,《dubbo實戰》系列選擇了社區推薦的<font color="red">2.7.6</font>版本,這是2.7系列的穩定版;

環境信息

我這邊用來編碼的環境如下:

  1. 操作系統:macOS Catalina 10.15.5
  2. JDK:1.8.0_121
  3. Maven:33.3.9
  4. 開發工具:IntelliJ IDEA 2019.3.2 (Ultimate Edition)

注意事項

如果您是在windows環境運行代碼,並且安裝了VMWare,請您關閉對應的虛擬網卡,否則在廣播模式(Multicast)時,consumer可能無法找到自己所需的服務;

本篇概覽

  • 作爲《dubbo實戰》系列的開篇,本文的主要內容如下:
  1. 創建整個《dubbo實戰》系列的父工程;
  2. 創建整個《dubbo實戰》系列的公共二方庫;
  3. 初步體驗dubbo框架,爲了簡單,本篇的實戰暫不使用註冊中心,而是服務提供方啓動時廣播自己的地址,再由消費方啓動時訂閱,並隨時遠程調用,調用邏輯如下圖所示:

在這裏插入圖片描述 4. 先創建一個提供遠程服務的子工程,名爲<font color="blue">helloxmldirectprovider</font>,並運行起來; 5. 再創建名爲<font color="blue">helloxmldirectconsumer</font>的子工程,運行起來後,會調用<font color="blue">helloxmldirectprovider</font>提供的遠程服務,將遠端返回的內容打印出來;

  • 接下來開始編碼

源碼下載

  1. 如果您不想編碼,可以在GitHub下載所有源碼,地址和鏈接信息如下表所示:
名稱 鏈接 備註
項目主頁 https://github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git倉庫地址(https) https://github.com/zq2599/blog_demos.git 該項目源碼的倉庫地址,https協議
git倉庫地址(ssh) [email protected]:zq2599/blog_demos.git 該項目源碼的倉庫地址,ssh協議
  1. 這個git項目中有多個文件夾,本章的應用在<font color="blue">dubbopractice</font>文件夾下,如下圖紅框所示:

在這裏插入圖片描述 3. <font color="blue">dubbopractice</font>是父子結構的工程,本篇的代碼在<font color="red">helloxmldirectprovider</font>和<font color="red">helloxmldirectconsumer</font>這兩個子工程中,如下圖:

在這裏插入圖片描述

《dubbo實戰》系列的父工程

  1. 爲了方便管理《dubbo實戰》系列的代碼和依賴庫版本的管理,這裏創建名爲<font color="blue">dubbopractice</font>的父maven工程,整個系列的後續源碼都會作爲它的子工程;
  2. dubbopractice的pom.xml內容如下:
<?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">
    <modules>
        <module>practiceinterface</module>
        <module>helloxmldirectprovider</module>
        <module>helloxmldirectconsumer</module>
        <module>springbootzkprovider</module>
        <module>springbootzkconsumer</module>
        <module>springbootmulticastprovider</module>
        <module>springbootmulticastconsumer</module>
    </modules>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <java.version>1.8</java.version>
        <dubbo.version>2.7.6</dubbo.version>
        <springboot.version>2.3.3.RELEASE</springboot.version>
    </properties>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>dubbopractice</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.25.Final</version>
            </dependency>
            <!-- dubbo相關 -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-registry-multicast</artifactId>
                <version>${dubbo.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.7</version>
            </dependency>
            <dependency>
                <groupId>com.github.sgroschupf</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.1</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.16</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.11.0</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jdk8</artifactId>
                <version>2.11.0</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.25</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.7</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>3.10</version>
                <scope>compile</scope>
            </dependency>
            <!-- swagger依賴 -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.5.0</version>
            </dependency>
            <!-- swagger-ui -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.5.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

《dubbo實戰》系列的二方庫

  1. 涉及到多個工程之間的服務調用,因此要有個工程保存公用的數據結構、接口定義等,因此新建名爲<font color="blue">practiceinterface</font>的子工程;
  2. <font color="blue">practiceinterface</font>工程的pom.xml內容如下,非常簡單:
<?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>dubbopractice</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>practiceinterface</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>practiceinterface</name>
    <description>Beans of all app</description>
</project>
  1. 此工程目前只有一個接口定義,後面多個子工程都會用到:
package com.bolingcavalry.dubbopractice.service;

public interface DemoService {
    String sayHello(String name);
}

編碼(服務提供方)

  • 先創建提供服務的工程<font color="blue">helloxmldirectprovider</font>,一共要創建6個文件,創建順序和功能如下表:
創建順序 文件名 作用
1 pom.xml 工程的pom文件
2 src/main/java/com/bolingcavalry/helloxmldirectprovider/ProviderApplication.java 啓動類
3 src/main/java/com/bolingcavalry/helloxmldirectprovider/service/impl/DemoServiceImpl.java 提供具體的服務
4 src/main/resources/log4j.properties 日誌配置文件
5 src/main/resources/dubbo.properties dubbo配置文件
6 src/main/resources/spring/dubbo-provider.xml spring的bean配置
  • 完整的文件位置如下圖:

在這裏插入圖片描述

  • 接下來逐個創建上述內容;
  1. 創建名爲<font color="blue">helloxmldirectprovider</font>的子工程,pom.xml內容如下,可見剛纔新建的二方庫<font color="blue">practiceinterface</font>也被依賴了:
<?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>dubbopractice</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>helloxmldirectprovider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>practiceinterface</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
    </dependencies>
</project>
  1. 編寫啓動類<font color="blue">ProviderApplication.java</font>,可見就是個普通的後臺程序,加載spring配置做初始化:
package com.bolingcavalry.helloxmldirectprovider;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ProviderApplication {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-provider.xml");
        context.start();
        System.in.read();
    }
}
  1. 編寫提供具體服務的業務實現類<font color="blue">DemoServiceImpl.java</font>,只是個簡單的接口實現類而已:
package com.bolingcavalry.helloxmldirectprovider.service.impl;

import com.bolingcavalry.dubbopractice.service.DemoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.rpc.RpcContext;

@Slf4j
public class DemoServiceImpl implements DemoService {
    @Override
    public String sayHello(String name) {
        log.info("Hello " + name + ", request from consumer: " + RpcContext.getContext().getRemoteAddress());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress();
    }
}
  1. 日誌配置文件<font color="blue">log4j.properties</font>,內容如下:
###set log levels###
log4j.rootLogger=info, stdout
###output to the console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
  1. 在同樣位置創建dubbo配置文件<font color="blue">dubbo.properties</font>,內容很簡單隻有qos的端口設置,用於支持telnet命令:
dubbo.application.qos.port=22222
  1. 在resources目錄下新建文件夾<font color="blue">spring</font>,在此文件夾下創建文件<font color="blue">dubbo-provider.xml</font>,要重點關注的是<font color="blue">dubbo:registry</font>的配置,其address屬性值爲<font color="red">multicast://224.5.6.7:1234</font>,代表當前服務通過廣播讓消費者獲得自身信息:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <dubbo:application name="demo-provider"/>
    <!--廣播模式-->
    <dubbo:registry address="multicast://224.5.6.7:1234" />

    <bean id="demoService" class="com.bolingcavalry.helloxmldirectprovider.service.impl.DemoServiceImpl"/>
    <dubbo:service interface="com.bolingcavalry.dubbopractice.service.DemoService" ref="demoService"/>
</beans>
  1. 至此,服務提供方編碼完成,直接在IDEA上運行ProviderApplication類即可啓動服務,啓動成功後的日誌輸出如下圖:

在這裏插入圖片描述

編碼(服務消費方)

  • 現在網絡上已經有了服務,接下來創建一個消費該服務的工程<font color="blue">helloxmldirectconsumer</font>,一共要創建5個文件,創建順序和功能如下表:
創建順序 文件名 作用
1 pom.xml 工程的pom文件
2 src/main/java/com/bolingcavalry/helloxmldirectconsumer/ConsumerApplication.java 啓動、調用遠端服務、再結束自身進程
3 src/main/resources/log4j.properties 日誌配置文件
4 src/main/resources/dubbo.properties dubbo配置文件
5 src/main/resources/spring/dubbo-consumer.xml spring的bean配置
  • 完整的文件位置如下圖:

在這裏插入圖片描述

  • 接下來逐個創建上述文件;
  1. 創建名爲<font color="blue">helloxmldirectconsumer</font>的子工程,pom.xml內容如下,可見剛纔新建的二方庫<font color="blue">practiceinterface</font>也被依賴了:
<?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>dubbopractice</artifactId>
        <groupId>com.bolingcavalry</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>helloxmldirectconsumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>practiceinterface</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
    </dependencies>
</project>
  1. 編寫唯一的java文件<font color="blue">ConsumerApplication.java</font>,裏面用了最簡單的方法初始化spring環境,然後取得服務實例,執行過方法後結束進程:
package com.bolingcavalry.helloxmldirectconsumer;

import com.bolingcavalry.dubbopractice.service.DemoService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConsumerApplication {
    public static void main(String[] args) throws Exception {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml");
        context.start();
        DemoService demoService = context.getBean("demoService", DemoService.class);
        String hello = demoService.sayHello("world1");
        System.out.println("result: " + hello);
    }
}
  1. 日誌配置文件<font color="blue">log4j.properties</font>,內容如下:
###set log levels###
log4j.rootLogger=info, stdout
###output to console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n
  1. 在同樣位置創建dubbo配置文件<font color="blue">dubbo.properties</font>,內容很簡單隻有qos的端口設置,用於支持telnet命令,本例中是用不上的,因爲遠程調用後進程就會結束:
dubbo.application.qos.port=33333
  1. 在resources目錄下新建文件夾<font color="blue">spring</font>,在此文件夾下創建文件<font color="blue">dubbo-consumer.xml</font>,要重點關注的是<font color="blue">dubbo:registry</font>的配置,其address屬性值爲<font color="red">multicast://224.5.6.7:1234?unicast=false</font>,代表當前服務通過廣播讓消費者獲得自身信息,<font color="blue">unicast=false</font>表示多個消費者都能收到廣播:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
       http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">

    <dubbo:application name="demo-consumer"/>
    <dubbo:registry address="multicast://224.5.6.7:1234?unicast=false"/>
    <dubbo:reference id="demoService" check="false" interface="com.bolingcavalry.dubbopractice.service.DemoService" timeout="2000"/>
</beans>
  1. 上面的<font color="blue">dubbo-consumer.xml</font>中還有一處要注意,就是<font color="blue">dubbo:reference</font>的<font color="red">timeout</font>屬性,這是遠程調用的超時時間,此處設置爲2秒,要注意的是前面<font color="blue">helloxmldirectprovider</font>提供的服務延時了1秒才返回,所以這裏設置不能低於1秒;
  2. 至此,服務消費方編碼完成,直接在IDEA上運行<font color="blue">ConsumerApplication</font>類即可啓動,如下圖,紅框中就是遠程調用helloxmldirectprovider服務返回的內容:

在這裏插入圖片描述

  • 至此,《dubbo實戰》系列的準備和初體驗都完成了,接下來的章節,咱們會通過更多實戰來學習這個優秀的框架;

你不孤單,欣宸原創一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 數據庫+中間件系列
  6. DevOps系列

歡迎關注公衆號:程序員欣宸

微信搜索「程序員欣宸」,我是欣宸,期待與您一同暢遊Java世界... https://github.com/zq2599/blog_demos

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章