3 - 使用 Dubbo x Spring Boot 開發微服務應用程式

本文將示範如何基於 Dubbo Samples,透過 Dubbo x Spring Boot 快速開發微服務應用程式。

目標

從零開始基於 Dubbo x Spring Boot 開發微服務,並了解 Dubbo x Spring Boot 的設定方法。

難度

環境需求

  • 系統:Windows、Linux、MacOS

  • JDK 8 及以上版本(建議使用 JDK 17)

  • Git

  • IntelliJ IDEA(可選)

  • Docker(可選)

專案介紹

在此任務中,將分為三個子模組獨立開發,模擬生產環境中的部署架構。

.//apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
├── dubbo-samples-spring-boot-interface // shared API module
├── dubbo-samples-spring-boot-consumer // consumer module
└── dubbo-samples-spring-boot-provider // server module

如上圖所示,共有 3 個模組,其中 interface 模組被 consumerprovider 模組共同依賴,存放 RPC 通訊使用的 API 介面。

.//apache/dubbo-samples/1-basic/dubbo-samples-spring-boot
├── dubbo-samples-spring-boot-interface // shared API module
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── org
│ └── apache
│ └── dubbo
│ └── springboot
│ └── demo
│ └── DemoService.java // API interface
├── dubbo-samples-spring-boot-consumer // consumer module
│ ├── pom.xml
│ └── src
│ ├── main
│ │ ├── java
│ │ │ └── org
│ │ │ └── apache
│ │ │ └── dubbo
│ │ │ └── springboot
│ │ │ └── demo
│ │ │ └── consumer
│ │ │ ├── ConsumerApplication.java // consumer startup class
│ │ │ └── Task.java // The consumer simulates calling tasks
│ │ └── resources
│ │ └── application.yml // Spring Boot configuration file
├── dubbo-samples-spring-boot-provider // server module
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ │ └── org
│ │ └── apache
│ │ └── dubbo
│ │ └── springboot
│ │ └── demo
│ │ └── provider
│ │ ├── DemoServiceImpl.java // server implementation class
│ │ └── ProviderApplication.java // server startup class
│ └── resources
│ └── application.yml // Spring Boot configuration file
└── pom.xml

以上是本教學會用到的專案檔案結構。

快速部署(直接基於 Samples 啟動)

本章節將逐步教您如何透過幾個簡單的指令部署並執行基於 Dubbo x Spring Boot 的使用案例。

注意:本章節部署的程式碼細節可以在 apache/dubbo-samples 倉庫中的 1-basic/dubbo-samples-spring-boot 找到,下一章節也會進行說明。

1. 取得測試專案

在開始整個教學之前,我們需要取得測試專案的程式碼。所有 Dubbo 的測試案例程式碼都儲存在 apache/dubbo-samples 這個儲存庫中,以下指令可以協助您取得 Samples 儲存庫中的所有程式碼。

git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git

2. 啟動一個簡單的註冊中心

對於一個微服務應用程式來說,註冊中心是一個不可或缺的組件。只有透過註冊中心,消費者才能成功地發現伺服器的地址資訊,進而發起呼叫。

為了讓本教學更容易上手,我們提供了一個基於 Apache Zookeeper 註冊中心的簡易啟動器。如果您需要在生產環境中部署註冊中心,請參考 生產環境初始化 來部署一個高可用的註冊中心。

Windows:
./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper

Linux / MacOS:
./mvnw clean compile exec:java -pl tools/embedded-zookeeper

Docker:
docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper

3. 本地打包 API 模組

為了成功編譯伺服器和消費者模組,您需要先在本機打包並安裝 dubbo-samples-spring-boot-interface 模組。

./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot
./mvnw clean install -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-interface

4. 啟動服務提供者

啟動註冊中心後,下一步是啟動一個對外提供服務的服務提供者。dubbo-samples 中也提供了對應的範例,可透過以下指令快速拉起。

Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider "-Dexec.mainClass=org.apache.dubbo.springboot.demo.provider.ProviderApplication"

Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-provider -Dexec.mainClass="org.apache.dubbo.springboot.demo.provider.ProviderApplication"

Note: You need to open an independent terminal to run, and the command will keep executing.

執行上述指令後,稍等片刻,待出現以下日誌(Current Spring Boot Application is await),即表示服務提供者已啟動,表示服務提供者可以對外提供服務。

2023-02-08 17:13:00.357 INFO 80600 --- [lication.main()] o.a.d.c.d.DefaultApplicationDeployer : [DUBBO] Dubbo Application[1.1](dubbo-springboot-demo-provider) is ready., dubbo version: 3.2 .0-beta.4, current host: 30.221.128.96
2023-02-08 17:13:00.369 INFO 80600 --- [lication.main()] o.a.d.s.d.provider.ProviderApplication : Started ProviderApplication in 9.114 seconds (JVM running for 26.522)
2023-02-08 17:13:00.387 INFO 80600 --- [pool-1-thread-1].b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await...

5. 啟動服務消費者

