1. 程式人生 > >沉澱再出發:dubbo服務治理和應用例項

沉澱再出發:dubbo服務治理和應用例項

沉澱再出發:dubbo服務治理和應用例項

一、前言

    阿里開發的dubbo作為服務治理的工具,在分散式開發中有著重要的意義,這裡我們主要專注於dubbo的架構,基本原理以及在Windows下面開發出來的例項來解釋和介紹,從而使得dubbo不再神祕。

二、dubbo的架構和原理

 2.1、dubbo的架構

    Dubbo框架設計一共劃分了10個層,而最上面的Service層留給實際想要使用Dubbo開發分散式服務的開發者實現業務邏輯的介面層。左邊淡藍背景的為服務消費方使用的介面,右邊淡綠色背景的為服務提供方使用的介面, 位於中軸線上的為雙方都用到的介面。


   各個層次的設計要點:

 1     服務介面層(Service):該層是與實際業務邏輯相關的,根據服務提供方和服務消費方的業務設計對應的介面和實現。
 2     配置層(Config):對外配置介面,以ServiceConfig和ReferenceConfig為中心,可以直接new配置類,也可以通過spring解析配置生成配置類。
 3     服務代理層(Proxy):服務介面透明代理,生成服務的客戶端Stub和伺服器端Skeleton,以ServiceProxy為中心,擴充套件介面為ProxyFactory。
 4     服務註冊層(Registry):封裝服務地址的註冊與發現,以服務URL為中心,擴充套件介面為RegistryFactory、Registry和RegistryService。可能沒有服務註冊中心,此時服務提供方直接暴露服務。
5 叢集層(Cluster):封裝多個提供者的路由及負載均衡,並橋接註冊中心,以Invoker為中心,擴充套件介面為Cluster、Directory、Router和LoadBalance。將多個服務提供方組合為一個服務提供方,實現對服務消費方來透明,只需要與一個服務提供方進行互動。 6 監控層(Monitor):RPC呼叫次數和呼叫時間監控,以Statistics為中心,擴充套件介面為MonitorFactory、Monitor和MonitorService。 7 遠端呼叫層(Protocol):封將RPC呼叫,以Invocation和Result為中心,擴充套件介面為Protocol、Invoker和Exporter。Protocol是服務域,它是Invoker暴露和引用的主功能入口,它負責Invoker的生命週期管理。Invoker是實體域,它是Dubbo的核心模型,其它模型都向它靠擾,或轉換成它,它代表一個可執行體,可向它發起invoke呼叫,它有可能是一個本地的實現,也可能是一個遠端的實現,也可能一個叢集實現。
8 資訊交換層(Exchange):封裝請求響應模式,同步轉非同步,以Request和Response為中心,擴充套件介面為Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。 9 網路傳輸層(Transport):抽象mina和netty為統一介面,以Message為中心,擴充套件介面為Channel、Transporter、Client、Server和Codec。 10 資料序列化層(Serialize):可複用的一些工具,擴充套件介面為Serialization、 ObjectInput、ObjectOutput和ThreadPool。

    Dubbo對於服務提供方和服務消費方,從框架的10層中分別提供了各自需要關心和擴充套件的介面,構建整個服務生態系統(服務提供方和服務消費方本身就是一個以服務為中心的)。

