歡迎訪問我的GitHub
https://github.com/zq2599/blog_demos
內容:所有原創文章分類匯總及配套原始碼,涉及Java、Docker、Kubernetes、DevOPS等;
《dubbo實戰》系列導航
- 準備和初體驗
- 與SpringBoot集成
- 使用Zookeeper注冊中心
- 管理控制臺dubbo-admin
關于dubbo
- Apache Dubbo (發音?d?b??) 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向介面的遠程方法呼叫,智能容錯和負載均衡,以及服務自動注冊和發現;
- 以下是來自官方的架構圖:

版本簡介和選定
- 截止寫此文時,Dubbo 社區主力維護的有 2.6.x 和 2.7.x 兩大版本;
- 2.6.x 主要以 bugfix 和少量 enhancements 為主,因此能完全保證穩定性;
- 2.7.x 作為社區的主要開發版本,得到持續更新并增加了大量新 feature 和優化,同時也帶來了一些穩定性挑戰;
- 綜上所述,《dubbo實戰》系列選擇了社區推薦的2.7.6版本,這是2.7系列的穩定版;
環境資訊
我這邊用來編碼的環境如下:
- 作業系統:macOS Catalina 10.15.5
- JDK:1.8.0_121
- Maven:33.3.9
- 開發工具:IntelliJ IDEA 2019.3.2 (Ultimate Edition)
注意事項
如果您是在windows環境運行代碼,并且安裝了VMWare,請您關閉對應的虛擬網卡,否則在廣播模式(Multicast)時,consumer可能無法找到自己所需的服務;
本篇概覽
- 作為《dubbo實戰》系列的開篇,本文的主要內容如下:
- 創建整個《dubbo實戰》系列的父工程;
- 創建整個《dubbo實戰》系列的公共二方庫;
- 初步體驗dubbo框架,為了簡單,本篇的實戰暫不使用注冊中心,而是服務提供方啟動時廣播自己的地址,再由消費方啟動時訂閱,并隨時遠程呼叫,呼叫邏輯如下圖所示:

4. 先創建一個提供遠程服務的子工程,名為helloxmldirectprovider,并運行起來;
5. 再創建名為helloxmldirectconsumer的子工程,運行起來后,會呼叫helloxmldirectprovider提供的遠程服務,將遠端回傳的內容列印出來;
- 接下來開始編碼
原始碼下載
- 如果您不想編碼,可以在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協議 |
- 這個git專案中有多個檔案夾,本章的應用在dubbopractice檔案夾下,如下圖紅框所示:

3. dubbopractice是父子結構的工程,本篇的代碼在helloxmldirectprovider和helloxmldirectconsumer這兩個子工程中,如下圖:

《dubbo實戰》系列的父工程
- 為了方便管理《dubbo實戰》系列的代碼和依賴庫版本的管理,這里創建名為dubbopractice的父maven工程,整個系列的后續原始碼都會作為它的子工程;
- 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實戰》系列的二方庫
- 涉及到多個工程之間的服務呼叫,因此要有個工程保存公用的資料結構、介面定義等,因此新建名為practiceinterface的子工程;
- practiceinterface工程的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>
- 此工程目前只有一個介面定義,后面多個子工程都會用到:
package com.bolingcavalry.dubbopractice.service;
public interface DemoService {
String sayHello(String name);
}
編碼(服務提供方)
- 先創建提供服務的工程helloxmldirectprovider,一共要創建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配置 |
- 完整的檔案位置如下圖:

- 接下來逐個創建上述內容;
- 創建名為helloxmldirectprovider的子工程,pom.xml內容如下,可見剛才新建的二方庫practiceinterface也被依賴了:
<?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>
- 撰寫啟動類ProviderApplication.java,可見就是個普通的后臺程式,加載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();
}
}
- 撰寫提供具體服務的業務實作類DemoServiceImpl.java,只是個簡單的介面實作類而已:
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();
}
}
- 日志配置檔案log4j.properties,內容如下:
###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
- 在同樣位置創建dubbo組態檔dubbo.properties,內容很簡單只有qos的埠設定,用于支持telnet命令:
dubbo.application.qos.port=22222
- 在resources目錄下新建檔案夾spring,在此檔案夾下創建檔案dubbo-provider.xml,要重點關注的是dubbo:registry的配置,其address屬性值為multicast://224.5.6.7:1234,代表當前服務通過廣播讓消費者獲得自身資訊:
<?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" />
<dubbo:service interface="com.bolingcavalry.dubbopractice.service.DemoService" ref="demoService"/>
</beans>
- 至此,服務提供方編碼完成,直接在IDEA上運行ProviderApplication類即可啟動服務,啟動成功后的日志輸出如下圖:

編碼(服務消費方)
- 現在網路上已經有了服務,接下來創建一個消費該服務的工程helloxmldirectconsumer,一共要創建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配置 |
- 完整的檔案位置如下圖:

- 接下來逐個創建上述檔案;
- 創建名為helloxmldirectconsumer的子工程,pom.xml內容如下,可見剛才新建的二方庫practiceinterface也被依賴了:
<?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>
- 撰寫唯一的java檔案ConsumerApplication.java,里面用了最簡單的方法初始化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);
}
}
- 日志組態檔log4j.properties,內容如下:
###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
- 在同樣位置創建dubbo組態檔dubbo.properties,內容很簡單只有qos的埠設定,用于支持telnet命令,本例中是用不上的,因為遠程呼叫后行程就會結束:
dubbo.application.qos.port=33333
- 在resources目錄下新建檔案夾spring,在此檔案夾下創建檔案dubbo-consumer.xml,要重點關注的是dubbo:registry的配置,其address屬性值為multicast://224.5.6.7:1234?unicast=false,代表當前服務通過廣播讓消費者獲得自身資訊,unicast=false表示多個消費者都能收到廣播:
<?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>
- 上面的dubbo-consumer.xml中還有一處要注意,就是dubbo:reference的timeout屬性,這是遠程呼叫的超時時間,此處設定為2秒,要注意的是前面helloxmldirectprovider提供的服務延時了1秒才回傳,所以這里設定不能低于1秒;
- 至此,服務消費方編碼完成,直接在IDEA上運行ConsumerApplication類即可啟動,如下圖,紅框中就是遠程呼叫helloxmldirectprovider服務回傳的內容:

- 至此,《dubbo實戰》系列的準備和初體驗都完成了,接下來的章節,咱們會通過更多實戰來學習這個優秀的框架;
你不孤單,欣宸原創一路相伴
- Java系列
- Spring系列
- Docker系列
- kubernetes系列
- 資料庫+中間件系列
- DevOps系列
歡迎關注公眾號:程式員欣宸
微信搜索「程式員欣宸」,我是欣宸,期待與您一同暢游Java世界...
https://github.com/zq2599/blog_demos
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/266202.html
標籤:Java
上一篇:【老孟Flutter】Flutter 2.0 重磅更新
下一篇:執行緒池使用的N種姿勢
