如何快速開發一個 Dubbo 應用

背景java

本文將以 Dubbo 爲例,介紹如何快速開發一個 Dubbo 應用。爲了便於讀者理解:git

首先會介紹一下傳統的 RMI 的基本概念github

而後比較下現代的 RPC 框架與 RMI 的區別spring

再基於 Dubbo 提供的 API 展現最基本的 Dubbo 應用如何開發編程

最後介紹如何經過 start.dubbo.io 快速搭建 Dubbo 的腳手架工程api

Java RMI 簡介網絡

 

Java RMI (Remote Method Invocation) 遠程方法調用,可以讓客戶端像使用本地調用同樣調用服務端 Java 虛擬機中的對象方法。RMI 是面嚮對象語言領域對 RPC (Remote Procedure Call)的完善,用戶無需依靠 IDL 的幫助來完成分佈式調用,而是經過依賴接口這種更簡單天然的方式。架構

Java RMI 工做原理app

一個典型的 RMI 調用以下圖所示:框架

服務端向 RMI 註冊服務綁定本身的地址;

客戶端經過 RMI 註冊服務獲取目標地址;

客戶端調用本地的 Stub 對象上的方法,和調用本地對象上的方法一致;

本地存根對象將調用信息打包,經過網絡發送到服務端;

服務端的 Skeleton 對象收到網絡請求以後,將調用信息解包;

而後找到真正的服務對象發起調用,並將返回結果打包經過網絡發送回客戶端。