1     在RPC中,Protocol是核心層,也就是隻要有Protocol + Invoker + Exporter就可以完成非透明的RPC呼叫,然後在Invoker的主過程上Filter攔截點。
2     Consumer和Provider是抽象概念,只是想讓看圖者更直觀的瞭解哪些類分屬於客戶端與伺服器端,不用Client和Server的原因是Dubbo在很多場景下都使用Provider、Consumer、Registry、Monitor劃分邏輯拓普節點,保持統一概念。
3     而Cluster是外圍概念,所以Cluster的目的是將多個Invoker偽裝成一個Invoker,這樣其它人只要關注Protocol層Invoker即可,加上Cluster或者去掉Cluster對其它層都不會造成影響,因為只有一個提供者時,是不需要Cluster的。
4     Proxy層封裝了所有介面的透明化代理,而在其它層都以Invoker為中心,只有到了暴露給使用者使用時,才用Proxy將Invoker轉成介面,或將介面實現轉成Invoker,也就是去掉Proxy層RPC是可以Run的,只是不那麼透明,不那麼看起來像調本地服務一樣調遠端服務。
5     而Remoting實現是Dubbo協議的實現,如果你選擇RMI協議,整個Remoting都不會用上,Remoting內部再劃為Transport傳輸層和Exchange資訊交換層,Transport層只負責單向訊息傳輸,是對Mina、Netty、Grizzly的抽象,它也可以擴充套件UDP傳輸,而Exchange層是在傳輸層之上封裝了Request-Response語義。
6     Registry和Monitor實際上不算一層,而是一個獨立的節點,只是為了全域性概覽,用層的方式畫在一起。

 2.2、Dubbo核心要點

  服務定義

     服務是圍繞服務提供方和服務消費方的,服務提供方實現服務,而服務消費方呼叫服務。

  服務註冊

    對於服務提供方,它需要釋出服務,而且由於應用系統的複雜性,服務的數量、型別也不斷膨脹;對於服務消費方,它最關心如何獲取到它所需要的服務,而面對複雜的應用系統,需要管理大量的服務呼叫。而且,對於服務提供方和服務消費方來說,他們還有可能兼具這兩種角色,即既需要提供服務,有需要消費服務。通過將服務統一管理起來,可以有效地優化內部應用對服務釋出/使用的流程和管理。服務註冊中心可以通過特定協議來完成服務對外的統一。Dubbo提供的註冊中心有如下幾種型別可供選擇: Multicast註冊中心、Zookeeper註冊中心、Redis註冊中心、Simple註冊中心。

  服務監控

   無論是服務提供方,還是服務消費方,他們都需要對服務呼叫的實際狀態進行有效的監控,從而改進服務質量。

 遠端通訊與資訊交換   

   遠端通訊需要指定通訊雙方所約定的協議,在保證通訊雙方理解協議語義的基礎上,還要保證高效、穩定的訊息傳輸。Dubbo繼承了當前主流的網路通訊框架,主要包括如下幾個:Mina、Netty、Grizzly

 服務呼叫

1     服務提供方釋出服務到服務註冊中心;
2     服務消費方從服務註冊中心訂閱服務;
3     服務消費方呼叫已經註冊的可用服務

 註冊/登出服務

    服務的註冊與登出,是對服務提供方角色而言:

 服務訂閱/取消

    為了滿足應用系統的需求,服務消費方的可能需要從服務註冊中心訂閱指定的有服務提供方釋出的服務,在得到通知可以使用服務時,就可以直接呼叫服務。反過來,如果不需要某一個服務了,可以取消該服務。

 2.3、協議支援

   Dubbo支援多種協議,如下所示:

1     Dubbo協議
2     Hessian協議
3     HTTP協議
4     RMI協議
5     WebService協議
6     Thrift協議
7     Memcached協議
8     Redis協議

    在通訊過程中,不同的服務等級一般對應著不同的服務質量,那麼選擇合適的協議便是一件非常重要的事情。可以根據你應用的建立來選擇。例如,使用RMI協議,一般會受到防火牆的限制,所以對於外部與內部進行通訊的場景,就不要使用RMI協議,而是基於HTTP協議或者Hessian協議。

 2.4、dubbo的包結構

