本文將基于 Dubbo Samples 示例演示如何快速搭建并部署一個微服務應用,
背景

Dubbo 作為一款微服務框架,最重要的是向用戶提供跨行程的 RPC 遠程呼叫能力,如上圖所示,Dubbo 的服務消費者(Consumer)通過一系列的作業將請求發送給服務提供者(Provider),
為了實作這樣一個目標,Dubbo 引入了注冊中心(Registry)組件,通過注冊中心,服務消費者可以感知到服務提供者的連接方式,從而將請求發送給正確的服務提供者,
目標
了解微服務呼叫的方式以及 Dubbo 的能力
難度
低
環境要求
-
系統:Windows、Linux、MacOS
-
JDK 8 及以上(推薦使用 JDK17)
-
Git
-
Docker (可選)
動手實踐
本章將通過幾個簡單的命令,一步一步教你如何部署并運行一個最簡單的 Dubbo 用例,
1. 獲取測驗工程
在開始整個教程之前,我們需要先獲取測驗工程的代碼,Dubbo 的所有測驗用例代碼都存盤在 apache/dubbo-samples 這個倉庫中,以下這個命令可以幫你獲取 Samples 倉庫的所有代碼,
git clone --depth=1 --branch master [email protected]:apache/dubbo-samples.git
2. 認識 Dubbo Samples 專案結構
在將 apache/dubbo-samples 這個倉庫 clone 到本地以后,本小節將就倉庫的具體組織方式做說明,
.
├── codestyle // 開發使用的 style 組態檔
├── 1-basic // 基礎的入門用例
├── 2-advanced // 高級用法
├── 3-extensions // 擴展使用示例
├── 4-governance // 服務治理用例
├── 10-task // Dubbo 學習系列示例
├── 99-integration // 集成測驗使用
├── test // 集成測驗使用
└── tools // 三方組件快速啟動工具
如上表所示,apache/dubbo-samples 主要由三個部分組成:代碼風格檔案、測驗代碼、集成測驗,
-
代碼風格檔案是開發 Dubbo 代碼的時候可以使用,其中包括了 IntelliJ IDEA 的組態檔,
-
測驗代碼即本教材所需要的核心內容,目前包括了 5 個部分的內容:面向初學者的 basic 入門用例、面向開發人員的 advanced 高級用法、面向中間件維護者的 extensions Dubbo 周邊擴展使用示例、面向生產的 governance 服務治理用例以及 Dubbo 學習系列,本文將基于 basic 入門用例中最簡單的 Dubbo API 使用方式進行講解,
-
集成測驗是 Dubbo 的質量保證體系中重要的一環,Dubbo 的每個版本都會對所有的 samples 進行回歸驗證,保證 Dubbo 的所有變更都不會影響 samples 的使用,
3. 啟動一個簡易的注冊中心
從這一小節開始,將正式通過三個命令部署一個微服務應用,
從 背景 一節中可知,運行起 Dubbo 應用的一個大前提是部署一個注冊中心,為了讓本教程更易于上手,我們提供了一個基于 Apache Zookeeper 注冊中心的簡易啟動器,如果您需要在生產環境部署注冊中心,請參考生產環境初始化一文部署高可用的注冊中心,
Windows:
./mvnw.cmd clean compile exec:java -pl tools/embedded-zookeeper
Linux / MacOS:
./mvnw clean compile exec:java -pl tools/embedded-zookeeper
注:需要開一個獨立的 terminal 運行,命令將會保持一直執行的狀態,
Docker:
docker run --name some-zookeeper --restart always -d zookeeper
在執行完上述命令以后,等待一會出現如下圖所示的日志即代表注冊中心啟動完畢,可以繼續執行后續任務,

4. 啟動服務提供者
在啟動了注冊中心之后,下一步是啟動一個對外提供服務的服務提供者,在 dubbo-samples 中也提供了對應的示例,可以通過以下命令快速拉起,
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
注:需要開一個獨立的 terminal 運行,命令將會保持一直執行的狀態,
在執行完上述命令以后,等待一會出現如下圖所示的日志(DubboBootstrap awaiting)即代表服務提供者啟動完畢,標志著該服務提供者可以對外提供服務了,