(來源:https://www.cs.rutgers.edu/~pxk/417/notes/images/rpc-rmi_flow.png)

Java RMI 基本概念

Java RMI 是 Java 領域建立分佈式應用的技術基石。後續的 EJB 技術,以及現代的分佈式服務框架,其中的基本理念依舊是 Java RMI 的延續。在 RMI 調用中,有如下幾個核心的概念:

經過接口進行遠程調用

經過客戶端的 Stub 對象和服務端的 Skeleton 對象的幫助將遠程調用假裝成本地調用

經過RMI 註冊服務完成服務的註冊和發現

對於第一點,客戶端須要依賴接口,而服務端須要提供該接口的實現。對於第二點,在 J2SE 1.5 版本以前須要經過 rmic 預先編譯好客戶端的 Stub 對象和服務端的 Skeleton 對象。在以後的版本中,再也不須要事先生成 Stub 和 Skeleton 對象。

下面經過示例代碼簡單的展現 RMI 中的服務註冊和發現:

服務端的服務註冊

說明:

初始化服務對象實例;

經過 UnicastRemoteObject.exportObject 生成能夠與服務端通信的 Stub 對象;

建立一個本地的 RMI 註冊服務,監聽端口爲 1099。該註冊服務運行在服務端,也能夠單獨啓動一個註冊服務的進程;

將 Stub 對象綁定到註冊服務上,這樣,客戶端能夠經過 Hello 這個名字查找到該遠程對象。

客戶端的服務發現

說明:

獲取註冊服務實例,在本例中,因爲沒有傳入任何參數,假定要獲取的註冊服務實例部署在本機,並監聽在 1099 端口上;

從註冊服務中查找服務名爲 Hello 的遠程對象;

經過獲取的 Stub 對象發起一次 RMI 調用並得到結果。

理解 RMI 的工做原理和基本概念,對掌握現代分佈式服務框架頗有幫助,建議進一步的閱讀 RMI 官方教材 [1]。

Dubbo 基本概念

現代的分佈式服務框架的基本概念與 RMI 是相似的,一樣是使用 Java 的 Interface 做爲服務契約,經過註冊中心來完成服務的註冊和發現,遠程通信的細節也是經過代理類來屏蔽。具體來講,Dubbo 在工做時有如下四個角色參與:

服務提供者:啓動時在指定端口上暴露服務,並將服務地址和端口註冊到註冊中心上。

服務消費者:啓動時向註冊中心訂閱本身感興趣的服務,以便得到服務提供方的地址列表。

註冊中心 :負責服務的註冊和發現,負責保存服務提供方上報的地址信息,並向服務消費方推送。

監控中心:負責收集服務提供方和消費方的運行狀態,好比服務調用次數、延遲等,用於監控。

運行容器:負責服務提供方的初始化、加載以及運行的生命週期管理。

部署階段

服務提供者在指定端口暴露服務,並向註冊中心註冊服務信息。

服務消費者向註冊中心發起服務地址列表的訂閱。

運行階段

註冊中心向服務消費者推送地址列表信息。

服務消費者收到地址列表後,從其中選取一個向目標服務發起調用。

調用過程服務消費者和服務提供者的運行狀態上報給監控中心。

基於 API 的 Dubbo 應用

Dubbo 的應用通常都是經過 Spring 來組裝的。爲了快速得到一個能夠工做的 Dubbo 應用,這裏的示例摒棄了複雜的配置,而改用面向 Dubbo API 的方式來構建服務提供者和消費者,另外,註冊中心和監控中心在本示例中也不須要安裝和配置。

在生產環境,Dubbo 的服務須要一個分佈式的服務註冊中心與之配合,好比,ZooKeeper。爲了方便開發,Dubbo 提供了直連[2]以及組播[3]兩種方式,從而避免額外搭建註冊中心的工做。在本例中,將使用組播的方式來完成服務的註冊和發現。

定義服務契約

說明:

定義了一個簡單的服務契約 GreetingsService,其中只有一個方法 sayHi 可供調用,入參是 String 類型,返回值也是 String 類型。

提供契約的實現

說明:

服務提供者須要實現服務契約 GreetingsService 接口。

該實現簡單的返回一個歡迎信息,若是入參是 dubbo,則返回 hi, dubbo。

實現 Dubbo 服務提供方

說明:

建立一個 ServiceConfig 的實例,泛型參數信息是服務接口類型,即 GreetingsService。

生成一個 AplicatonConfig 的實例,並將其裝配進 ServiceConfig。

生成一個 RegistryConfig 實例,並將其裝配進 ServiceConfig,這裏使用的是組播方式,參數是 multicast://224.5.6.7:1234。合法的組播地址範圍爲:224.0.0.0 - 239.255.255.255

將服務契約 GreetingsService 裝配進 ServiceConfig。

將服務提供者提供的實現 GreetingsServiceImpl 的實例裝配進 ServiceConfig。

ServiceConfig 已經具有足夠的信息,開始對外暴露服務,默認監聽端口是 20880。

爲了防止服務端退出,按任意鍵或者 ctrl-c 退出。

在這裏順便給你們推薦一個架構交流羣:617434785,裏面會分享一些資深架構師錄製的視頻錄像

實現 Dubbo 服務調用方

說明:

建立一個 ReferenceConfig 的實例,一樣,泛型參數信息是服務接口類型,即 GreetingService。

生成一個 AplicatonConfig 的實例,並將其裝配進 ReferenceConfig。

生成一個 RegistryConfig 實例,並將其裝配進 ReferenceConfig,注意這裏的組播地址信息須要與服務提供方的相同。

將服務契約 GreetingsService 裝配進 ReferenceConfig。

從 ReferenceConfig 中獲取到 GreetingService 的代理。

經過 GreetingService 的代理髮起遠程調用,傳入的參數爲 dubbo。

打印返回結果 hi, dubbo。

運行

完整的示例:

https://github.com/dubbo/dubbo-samples/tree/master/dubbo-samples-api 

在完整的示例中,因爲配置了 exec-maven-plugin,能夠很方便的在命令行下經過 maven 的方式執行。固然,您也能夠在 IDE 裏直接執行,可是須要注意的是,因爲使用了組播的方式來發現服務,運行時須要指定:

 -Djava.net.preferIPv4Stack=true。

★ 構建示例

經過如下的命令來同步示例代碼並完成構建:

同步代碼:git clone https://github.com/dubbo/dubbo-samples.git

構建:mvn clean package

當看到 BUILD SUCCESS 的時候代表構建完成,下面就能夠開始進入運行階段了。

★ 運行服務端

經過運行如下的 maven 命令來啓動服務提供者:

當 first-dubbo-provider is running. 出現時,表明服務提供者已經啓動就緒,等待客戶端的調用。

★ 運行客戶端

經過運行如下的 maven 命令來調用服務:

能夠看到, hi, dubbo 是從服務提供者返回的執行結果。

快速生成 Dubbo 應用

Dubbo 還提供了一個公共服務快速搭建基於 Spring Boot 的 Dubbo 應用。訪問 http://start.dubbo.io 並按照下圖所示來生成示例工程:

說明:

在 Group 中提供 maven groupId,默認值是 com.example。

在 Artifact 中提供 maven artifactId,默認值是 demo。

在 DubboServiceName 中提供服務名,默認值是 com.example.HelloService。

在 DubboServiceVersion 中提供服務的版本,默認值是 1.0.0。

在 Client/Server 中選取本次構建的工程是服務提供者 (Server) 仍是服務消費者 (Client),默認值是 server。

使用 embeddedZookeeper 做爲服務註冊發現,默認爲勾選。

是否激活 qos 端口,默認爲不勾選,若是勾選能夠經過 22222 端口訪問。

點擊 Generate Project 便可下載生成好的工程。

在本例中展現的是服務提供者,一樣的,經過在生成界面選取 client 來生成對應的服務消費者。

★ 運行

用 IDE 打開生成好的工程,能夠發現應用是一個典型的 Spring Boot 應用。程序的入口以下所示:

說明:

在 2181 端口上啓動嵌入式 ZooKeeper。

啓動 Spring Boot 上下文。

能夠直接在 IDE 中運行,輸出結果以下:

2018-05-28 16:59:38.072 INFO 59943 --- [           main] a.b.d.c.e.WelcomeLogoApplicationListener : 

:: Dubbo Spring Boot (v0.1.0) : https://github.com/dubbo/dubbo-spring-boot-project

:: Dubbo (v2.0.1) : https://github.com/alibaba/dubbo

:: Google group : http://groups.google.com/group/dubbo

...

2018-05-28 16:59:39.624 INFO 59943 --- [           main] com.example.demo.DemoApplication : Started DemoApplication in 1.746 seconds (JVM running for 2.963)

說明:

輸出中打印的以 dubbo. 開頭的配置信息,定義在 main/resources/application.properties 中。

★ 經過 Telnet 管理服務

生成工程的時候若是選擇了激活 qos 的話,就能夠經過 telnet 或者 nc 來管理服務、查看服務狀態。

目前 qos 支持如下幾個命令,更詳細的信息請查閱官方文檔[4]:

ls:列出消費者、提供者信息

online:上線服務

offline:下線服務

help:聯機幫助

總結

在本文中,從 RMI 開始,介紹了 Java 領域分佈式調用的基本概念,也就是基於接口編程、經過代理將遠程調用假裝成本地、經過註冊中心完成服務的註冊和發現。

而後爲了簡單起見,使用簡單的組播註冊方式和直接面向 Dubbo API 編程的方式介紹瞭如何開發一個 Dubbo 的完整應用。深刻的瞭解 ServiceConfig 和 ReferenceConfig 的用法,對於進一步的使用 Spring XML 配置、乃至 Spring Boot 的編程方式有這很大的幫助。

最後,簡單的介紹瞭如何經過 Dubbo 團隊提供的公共服務 start.dubbo.io 快速搭建基於 Spring Boot 的 Dubbo 應用,並經過 qos 來作 Dubbo 服務的簡單運維。

相關文章
相關標籤/搜索