1     dubbo-common 公共邏輯模組,包括Util類和通用模型。
2     dubbo-remoting 遠端通訊模組,相當於Dubbo協議的實現,如果RPC用RMI協議則不需要使用此包。
3     dubbo-rpc 遠端呼叫模組,抽象各種協議,以及動態代理,只包含一對一的呼叫,不關心叢集的管理。
4     dubbo-cluster 叢集模組,將多個服務提供方偽裝為一個提供方,包括:負載均衡、容錯、路由等,叢集的地址列表可以是靜態配置的,也可以是由註冊中心下發。
5     dubbo-registry 註冊中心模組,基於註冊中心下發地址的叢集方式,以及對各種註冊中心的抽象。
6     dubbo-monitor 監控模組,統計服務呼叫次數,呼叫時間的,呼叫鏈跟蹤的服務。
7     dubbo-config 配置模組,是Dubbo對外的API,使用者通過Config使用Dubbo,隱藏Dubbo所有細節。
8     dubbo-container 容器模組,是一個Standalone的容器,以簡單的Main載入Spring啟動,因為服務通常不需要Tomcat/JBoss等Web容器的特性,沒必要用Web容器去載入服務。

三、dubbo的應用例項

    這裡我們使用windows10作業系統,在Windows上面安裝zookeeper,這個在我們之前的部落格上已經安裝過了,可以檢視沉澱再出發:kafka初探來進行安裝。因為dubbo的執行需要zookeeper的參與。開發工具我們使用IDEA,建立maven工程的方式,下面言歸正傳。

 3.1、建立空的maven工程

    然後生成空白的maven工程,如果有src資料夾則直接刪除就可以了。

 接下來最重要的一步,修改其中的pom.xml檔案:

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 
  3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5     <modelVersion>4.0.0</modelVersion>
  6 
  7     <groupId>com.zyr</groupId>
  8     <artifactId>dubbo_demo</artifactId>
  9     <packaging>pom</packaging>
 10     <version>1.0-SNAPSHOT</version>
 11     <!--POM是最簡單的打包型別。不像一個JAR,SAR,或者EAR,它生成的構件只是它本身。-->
 12     <!--沒有程式碼需要測試或者編譯,也沒有資源需要處理-->
 13     <!--pom 專案裡沒有java程式碼,也不執行任何程式碼,只是為了聚合工程或傳遞依賴用的。-->
 14     <properties>
 15         <motan.version>0.3.0</motan.version>
 16         <dubbo.version>2.5.3</dubbo.version>
 17         <dubbox.version>2.8.4</dubbox.version>
 18         <spring.version>4.3.6.RELEASE</spring.version>
 19         <java.version>1.8</java.version>
 20         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 21     </properties>
 22 
 23     <dependencies>
 24         <dependency>
 25             <groupId>com.alibaba</groupId>
 26             <artifactId>dubbo</artifactId>
 27             <version>2.5.3</version>
 28             <exclusions>
 29                 <exclusion>
 30                     <groupId>org.springframework</groupId>
 31                     <artifactId>spring</artifactId>
 32                 </exclusion>
 33             </exclusions>
 34         </dependency>
 35         <dependency>
 36             <groupId>com.github.sgroschupf</groupId>
 37             <artifactId>zkclient</artifactId>
 38             <version>0.1</version>
 39         </dependency>
 40         <!-- spring相關 -->
 41         <dependency>
 42             <groupId>org.springframework</groupId>
 43             <artifactId>spring-core</artifactId>
 44             <version>${spring.version}</version>
 45         </dependency>
 46         <dependency>
 47             <groupId>org.springframework</groupId>
 48             <artifactId>spring-beans</artifactId>
 49             <version>${spring.version}</version>
 50         </dependency>
 51         <dependency>
 52             <groupId>org.springframework</groupId>
 53             <artifactId>spring-context</artifactId>
 54             <version>${spring.version}</version>
 55         </dependency>
 56         <dependency>
 57             <groupId>org.springframework</groupId>
 58             <artifactId>spring-jdbc</artifactId>
 59             <version>${spring.version}</version>
 60         </dependency>
 61         <dependency>
 62             <groupId>org.springframework</groupId>
 63             <artifactId>spring-web</artifactId>
 64             <version>${spring.version}</version>
 65         </dependency>
 66         <dependency>
 67             <groupId>org.springframework</groupId>
 68             <artifactId>spring-webmvc</artifactId>
 69             <version>${spring.version}</version>
 70         </dependency>
 71         <dependency>
 72             <groupId>org.springframework</groupId>
 73             <artifactId>spring-aop</artifactId>
 74             <version>${spring.version}</version>
 75         </dependency>
 76         <dependency>
 77             <groupId>org.springframework</groupId>
 78             <artifactId>spring-tx</artifactId>
 79             <version>${spring.version}</version>
 80         </dependency>
 81         <dependency>
 82             <groupId>org.springframework</groupId>
 83             <artifactId>spring-orm</artifactId>
 84             <version>${spring.version}</version>
 85         </dependency>
 86         <dependency>
 87             <groupId>org.springframework</groupId>
 88             <artifactId>spring-context-support</artifactId>
 89             <version>${spring.version}</version>
 90         </dependency>
 91         <dependency>
 92             <groupId>org.springframework</groupId>
 93             <artifactId>spring-test</artifactId>
 94             <version>${spring.version}</version>
 95         </dependency>
 96         <dependency>
 97             <groupId>org.springframework</groupId>
 98             <artifactId>spring-jms</artifactId>
 99             <version>${spring.version}</version>