最後一步是啟動一個服務消費者來呼叫服務提供者,這是 RPC 呼叫的核心,為服務消費者呼叫服務提供者提供了橋樑。

Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer "-Dexec.mainClass=org.apache.dubbo.springboot.demo.consumer.ConsumerApplication"

Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-spring-boot/dubbo-samples-spring-boot-consumer -Dexec.mainClass="org.apache.dubbo.springboot.demo.consumer.ConsumerApplication"

執行上述指令後,稍等片刻,待出現以下日誌(Hello world)。印出的資料是經過服務提供者處理後返回的,標誌著一次服務呼叫的成功。

2023-02-08 17:14:33.045 INFO 80740 --- [lication.main()] o.a.d.s.d.consumer.ConsumerApplication : Started ConsumerApplication in 11.052 seconds (JVM running for 31.62)
Receive result ======> Hello world
2023-02-08 17:14:33.146 INFO 80740 --- [pool-1-thread-1].b.c.e.AwaitingNonWebApplicationListener : [Dubbo] Current Spring Boot Application is await...
Wed Feb 08 17:14:34 CST 2023 Receive result ======> Hello world
Wed Feb 08 17:14:35 CST 2023 Receive result ======> Hello world
Wed Feb 08 17:14:36 CST 2023 Receive result ======> Hello world
Wed Feb 08 17:14:37 CST 2023 Receive result ======> Hello world

動手實作 (從零程式碼開發版本)

本章將透過循序漸進的教學,教您如何從零開始開發一個微服務應用程式。

1. 啟動註冊中心

對於一個微服務應用程式來說,註冊中心是一個不可或缺的組件。只有透過註冊中心,消費者才能成功地發現伺服器的地址資訊,進而發起呼叫。

為了讓本教學更容易上手,我們提供了一個基於 Apache Zookeeper 註冊中心的簡易啟動器。如果您需要在生產環境中部署註冊中心,請參考 生產環境初始化 來部署一個高可用的註冊中心。

Windows:
git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git
cd dubbo-samples
./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper

Linux / MacOS:
git clone --depth=1 --branch master git@github.com:apache/dubbo-samples.git
cd dubbo-samples
./mvnw clean compile exec:java -pl tools/embedded-zookeeper

Docker:
docker run --name some-zookeeper -p 2181:2181 --restart always -d zookeeper

2. 初始化專案

從本節開始,將基於 IntelliJ IDEA 建置和測試專案。

img

如上圖所示,即可建置一個基礎專案。

建置基礎專案後,我們需要建立三個子模組 dubbo-spring-boot-demo-interfacedubbo-spring-boot-demo-providerdubbo-spring-boot-demo-consumer

img

img

img

img

建立完三個子模組後,您需要建立以下資料夾

  1. dubbo-spring-boot-demo-consumer/src/main/java 下建立 org.apache.dubbo.springboot.demo.consumer 套件

  2. dubbo-spring-boot-demo-interface/src/main/java 下建立 org.apache.dubbo.springboot.demo 套件

  3. dubbo-spring-boot-demo-provider/src/main/java 下建立 org.apache.dubbo.springboot.demo.provider 套件

img

最終的資料夾參考如上圖所示。

3. 加入 Maven dependencies (相依性)

初始化專案後,我們需要先加入 Dubbo 相關的 maven 相依性。

對於多模組專案,首先需要在父專案的 pom.xml 中設定相依性資訊。

img

編輯 ./pom.xml 檔案,並加入以下設定。

    <properties>
        <dubbo.version>3.2.0-beta.4</dubbo.version>
        <spring-boot.version>2.7.8</spring-boot.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-bom</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
                <version>${dubbo.version}</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>


    <build>
        <plugin Management>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

接著在 dubbo-spring-boot-consumerdubbo-spring-boot-provider 兩個模組的 pom.xml 中設定具體的相依性。

img

編輯 ./dubbo-spring-boot-consumer/pom.xml./dubbo-spring-boot-provider/pom.xml,並加入以下設定。

    <dependencies>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-samples-spring-boot-interface</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- dubbo -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-dependencies-zookeeper-curator5</artifactId>
            <type>pom</type>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-reload4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

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

    </dependencies>

在此設定中,定義了 dubbo 和 zookeeper(以及對應的連接器 curator)的相依性。

加入上述設定後,您可以透過 IDEA 的 Maven - Reload All Maven Projects 重新整理相依性。

4. 定義服務介面

服務介面是 Dubbo 中消費者和伺服器之間的橋樑。

img

dubbo-spring-boot-demo-interface 模組的 org.apache.dubbo.samples.api 下建立 DemoService 介面,定義如下

package org.apache.dubbo.springboot.demo;

public interface DemoService {

    String sayHello(String name);
}

DemoService 中,定義了 sayHello 方法。後續服務端發佈的服務以及消費端訂閱的服務都是圍繞 DemoService 介面展開的。

5. 定義服務端的實現

定義好服務介面後,就可以在服務端定義對應的實現了。與消費端相比,這部分的實現是遠端實現,本地沒有相關資訊。

img

dubbo-spring-boot-demo-provider 模組的 org.apache.dubbo.samples.provider 下建立 DemoServiceImpl 類別,定義如下

