Dubbo:專案構建過程與所需元件介紹
1 SOA : Service-Oriented Architecture 2
2 RPC : Remote Procedure Call Protocol 2
Dubbo第一天
- SOA : Service-Oriented Architecture
面向服務的架構(SOA)是一個元件模型,它將應用程式的不同功能單元(稱為服務)通過這些服務之間定義良好的介面和契約聯絡起來。介面是採用中立的方式進行定義的,它應該獨立於實現服務的硬體平臺、作業系統和程式語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行互動。
面向服務架構,它可以根據需求通過網路對鬆散耦合的粗粒度應用元件進行分散式部署、組合和使用。服務層是SOA的基礎,可以直接被應用呼叫,從而有效控制系統中與軟體代理互動的人為依賴性。
SOA是一種粗粒度、鬆耦合服務架構,服務之間通過簡單、精確定義介面進行通訊,不涉及底層程式設計介面和通訊模型。SOA可以看作是B/S模型、XML(標準通用標記語言的子集)/Web Services技術之後的自然延伸。
SOA將能夠幫助軟體工程師們站在一個新的高度理解企業級架構中的各種元件的開發、部署形式,它將幫助企業系統架構者以更迅速、更可靠、更具重用性架構整個業務系統。較之以往,以SOA架構的系統能夠更加從容地面對業務的急劇變化。
- RPC : Remote Procedure Call Protocol
遠端過程呼叫協議,它是一種通過網路從遠端計算機程式上請求服務,而不需要了解底層網路技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,為通訊程式之間攜帶資訊資料。在OSI網路通訊模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網路分散式多程式在內的應用程式更加容易。
RPC採用客戶機/伺服器模式。請求程式就是一個客戶機,而服務提供程式就是一個伺服器。首先,客戶機呼叫程序傳送一個有程序引數的呼叫資訊到服務程序,然後等待應答資訊。在伺服器端,程序保持睡眠狀態直到呼叫資訊到達為止。當一個呼叫資訊到達,伺服器獲得程序引數,計算結果,傳送答覆資訊,然後等待下一個呼叫資訊,最後,客戶端呼叫程序接收答覆資訊,獲得程序結果,然後呼叫執行繼續進行。
OSI是Open System Interconnection的縮寫,意為開放式系統互聯。國際標準化組織(ISO)制定了OSI模型,該模型定義了不同計算機互聯的標準,是設計和描述計算機網路通訊的基本框架。OSI模型把網路通訊的工作分為7層,分別是物理層、資料鏈路層、網路層、傳輸層、會話層、表示層和應用層。
Dubbo是阿里巴巴開發的一個基於SOA結構基礎的,實現RPC遠端呼叫的框架.
Dubbo框架,是基於容器執行的. 容器是Spring.
在編寫服務和客戶端的時候, 需要註冊中心實現服務的釋出和訂閱. 註冊中心中有服務端釋出的服務全部資訊,包括請求地址,引數命名,引數數量,引數限制,引數是否加密等. 客戶端通過註冊中心訂閱服務,獲取服務的所有資訊,實現RPC遠端訪問.
官方網站 : http://dubbo.io/
阿里巴巴已經將dubbo框架捐獻給了Apache軟體基金會.
註冊中心. 是用於釋出和訂閱服務的一個平臺.
開發服務端程式碼完畢後, 將服務資訊釋出出去. 實現一個服務的公開.
釋出的資訊包括但不限於: 服務端所在位置(URL), 要呼叫的介面命名, 介面中有什麼方法, 方法需要什麼引數, 方法有什麼返回, 呼叫過程超時時長是多少, 呼叫過程自動重複多少次, 引數資料和返回資料長度有多少等.
客戶端程式,從註冊中心下載服務內容, 就是釋出的服務資訊. 這個過程是訂閱.
訂閱服務的時候, 會將釋出的服務所有資訊,一次性下載到客戶端.
客戶端也可以自定義, 修改部分服務資訊. 如: 超時的時長, 呼叫的重複次數等.
服務的消費者, 就是服務的客戶端.
消費者必須使用Dubbo技術開發部分程式碼. 基本上都是配置檔案定義.
服務的提供者, 就是服務端.
服務端必須使用Dubbo技術開發部分程式碼. 以配置檔案為主.
協議. 在Dubbo技術中, 客戶端和伺服器的通訊方式, 都是建立在協議通訊基礎之上的.
dubbo技術支援若干協議. 如: dubbo協議(阿里自主開發的協議), http協議, tcp協議等.
容器. Dubbo技術的服務端(Provider), 在啟動執行的時候, 必須依賴容器才能正常啟動.
預設依賴的就是spring容器. 且Dubbo技術不能脫離spring框架.
在2.5.3版本的dubbo中, 預設依賴的是spring2.5版本技術. 可以選用spring4.5以下版本.
在2.5.7版本的dubbo中, 預設依賴的是spring4.3.10版本技術. 可以選擇任意的spring版本.
監控中心. 是Dubbo提供的一個war工程.
主要功能是監控服務端(Provider)和消費段(Consumer)的使用資料的. 如: 服務端是什麼,有多少介面,多少方法, 呼叫次數, 壓力資訊等. 客戶端有多少, 呼叫過哪些服務端, 呼叫了多少次等. 也可以實現叢集權重的分配.
官方推薦使用的註冊中心.
Zookeeper是apache開發的一個java工程. 是hadoop工程的子工程. 主體功能是用於實現其他應用管理的一個管理平臺.
核心功能是: 管理多應用, 統一管理配置資訊, 名稱管理服務, 分散式鎖等.
管理多應用 : Apache中有若干應用, 如: hadoop, bea, pig等. 這些應用可能同時使用, 需要一個統一的管理平臺, 實現管理.
統一配置 : 在商業開發中, 很可能統一個應用使用多份,如: 多個hadoop. 那麼多個hadoop配置應用統一.
名稱服務管理 : 商業開發中, 應用數量若干. 如: hadoop10個, pig20個, bea30個. 在記憶各個應用位置的時候,非常麻煩. 應用位置: 就是主機名(IP)+埠號. Zookeeper可以為每個應用命名, 類似域名. 方便管理和查詢.
分部鎖 : 如果多個同應用同時使用的時候, 不同客戶端訪問過程,是否有資料錯誤的可能. 如: 有若干hadoop, 客戶端1訪問hadoop1, 新增資料. 客戶端2訪問hadoop2,查詢資料.查詢的結果應該包括新增的資料. 先執行哪一個客戶端請求? 保證資料結果正確性.
-
-
- multicast
-
廣播實現服務釋出和訂閱的註冊方式. 不需要啟動任何的註冊中心平臺.
只適用於小型的專案. 在大型工程中會有通訊阻塞問題.(廣播風暴.)
-
-
- redis
-
KV伺服器. 快取記憶體伺服器. 是一個記憶體結構的類似資料庫的快取伺服器. 也可以稱為NoSQL資料庫.
實際就是通過鍵值對的形式, 在redis中儲存服務的釋出資料. 客戶端通過key查詢value,訂閱服務.
效率高, 且可搭建叢集. 適用部分大型商業開發. 但是穩定性不保證.
tar -zxf xxxx.tar.gz
-
-
-
- 建議複製到/usr/local/目錄中
-
-
cp -r xxx /usr/local/xxx
-
-
-
- 配置環境變數
-
-
vi /etc/profile
內容:
JAVA_HOME=XXX
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME
export CLASSPATH
export PATH
-
-
- 安裝Zookeeper
-
下載位置: zookeeper.apache.org
-
-
-
- 解壓縮
-
-
tar -zxf zookeeper.tar.gz
-
-
-
- 建議複製到/usr/local目錄中
-
-
cp -r zookeeper /usr/local/zookeeper
-
-
-
- 簡介Zookeeper資源
- bin
- 簡介Zookeeper資源
-
-
可執行檔案. 啟動,停止, 狀態檢查, 重啟等功能都通過目錄中的可執行檔案操作.
-
-
-
-
- conf
-
-
-
配置目錄. 儲存所有的配置檔案
-
-
-
-
- lib
-
-
-
就是Zookeeper內容. Zookeeper是java開發的, 實際上就是一組jar包. lib中的jar就是Zookeeper的源資訊.
-
-
-
-
- src
-
-
-
Zookeeper提供的原始碼. java開發的應用,開源免費.
-
-
-
-
- data
-
-
-
臨時資料檔案目錄. 需要自定義. 可以定義在任意位置.
Zookeeper使用的臨時資料檔案目錄, 是通過conf目錄中的配置檔案配置的.
預設是/tmp/zookeeper目錄中的臨時目錄.
目錄中保證Zookeeper執行過程的所有資料資訊. 包括臨時資料和持久化資料.
-
-
-
- 啟動Zookeeper
-
-
執行bin目錄中的可執行檔案
zkServer.sh start
啟動後, 會有日誌檔案建立. 其中儲存啟動日誌. zookeeper.out
如果啟動失敗, 則在日誌檔案中有對應的異常堆疊資訊.
-
-
-
- 停止
-
-
zkServer.sh stop
-
-
-
- 狀態檢視
-
-
zkServer.sh status
成功啟動狀態資訊
啟動失敗的狀態資訊
-
-
-
- 重啟
-
-
zkServer.sh restart
-
-
- 客戶端訪問
-
使用Zookeeper提供的預設客戶端本地訪問.
bin/zkCli.sh
預設連線本地服務, 埠為2181.
指定連線
bin/zkCli.sh -server ip:port
客戶端命令 : Zookeeper提供了命令提示. 輸入任意字元回車後有提示資訊.
服務提供者開始編寫. 首先開發服務的提供者, 再次釋出服務. 最後由服務消費者呼叫服務.
<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"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>dubbo-provider</artifactId> <version>1.0</version> <dependencies>
<!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.7</version> </dependency> <!-- zookeeper客戶端 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
</dependencies> </project> |
-
-
- 程式碼
- 介面
- 程式碼
-
package com.bjsxt.service;
public interface UserService {
void register(String name, String password);
void login(String name, String password);
}
|
-
-
-
- 實現類
-
-
package com.bjsxt.service.impl;
import org.springframework.stereotype.Service;
import com.bjsxt.service.UserService;
/** * 不考慮dubbo的任何問題. 正常開發 * 只考慮spring管理的問題. * spring容器管理服務物件. * 1. bean標籤管理 * 2. 註解管理 * 使用註解管理, 容易導包錯誤. Dubbo也提供了service註解. 但是dubbo的service註解 * 有程式碼衝突. 在大多數情況下. 和spring-context, spring-tx有衝突. * Dubbo的service註解, 在2.5.3版本中(使用spring2.5)註解無衝突. */
@Service public class UserServiceImpl implements UserService {
@Override public void register(String name, String password) { System.out.println("register : " + name + " ; " + password); }
@Override public void login(String name, String password) { System.out.println("login : " + name + " ; " + password); }
}
|
描述自定義的Provider和註冊中心的資訊.
本地開發的服務程式碼是什麼, 註冊中心種類和位置是什麼.
dubbo沒有自定義的配置檔案. 使用的都是spring的配置檔案.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- dubbo配置. Dubbo的配置資訊,必須匯入新的namespace. namespace可以通過dubbo的jar包查詢. 配置檔案的約束資訊所在位置: dubbo.jar/META-INF/dubbo.xsd --> <!-- 1. 配置dubbo的應用名稱, 是為一個Dubbo的Provider或Consumer在註冊中心中定義唯一命名. 且在monitor監控中心中可以根據應用名稱檢視應用統計資訊. --> <dubbo:application name="test-provider-001"/>
<!-- 2. 配置註冊中心. 是定義註冊中心Zookeeper所在的位置和使用的協議. 協議名稱就是zookeeper, 地址是IP:port --> <dubbo:registry address="192.168.120.143:2181" protocol="zookeeper"/>
<!-- 3. 配置協議資訊. 是配置,在釋出的服務中,繫結的協議是什麼. 也就是Consumer使用什麼協議訪問Provider --> <dubbo:protocol name="dubbo" port="20880"/>
<!-- 4. 配置具體的要釋出的服務資訊. 釋出的服務是協議內容. 就是 - 協議://ip:port/介面名稱?方法&引數&其他配置等 釋出的服務, 在訂閱後,必須配合具體的服務的介面,才能使用. 不需要實現類. 釋出的服務雖然是協議內容, 但是必須由具體的要釋出的服務介面的實現類提供服務的實現. 所以需要引用一個有效的service物件. ref - 具體的提供服務的實現類物件. 是spring容器管理的物件. 使用bean物件命名查詢的. interface - 介面. 代表釋出的服務繫結的介面型別是什麼. --> <dubbo:service ref="userServiceImpl" interface="com.bjsxt.service.UserService"/>
<!-- 掃描spring的註解, 建立service物件. --> <context:component-scan base-package="com.bjsxt.service"></context:component-scan>
</beans> |
-
-
- 協議型別
-
Dubbo中支援多種協議. 推薦使用dubbo協議.
-
-
-
- dubbo
-
-
Dubbo預設協議採用單一長連線和NIO非同步通訊,適合於小資料量大併發的服務呼叫,以及服務消費者機器數遠大於服務提供者機器數的情況。
單一長連線 - 客戶端伺服器連線只建立一次. 建立成功後必須訪問結束才斷開.
NIO非同步通訊 - 提高效率的方式. 可以讓客戶端和伺服器同時傳送和接收資料.
限制:
不適合傳遞大資料. 如: 檔案.
使用Dubbo協議的時候, 服務中方法的引數和返回值型別都必須可序列化. 因為Dubbo協議採用tcp+hessian協議配合實現資料傳遞. hessian協議要求必須傳遞的資料都可序列化.
-
-
-
- rmi
-
-
遠端方法呼叫介面. 是JDK定義的遠端呼叫協議. 採用阻塞式短連線和JDK標準序列化方式.
阻塞短連線 - 單一連線過程中, 通訊方式為同步.
不適用於高併發的請求環境. 如: 網際網路.
-
-
-
- hessian
-
-
是http協議的升級版. 是一個建立在http協議基礎上的應用層協議.
要求所有的服務方法引數和返回值型別必須可序列化. 且不能傳遞集合等介面型別的自定義實現類. 傳遞的是自定義的集合介面實現類. 只序列化內容,不序列化方法.
-
-
-
- redis
-
-
是使用redis作為中間過程, 通過redis實現資料通訊的一種方式.
相對較少. 相對的穩定性無法控制.
服務消費者開發. 不需要考慮dubbo問題. 都是通過配置實現dubbo的服務訂閱和應用. 將dubbo中的Provider當做是本地的一個介面應用即可.
將Provider介面作為本地物件應用. 通過spring容器注入代理物件.
代理物件由spring容器+dubbo動態建立.
-
-
- pom檔案
-
<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"> <modelVersion>4.0.0</modelVersion> <groupId>com.bjsxt</groupId> <artifactId>dubbo-consumer</artifactId> <version>1.0</version> <dependencies>
<!-- 需要依賴服務提供者的介面. 配合訂閱的服務資訊,實現代理物件的建立. --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>dubbo-provider</artifactId> <version>1.0</version> </dependency> <!-- dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.7</version> </dependency> <!-- zookeeper客戶端 --> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency>
</dependencies> </project> |
-
-
- 程式碼
- 介面
- 程式碼
-
package com.bjsxt.consumer.service;
public interface UserServiceConsumer {
public void register(String name, String password);
public void login(String name, String password);
}
|
-
-
-
- 實現類
-
-
package com.bjsxt.consumer.service.impl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;
import com.bjsxt.consumer.service.UserServiceConsumer; import com.bjsxt.service.UserService;
/** * 服務消費者程式碼. * 不考慮Dubbo的技術問題. 只考慮當前物件在spring容器中的管理問題. */ @Service public class UserServiceConsumerImpl implements UserServiceConsumer {
// 需要通過spring注入. 注入的是介面的代理物件. 由介面+訂閱的服務資訊+JDK的proxy實現. // 動態代理物件的具體建立邏輯.由Dubbo技術提供. // dubbo技術提供了reference註解, 替代後續定義的標籤. 有程式碼衝突. @Autowired private UserService userService;
@Override public void register(String name, String password) { // 具體邏輯由Provider提供. System.out.println("consumer register run..."); // 呼叫Provider程式碼, 需要定義屬性. 提供物件引用. this.userService.register(name, password); }
@Override public void login(String name, String password) { System.out.println("consumer login run..."); this.userService.login(name, password); }
}
|
核心標籤是: <dubbo:reference interface=”” id=””/>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 1. 配置dubbo應用名 --> <dubbo:application name="test-consumer-001" />
<!-- 2. 配置dubbo的註冊中心 --> <dubbo:registry address="192.168.120.143:2181" protocol="zookeeper" />
<!-- 3. 配置dubbo的訂閱服務內容. 要訂閱哪一個介面服務資訊. Consumer不需要定義協議. 因為協議資訊由服務的提供者定義. reference - 引用, 是要訂閱註冊中心中的服務資訊. 訂閱成功後, 在spring容器中,依賴容器和Dubbo技術,建立代理物件. 建立的代理物件命名為id屬性值. 建議id屬性值命名和Consumer中引用的屬性名一致. interface - 要訂閱的具體的服務介面命名. 就是Provider釋出的服務介面命名. --> <dubbo:reference interface="com.bjsxt.service.UserService" id="userService" />
<!-- 配置掃描spring註解 --> <context:component-scan base-package="com.bjsxt.consumer.service"></context:component-scan>
</beans> |
是Dubbo框架提供的一個Main類. 其中定義了main方法.實現啟動方式.
Dubbo提供的Main中,掃描的配置檔案有固定位置.
配置檔案固定在 classpath:META-INF/spring目錄中.
配置檔案型別必須是xml配置檔案.
package com.bjsxt.test;
import com.alibaba.dubbo.container.Main;
public class TestMain {
public static void main(String[] args) throws Exception {
// 啟動Provider Main.main(args);
// 阻塞 System.in.read();
}
}
|
常用於生產環境使用. 商業專案中最終的使用方式.
打包啟動: 就是將程式碼打包為jar包. 並提供啟動檔案, 如: start.bat, start.sh等. 執行啟動檔案, 自動呼叫Main類中的main方法.
assembly打包,需要在maven中增加新的外掛. 且會修改install功能.
-
-
- 匯入assembly資源
-
資料/assembly/dubbo-monitor-simple-2.5.3/*
複製之前,檢查conf目錄中的*.properties檔案. 清空檔案內容.
Main類預設先查詢conf目錄中的properites配置,再檢查META-INF/spring中的配置.
儲存在工程的根目錄下. 不要儲存在src目錄中.
-
-
- 定義assembly配置資訊
-
提供一個xml配置檔案. 定義assembly配置資訊.
<?xml version='1.0' encoding='UTF-8'?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"> <!-- 該字元會新增到最終tar.gz包的名稱後面,作為字尾 當前應用 : homework-provider-impl 打包後 : homework-provider-impl-assembly.tar.gz --> <id>assembly</id> <!-- 指定打包的格式為tar.gz,該型別壓縮包在linux中比較常見 --> <formats> <format>tar.gz</format> </formats> <!-- 在tar.gz壓縮包中是否包含根資料夾,該根資料夾名稱和tar.gz去掉id字尾一致 --> <includeBaseDirectory>true</includeBaseDirectory> <fileSets> <!-- 將專案根路徑下assembly/bin路徑中的內容打包到壓縮包中的根目錄下的bin目錄中 --> <fileSet> <!-- 相對專案根路徑的相對路徑 --> <directory>assembly/bin</directory> <outputDirectory>bin</outputDirectory> <!-- 設定最終tar.gz中該資料夾下的許可權,跟linux |