100         </dependency>
101         <dependency>
102             <groupId>org.aspectj</groupId>
103             <artifactId>aspectjrt</artifactId>
104             <version>1.6.11</version>
105         </dependency>
106         <dependency>
107             <groupId>org.aspectj</groupId>
108             <artifactId>aspectjweaver</artifactId>
109             <version>1.6.11</version>
110         </dependency>
111         <!-- https://mvnrepository.com/artifact/junit/junit -->
112         <dependency>
113             <groupId>junit</groupId>
114             <artifactId>junit</artifactId>
115             <version>4.12</version>
116             <scope>test</scope>
117         </dependency>
118 
119     </dependencies>
120 
121     <modules>
122         <module>dubbo_api</module>
123         <module>dubbo_provider</module>
124         <module>dubbo_consumer</module>
125     </modules>
126 </project>

   這裡要注意,後面的<modules>中的內容,我們正要建立,因此會提示錯誤的資訊,我們暫時不用管就可以了,等建立之後就能正常識別了。或者我們先不寫這些東西,當後面的模組的pom.xml繼承了這個pom.xml的時候就會自動新增進去了

 3.2、在空的工程裡面建立API模組

   其實我們只用建立生產者和消費者就可以了,但是為了更高層次的封裝,我們將生產者提供的服務給暴露出來,用統一的模組來顯示,於是就有了API模組。右鍵點選專案“dubbo_demo”,然後新建“Module”,在模組中我們同樣使用快速模板。

 

     可以看到這個子模組已經預設的將空專案的pom.xml當成了父pom.xml。

 

   之後生成子專案:

  我們修改dubbo_api的pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>dubbo_demo</artifactId>
 7         <groupId>com.zyr</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>dubbo_api</artifactId>
13     <packaging>jar</packaging>
14 
15 </project>

  同時定義需要暴露的服務介面:DemoService.java

1 package com.api.service;
2 
3 /**
4  * 定義服務介面
5  */
6 public interface DemoService {
7     String sayHello(String name);
8 }

   至此這個模組暫時配置完成。

 3.3、繼續在原工程裡面建立provider模組

   同樣的我們需要建立生產者和消費者模組,這裡先建立生產者模組,方式和前面的一樣,名字改為dubbo_provider:

 然後我們修改dubbo_provider的pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>dubbo_demo</artifactId>
 7         <groupId>com.zyr</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10 