[19/01/23 03:55:49:049 CST] org.apache.dubbo.samples.provider.Application.main() INFO bootstrap.DubboBootstrap: [DUBBO] DubboBootstrap awaiting ..., dubbo version: 3.2.0-beta.3, current host: 169.254.44.42
5. 啟動服務消費者
最后一步是啟動一個服務消費者來呼叫服務提供者,也即是 RPC 呼叫的核心,為服務消費者提供呼叫服務提供者的橋梁,
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
在執行完上述命令以后,等待一會出現如下圖所示的日志(hi, dubbo),列印出的資料就是服務提供者處理之后回傳的,標志著一次服務呼叫的成功,

Receive result ======> hi, dubbo
延伸閱讀
1. 消費端是怎么找到服務端的?
在本用例中的步驟 3 啟動了一個 Zookeeper 的注冊中心,服務提供者會向注冊中心中寫入自己的地址,供服務消費者獲取,
Dubbo 會在 Zookeeper 的 /dubbo/interfaceName 和 /services/appName 下寫入服務提供者的連接資訊,
如下所示是 Zookeeper 上的資料示例:
[zk: localhost:2181(CONNECTED) 5] ls /dubbo/org.apache.dubbo.samples.api.GreetingsService/providers
[dubbo%3A%2F%2F30.221.146.35%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26ipv6%3Dfd00%3A1%3A5%3A5200%3A3218%3A774a%3A4f67%3A2341%26methods%3DsayHi%26pid%3D85639%26release%3D3.1.4%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1674960780647]
[zk: localhost:2181(CONNECTED) 2] ls /services/first-dubbo-provider
[30.221.146.35:20880]
[zk: localhost:2181(CONNECTED) 3] get /services/first-dubbo-provider/30.221.146.35:20880
{"name":"first-dubbo-provider","id":"30.221.146.35:20880","address":"30.221.146.35","port":20880,"sslPort":null,"payload":{"@class":"org.apache.dubbo.registry.zookeeper.ZookeeperInstance","id":"30.221.146.35:20880","name":"first-dubbo-provider","metadata":{"dubbo.endpoints":"[{\"port\":20880,\"protocol\":\"dubbo\"}]","dubbo.metadata-service.url-params":"{\"connections\":\"1\",\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.1.4\",\"side\":\"provider\",\"ipv6\":\"fd00:1:5:5200:3218:774a:4f67:2341\",\"port\":\"20880\",\"protocol\":\"dubbo\"}","dubbo.metadata.revision":"871fbc9cb2730caea9b0d858852d5ede","dubbo.metadata.storage-type":"local","ipv6":"fd00:1:5:5200:3218:774a:4f67:2341","timestamp":"1674960780647"}},"registrationTimeUTC":1674960781893,"serviceType":"DYNAMIC","uriSpec":null}
更多關于 Dubbo 服務發現模型的細節,可以參考服務發現一文,
2. 消費端是如何發起請求的?
在 Dubbo 的呼叫模型中,起到連接服務消費者和服務提供者的橋梁是介面,
服務提供者通過對指定介面進行實作,服務消費者通過 Dubbo 去訂閱這個介面,服務消費者呼叫介面的程序中 Dubbo 會將請求封裝成網路請求,然后發送到服務提供者進行實際的呼叫,
在本用例中,定義了一個 GreetingsService 的介面,這個介面有一個名為 sayHi 的方法,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java
package org.apache.dubbo.samples.api;
public interface GreetingsService {
String sayHi(String name);
}
服務消費者通過 Dubbo 的 API 可以獲取這個 GreetingsService 介面的代理,然后就可以按照普通的介面呼叫方式進行呼叫,得益于 Dubbo 的動態代理機制,這一切都像本地呼叫一樣,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
// 獲取訂閱到的 Stub
GreetingsService service = reference.get();
// 像普通的 java 介面一樣呼叫
String message = service.sayHi("dubbo");
3. 服務端可以部署多個嗎?
可以,本小節將演示如何啟動一個服務端集群,
1)啟動一個注冊中心,可以參考動手實踐中第 3 小節的教程
2)修改服務提供者回傳的資料,讓第一個啟動的服務提供者回傳 hi, dubbo. I am provider 1.
修改 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java 檔案的第 25 行如下所示,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
package org.apache.dubbo.samples.provider;
import org.apache.dubbo.samples.api.GreetingsService;
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {
return "hi, " + name + ". I am provider 1.";
}
}
3)啟動第一個服務提供者,可以參考動手實踐中第 4 小節的教程
4)修改服務提供者回傳的資料,讓第二個啟動的服務提供者回傳 hi, dubbo. I am provider 2.
修改 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java 檔案的第 25 行如下所示,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java
package org.apache.dubbo.samples.provider;
import org.apache.dubbo.samples.api.GreetingsService;
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {
return "hi, " + name + ". I am provider 2.";
}
}
4)啟動第二個服務提供者,可以參考動手實踐中第 4 小節的教程
5)啟動服務消費者,可以參考動手實踐中第 5 小節的教程,多次啟動消費者可以看到回傳的結果是不一樣的,
在 dubbo-samples 中也提供了一個會定時發起呼叫的消費端應用org.apache.dubbo.samples.client.AlwaysApplication,可以通過以下命令啟動,
Windows:
./mvnw.cmd clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
Linux / MacOS:
./mvnw clean compile exec:java -pl 1-basic/dubbo-samples-api -Dexec.main
啟動后可以看到類似以下的日志,消費端會隨機呼叫到不同的服務提供者,回傳的結果也是遠端的服務提供者覺得其結果,
Sun Jan 29 11:23:37 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
Sun Jan 29 11:23:38 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
Sun Jan 29 11:23:39 CST 2023 Receive result ======> hi, dubbo. I am provider 2.
Sun Jan 29 11:23:40 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
Sun Jan 29 11:23:41 CST 2023 Receive result ======> hi, dubbo. I am provider 1.
4. 這個用例復雜嗎?
不,Dubbo 只需要簡單的配置就可以實作穩定、高效的遠程呼叫,
以下是一個服務提供者的簡單示例,通過定義若干個配置就可以啟動,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/Application.java
// 定義所有的服務
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
service.setInterface(GreetingsService.class);
service.setRef(new GreetingsServiceImpl());
// 啟動 Dubbo
DubboBootstrap.getInstance()
.application("first-dubbo-provider")
.registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
.protocol(new ProtocolConfig("dubbo", -1))
.service(service)
.start();
以下是一個服務消費者的簡單示例,通過定義若干個配置啟動后就可以獲取到對應的代理物件,之后用戶完全不需要感知這個物件背后的復雜實作,一切只需要和本地呼叫一樣就行了,
// 1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java
// 定義所有的訂閱
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
reference.setInterface(GreetingsService.class);
// 啟動 Dubbo
DubboBootstrap.getInstance()
.application("first-dubbo-consumer")
.registry(new RegistryConfig(ZOOKEEPER_ADDRESS))
.reference(reference)
.start();
// 獲取訂閱到的 Stub
GreetingsService service = reference.get();
// 像普通的 java 介面一樣呼叫
String message = service.sayHi("dubbo");
更多
本用例介紹了一個 RPC 遠程呼叫的基礎流程,通過啟動注冊中心、服務提供者、服務消費者三個節點來模擬一個微服務的部署架構,
下一個教程中,將就服務提供者和服務消費者分別都做了什么配置進行講解,從零告訴你如何搭建一個微服務應用,
歡迎在 https://github.com/apache/dubbo 給 Dubbo Star,
搜索關注官方微信公眾號:Apache Dubbo,了解更多業界最新動態,掌握大廠面試必備 Dubbo 技能
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/542764.html
標籤:其他
上一篇:分享會上狂吹MySQL的4大索引結構,沒想到大家的鑒賞能力如此的~~~~
下一篇:Java 多型