package org.apache.dubbo.springboot.demo.provider;

import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.springboot.demo.DemoService;

@DubboService
public class DemoServiceImpl implements DemoService {

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

DemoServiceImpl 中,實現 DemoService 介面,為 sayHello 方法返回 Hello name

注意:在 DemoServiceImpl 類別上添加了 @DubboService 註解。通過此配置,即可基於 Spring Boot 發佈 Dubbo 服務。

6. 配置服務端 Yaml 配置檔

從這一步驟到步驟 7,將通過 Spring Boot 配置 Dubbo 的一些基本資訊。

首先,我們先來建立服務端的配置檔。

img

dubbo-spring-boot-demo-provider 模組的 resources 資源資料夾下建立 application.yml 檔案,定義如下

dubbo:
  application:
    name: dubbo-springboot-demo-provider
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

在這個配置檔中,定義了 Dubbo 應用名稱、Dubbo 協定資訊以及 Dubbo 使用的註冊中心地址。

7. 配置消費端 Yaml 配置檔

同樣地,我們需要為消費端建立一個配置檔。

img

dubbo-spring-boot-demo-consumer 模組的 resources 資源資料夾下建立 application.yml 檔案,定義如下

dubbo:
  application:
    name: dubbo-springboot-demo-consumer
  protocol:
    name: dubbo
    port: -1
  registry:
    address: zookeeper://${zookeeper.address:127.0.0.1}:2181

在這個配置檔中,定義了 Dubbo 應用名稱、Dubbo 協定資訊以及 Dubbo 使用的註冊中心地址。

8. 基於 Spring 配置服務端啟動類別

除了配置 Yaml 配置檔外,我們還需要建立一個基於 Spring Boot 的啟動類別。

首先,我們先建立服務端的啟動類別。

img

dubbo-spring-boot-demo-provider 模組的 org.apache.dubbo.springboot.demo.provider 下建立 Application 類別,定義如下

package org.apache.dubbo.springboot.demo.provider;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
    }
}

在這個啟動類別中,配置了一個 ProviderApplication,用於讀取上面步驟 6 中定義的 application.yml 配置檔並啟動應用程式。

9. 基於 Spring 配置消費端啟動類別

同樣地,我們需要為消費端建立一個啟動類別。

img

dubbo-spring-boot-demo-consumer 模組的 org.apache.dubbo.springboot.demo.consumer 下建立 Application 類別,定義如下

package org.apache.dubbo.springboot.demo.consumer;

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {

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

在這個啟動類別中,配置了一個 ConsumerApplication,用於讀取上面步驟 7 中定義的 application.yml 配置檔並啟動應用程式。

10. 配置消費端請求任務

除了配置消費端的啟動類別外,我們還可以在 Spring Boot 模式下基於 CommandLineRunner 建立

img

dubbo-spring-boot-demo-consumer 模組的 org.apache.dubbo.springboot.demo.consumer 下建立一個 Task 類別,定義如下

package org.apache.dubbo.springboot.demo.consumer;

import java.util.Date;

import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.springboot.demo.DemoService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class Task implements CommandLineRunner {
    @DubboReference
    private DemoService demoService;

    @Override
    public void run(String... args) throws Exception {
        String result = demoService. sayHello("world");
        System.out.println("Receive result ======> " + result);

        new Thread(()-> {
            while (true) {
                try {
                    Thread. sleep(1000);
                    System.out.println(new Date() + " Receive result ======> " + demoService.sayHello("world"));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    Thread. currentThread(). interrupt();
                }
            }
        }).start();
    }
}

Task 類別中,通過 @DubboReference 從 Dubbo 獲取一個 RPC 訂閱,這個 demoService 可以像本地呼叫一樣直接呼叫。在 run 方法中為呼叫建立了一個執行緒。

11. 啟動應用程式

截至步驟 10,程式碼已經開發完成,本節將啟動整個專案並進行驗證。

img

首先是啟動 org.apache.dubbo.samples.provider.Application,稍等片刻出現如下圖所示的日誌 (Current Spring Boot Application is await),表示服務提供者已啟動,標誌著服務提供者可以對外提供服務。

[Dubbo] Current Spring Boot Application is await...

然後啟動 org.apache.dubbo.samples.client.Application,稍等片刻可以看到如下圖所示的日誌 (Hello world),表示服務消費者已啟動,並且成功獲取到對服務端的呼叫。

img

Receive result ======> Hello world

延伸閱讀

1. Dubbo 的 Spring 配置介紹

Dubbo 的主要配置方式包括 yaml 配置內容、@DubboReference@DubboService 等。更多細節,請參考[註解配置 | Apache Dubbo](/zh-cn/overview/mannual/java-sdk/reference-manual /config/annotation/) 文章。

更多

本教學介紹如何基於 Dubbo x Spring Boot 開發微服務應用程式。下一節將介紹另一種 Dubbo 配置方法 - Dubbo x Spring XML。


最後修改日期:2024 年 4 月 10 日:修正包含 -Dexec 的 Windows 命令 (#2957) (bbb9a203c3b)