11     <modelVersion>4.0.0</modelVersion>
12 
13     <artifactId>dubbo_provider</artifactId>
14 
15     <dependencies>
16         <dependency>
17             <groupId>com.zyr</groupId>
18             <artifactId>dubbo_api</artifactId>
19             <version>1.0-SNAPSHOT</version>
20             <scope>compile</scope>
21         </dependency>
22     </dependencies>
23 </project>

    最後新增的依賴,就是為了要使用其中的介面的,這樣就能連通了,同樣的我們還是繼承自空檔案的pom.xml,這樣就可以使用其中的依賴了,這種方式我們需要仔細的學習,在大型的工程之中是非常有用的。

   然後建立服務的實現類:DemoServiceImpl

 1 package com.provider.service;
 2 
 3 import com.api.service.DemoService;
 4 
 5 public class DemoServiceImpl  implements DemoService {
 6     public String sayHello(String name) {
 7         System.out.println("服務端接收到消費端的呼叫,開始處理...");
 8         return "處理之後:Hello "+name;
 9     }
10 }

   然後我們建立一個測試檔案:ProviderTest.java

 1 package com.provider.test;
 2 
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 
 5 import java.io.IOException;
 6 
 7 public class ProviderTest {
 8     public static void main(String[] args) {
 9         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:springmvc.xml");
10         context.start();
11 
12         System.out.println("Dubbo provider start...");
13 
14         try {
15             System.in.read();   // 按任意鍵退出
16             System.out.println("生產者退出...");
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20     }
21 }

   另外,我們這裡就需要配置屬於服務者的xml檔案了,這裡也是專案中非常重要的一點。在我們使用IntelliJ IDEA建立maven專案的時候,預設情況下是沒有給專案建立resources資料夾的,這個資料夾裡面是為了存放.xml配置檔案等其他資原始檔的,如果我們要使用classpath來定位這些xml檔案,我們必須把這些檔案放到resources資料夾下面去,這樣系統在編譯的時候就會找到這些檔案,將編譯之後的檔案放到target/classes資料夾下面

 建立resources資料夾並賦予資原始檔夾屬性

    問題是怎麼建立resources資料夾呢,有的人說直接在相應的目錄建立就行了,這一點肯定是錯誤的,就算我們建立了,IDEA也不會認可的,因此我們需要通過IDEA的法定途徑來讓IDEA承認

   我們從File-》Project Structure這個裡面進行定義資料夾的性質:

    首先我們找到需要定義resources的位置,也就是main下面,點選main右鍵,新建資料夾,寫入resources,然後建立:

   建立之後,我們將該資料夾賦予相應的性質,點選resources資料夾,並且點選上面的Resources,這樣在右邊我們就能看到系統認可了這個資原始檔夾

    使用同樣的方式,我們還可以定義其他的資料夾,甚至改變src的屬性,但是這樣之後,我們可能在工程中看不到裡面的底層檔案了,這個功能特別的有意思。

    改變了之後,我們就可以新建xml檔案了:

 建立dubbo-provider.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
 5        xsi:schemaLocation="http://www.springframework.org/schema/beans
 6     http://www.springframework.org/schema/beans/spring-beans.xsd
 7     http://code.alibabatech.com/schema/dubbo
 8     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
 9 
10     <!-- 提供方應用資訊,用於計算依賴關係 -->
11     <dubbo:application name="dubbo_provider"  />
12 
13     <!-- 使用zookeeper註冊中心暴露服務地址 -->
14     <dubbo:registry address="zookeeper://127.0.0.1:2181" />
15 
16     <!-- 用dubbo協議在20880埠暴露服務 -->
17     <dubbo:protocol name="dubbo" port="20880" />
18 
19     <!-- 宣告需要暴露的服務介面 -->
20     <dubbo:service interface="com.api.service.DemoService" ref="demoService" />
21 
22     <!-- 介面實現類-->
23     <bean id="demoService" class="com.provider.service.DemoServiceImpl"/>
24 
25 </beans>

 建立springmvc.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
 3        xmlns:context="http://www.springframework.org/schema/context"
 4        xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5        xsi:schemaLocation="http://www.springframework.org/schema/aop
 6         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
 7         http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 9         http://www.springframework.org/schema/context
10         http://www.springframework.org/schema/context/spring-context-4.0.xsd"
11        default-autowire="byName">
12 
13     <aop:aspectj-autoproxy />
14     <context:component-scan base-package="com" />
15     <import resource="classpath:dubbo-provider.xml" />
16 </beans>

   至此,provider模組設定完畢。

 3.4、繼續在原工程裡面建立consumer模組

   同樣的,我們建立模組之後,修改pom.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <parent>
 6         <artifactId>dubbo_demo</artifactId>
 7         <groupId>com.zyr</groupId>
 8         <version>1.0-SNAPSHOT</version>
 9     </parent>
10     <modelVersion>4.0.0</modelVersion>
11 
12     <artifactId>dubbo_consumer</artifactId>
13 
14     <dependencies>
15         <dependency>
16             <groupId>com.zyr</groupId>
17             <artifactId>dubbo_api</artifactId>
18             <version>1.0-SNAPSHOT</version>
19             <scope>compile</scope>
20         </dependency>
21     </dependencies>
22 </project>

 然後我們新建一個測試檔案:ConsumerTest.java

 1 package com.consumer.test;
 2 
 3 import com.api.service.DemoService;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import java.io.IOException;
 7 
 8 public class ConsumerTest {
 9     public static void main(String[] args) {
10         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] { "classpath:springmvc.xml" });
11 
12         context.start();
13         DemoService demoService = (DemoService) context.getBean("demoService");
14 
15         System.out.println("消費端準備呼叫遠端生產者的服務...");
16         System.out.println(demoService.sayHello("我是朱彥榮,來自消費端,呼叫遠端服務端程式..."));
17         try {
18             System.in.read();
19         } catch (IOException e) {
20             e.printStackTrace();
21         }
22     }
23 }

  新建resources檔案,加入xml:

  dubbo-consumer.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
 4        xsi:schemaLocation="http://www.springframework.org/schema/beans
 5         http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://code.alibabatech.com/schema/dubbo
 7         http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
 8     <!-- 消費方應用名,用於計算依賴關係,不是匹配條件,不要與提供方一樣 -->
 9     <dubbo:application name="dubbo_consumer" />
10     <!-- 使用multicast廣播註冊中心暴露發現服務地址 -->
11     <dubbo:registry  protocol="zookeeper" address="zookeeper://127.0.0.1:2181" />
12     <!-- 生成遠端服務代理,可以和本地bean一樣使用demoService -->
13     <dubbo:reference id="demoService" interface="com.api.service.DemoService" />
14 </beans>

   springmvc.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
 3        xmlns:context="http://www.springframework.org/schema/context"
 4        xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5        xsi:schemaLocation="http://www.springframework.org/schema/aop
 6         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
 7         http://www.springframework.org/schema/beans
 8         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 9         http://www.springframework.org/schema/context
10         http://www.springframework.org/schema/context/spring-context-4.0.xsd"
11        default-autowire="byName">
12 
13     <aop:aspectj-autoproxy />
14     <context:component-scan base-package="com" />
15     <import resource="classpath:dubbo-consumer.xml" />
16 </beans>

    至此我們完成了三個模組的配置,然後我們進入主pom.xml中,看看確實已經自動加入了module,因此刪除之前新增的(不重複的話無需刪除)即可。

 

 3.5、整個專案的結構

 3.6、執行測試

 首先我們執行zookeeper,在命令列輸入zkServer即可(需要配置環境變數):

 其次,我們先執行provider模組:

 

  最後,我們執行consumer模組:

     當有多個客戶端呼叫的時候:

   這樣,我們就實現了dubbo的服務通訊,生產者生產服務釋出到zookeeper上面,消費者通過相應的地址去獲取服務並且使用,這就是dubbo的工作方式了。

四、總結

    通過我們對dubbo的理解,以及使用對dubbo進行的實驗測試,我們掌握了dubbo的基本的功能,可以發現dubbo非常類似於wcf的概念,同樣也是釋出服務,客戶端使用服務,由此可以看到生產者,消費者,註冊者,這三個東西結合起來組成的SOA架構非常的有用。

參考文獻:https://blog.csdn.net/crazer_cy/article/details/80397649