Dubbo使用

  【注:本文參考《Dubbo入門---搭建一個最簡單的Demo框架》,感謝原創作者的知識探索與奉獻】

  一.Dubbo背景和簡介
  Dubbo開始於電商系統,因此在這裏先從電商系統的演變講起。
     1.單一應用框架(ORM)
     當網站流量很小時,只需一個應用,將所有功能(如下單支付等)都部署在一起,以減少部署節點和成本。此時,用於簡化增刪改查工作量的 數據訪問框架(ORM) 是關鍵。
     缺點:單一的系統架構,使得在開發過程中,佔用的資源越來越多,而且隨着流量的增加越來越難以維護。

  2.垂直應用框架(MVC)
  垂直應用架構解決了單一應用架構所面臨的擴容問題,流量能夠分散到各個子系統當中,且系統的體積可控,一定程度上降低了開發人員之間協同以及維護的成本,提升了開發效率。此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。
  缺點:垂直架構中相同的邏輯代碼需要不斷的複製,不能複用。

  

  3.分佈式應用架構(RPC)
  當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作爲獨立的服務,逐漸形成穩定的服務中心。此時,用於提高業務複用及整合的 分佈式服務框架(RPC) 是關鍵。

  

RPC(Remote Procedure Call Protocol):遠程過程調用:
兩臺服務器A、B,分別部署不同的應用a,b。當A服務器想要調用B服務器上應用b提供的函數或方法的時候,由於不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義傳達調用的數據。
說白了,就是你在你的機器上寫了一個程序,我這邊是無法直接調用的,這個時候就出現了一個遠程服務調用的概念。

RPC是一種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議。RPC協議假定某些傳輸協議的存在,如TCP或UDP,爲通信程序之間攜帶信息數據。在OSI網絡通信模型中,RPC跨越了傳輸層和應用層。RPC使得開發包括網絡分佈式多程序在內的應用程序更加容易。
RPC採用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然後等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息到達爲止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答覆信息,然後等待下一個調用信息,最後,客戶端調用進程接收答覆信息,獲得進程結果,然後調用執行繼續進行。

RPC需要解決的問題:
    通訊問題 : 主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調用的所有交換的數據都在這個連接裏傳輸。連接可以是按需連接,調用結束後就斷掉,也可以是長連接,多個遠程過程調用共享同一個連接。
    尋址問題 : A服務器上的應用怎麼告訴底層的RPC框架,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱名稱是什麼,這樣才能完成調用。比如基於Web服務協議棧的RPC,就要提供一個endpoint URI,或者是從UDDI服務上查找。如果是RMI調用的話,還需要一個RMI Registry來註冊服務的地址。
    序列化 與 反序列化 : 當A服務器上的應用發起遠程過程調用時,方法的參數需要通過底層的網絡協議如TCP傳遞到B服務器,由於網絡協議是基於二進制的,內存中的參數的值要序列化成二進制的形式,也就是序列化(Serialize)或編組(marshal),通過尋址和傳輸將序列化的二進制發送給B服務器。
    同理,B服務器接收參數要將參數反序列化。B服務器應用調用自己的方法處理後返回的結果也要序列化給A服務器,A服務器接收也要經過反序列化的過程。 

  4.流動計算架構(SOA)
  隨着服務化的進一步發展,服務越來越多,服務之間的調用和依賴關係也越來越複雜,誕生了面向服務的架構體系(SOA),也因此衍生出了一系列相應的技術,如對服務提供、服務調用、連接處理、通信協議、序列化方式、服務發現、服務路由、日誌輸出等行爲進行封裝的服務框。此時,用於提高機器利用率的資源調度和治理中心(SOA) 是關鍵。

   從以上電商系統的演變可以看出架構演變的過程:

  那麼,Dubbo是什麼呢?  

Dubbo是:
    一款分佈式服務框架
    高性能和透明化的RPC遠程服務調用方案
    SOA服務治理方案

   迄今爲止,Dubbo每天爲2千多個服務提供大於30億次訪問量支持,並被廣泛應用於阿里巴巴集團的各成員站點以及別的公司的業務中。

  Dubbo架構:

  

Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與通知的註冊中心。
Monitor: 統計服務的調用次數和調用時間的監控中心。

   調用流程
  ①服務容器負責啓動,加載,運行服務提供者。
  ②服務提供者在啓動時,向註冊中心註冊自己提供的服務。
  ③服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
  ④註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
  ⑤服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
  ⑥服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心  

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

Dubbo提供的註冊中心有如下幾種類型可供選擇:
    Multicast註冊中心
    Zookeeper註冊中心
    Redis註冊中心
    Simple註冊中心

   Dubbo優缺點:

  (1)優點:
     ①透明化的遠程方法調用。可以像調用本地方法一樣調用遠程方法;只需簡單配置,沒有任何API侵入。
     ②軟負載均衡及容錯機制。可在內網替代nginx lvs等硬件負載均衡器。
     ③服務註冊中心自動進行註冊與配置管理。不需要寫死服務提供者地址,註冊中心基於接口名自動查詢提供者ip。    使用類似zookeeper等分佈式協調服務作爲服務註冊中心,可以將絕大部分項目配置移入zookeeper集羣。
     ④服務接口監控與治理。Dubbo-admin與Dubbo-monitor提供了完善的服務接口管理與監控功能,針對不同應用的不同接口,可以進行 多版本,多協議,多註冊中心管理。
  (2)缺點:
     只支持JAVA語言。

  二.Dubbo入門Demo

  在瞭解了Dubbo以後,我們接下來搭建一個簡單的Demo實現。本文采用Dubbo與Zookeeper、Spring框架的整合。

主要是以下幾個步驟:
1. 安裝Zookeeper,啓動;
2. 創建MAVEN項目,構建Dubbo+Zookeeper+Spring實現的簡單Demo;
3. 安裝Dubbo-admin,實現監控。 

   1.安裝Zookeeper  

    Zookeeper是一個分佈式的服務框架,是樹型的目錄服務的數據存儲,能做到集羣管理數據 ,這裏能很好的作爲Dubbo服務的註冊中心。
    Dubbo能與Zookeeper做到集羣部署,當提供者出現斷電等異常停機時,Zookeeper註冊中心能自動刪除提供者信息,當提供者重啓時,能自動恢復註冊數據,以及訂閱請求

   首先,我在VMware上安裝了cent os6.9(64位),然後通過SecureCRT遠程操作cent os,將Zookeeper安裝到cent os中。

  【此處假定該cent os所在機器的ip爲:192.168.1.28】

[root@bogon ~]# pwd
/root
[root@bogon ~]# mkdir dubbotest
[root@bogon ~]# cd dubbotest
[root@bogon dubbotest]# rz
rz waiting to receive.
[root@bogon dubbotest]# ll
total 60520
-rw-r--r--. 1 root root 26924417 Jan 25 10:17 dubbo-admin.war
-rw-r--r--. 1 root root 35042811 Apr 23 08:49 zookeeper-3.4.10.tar.gz
[root@bogon dubbotest]# tar -zxf zookeeper-3.4.10.tar.gz
[root@bogon dubbotest]# ls
dubbo-admin.war  zookeeper-3.4.10  zookeeper-3.4.10.tar.gz
[root@bogon dubbotest]# cd zookeeper-3.4.10
[root@bogon zookeeper-3.4.10]# ll
total 1588
drwxr-xr-x.  2 1001 1001    4096 Mar 23  2017 bin
-rw-rw-r--.  1 1001 1001   84725 Mar 23  2017 build.xml
drwxr-xr-x.  2 1001 1001    4096 Mar 23  2017 conf
drwxr-xr-x. 10 1001 1001    4096 Mar 23  2017 contrib
drwxr-xr-x.  2 1001 1001    4096 Mar 23  2017 dist-maven
drwxr-xr-x.  6 1001 1001    4096 Mar 23  2017 docs
-rw-rw-r--.  1 1001 1001    1709 Mar 23  2017 ivysettings.xml
-rw-rw-r--.  1 1001 1001    5691 Mar 23  2017 ivy.xml
drwxr-xr-x.  4 1001 1001    4096 Mar 23  2017 lib
-rw-rw-r--.  1 1001 1001   11938 Mar 23  2017 LICENSE.txt
-rw-rw-r--.  1 1001 1001    3132 Mar 23  2017 NOTICE.txt
-rw-rw-r--.  1 1001 1001    1770 Mar 23  2017 README_packaging.txt
-rw-rw-r--.  1 1001 1001    1585 Mar 23  2017 README.txt
drwxr-xr-x.  5 1001 1001    4096 Mar 23  2017 recipes
drwxr-xr-x.  8 1001 1001    4096 Mar 23  2017 src
-rw-rw-r--.  1 1001 1001 1456729 Mar 23  2017 zookeeper-3.4.10.jar
-rw-rw-r--.  1 1001 1001     819 Mar 23  2017 zookeeper-3.4.10.jar.asc
-rw-rw-r--.  1 1001 1001      33 Mar 23  2017 zookeeper-3.4.10.jar.md5
-rw-rw-r--.  1 1001 1001      41 Mar 23  2017 zookeeper-3.4.10.jar.sha1
[root@bogon zookeeper-3.4.10]# cd conf
[root@bogon conf]# ll
total 12
-rw-rw-r--. 1 1001 1001  535 Mar 23  2017 configuration.xsl
-rw-rw-r--. 1 1001 1001 2161 Mar 23  2017 log4j.properties
-rw-rw-r--. 1 1001 1001  922 Mar 23  2017 zoo_sample.cfg
[root@bogon conf]# mv zoo_sample.cfg zoo.cfg
[root@bogon conf]# ll
total 12
-rw-rw-r--. 1 1001 1001  535 Mar 23  2017 configuration.xsl
-rw-rw-r--. 1 1001 1001 2161 Mar 23  2017 log4j.properties
-rw-rw-r--. 1 1001 1001  922 Mar 23  2017 zoo.cfg
[root@bogon conf]# vim zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/root/dubbotest/zookeeper-3.4.10/data
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
[root@bogon conf]# cd ..
[root@bogon zookeeper-3.4.10]# ll
total 1592
drwxr-xr-x.  2 1001 1001    4096 Mar 23  2017 bin
-rw-rw-r--.  1 1001 1001   84725 Mar 23  2017 build.xml
drwxr-xr-x.  2 1001 1001    4096 Apr 26 10:32 conf
drwxr-xr-x. 10 1001 1001    4096 Mar 23  2017 contrib
drwxr-xr-x.  2 root root    4096 Apr 26 10:26 data
drwxr-xr-x.  2 1001 1001    4096 Mar 23  2017 dist-maven
drwxr-xr-x.  6 1001 1001    4096 Mar 23  2017 docs
-rw-rw-r--.  1 1001 1001    1709 Mar 23  2017 ivysettings.xml
-rw-rw-r--.  1 1001 1001    5691 Mar 23  2017 ivy.xml
drwxr-xr-x.  4 1001 1001    4096 Mar 23  2017 lib
-rw-rw-r--.  1 1001 1001   11938 Mar 23  2017 LICENSE.txt
-rw-rw-r--.  1 1001 1001    3132 Mar 23  2017 NOTICE.txt
-rw-rw-r--.  1 1001 1001    1770 Mar 23  2017 README_packaging.txt
-rw-rw-r--.  1 1001 1001    1585 Mar 23  2017 README.txt
drwxr-xr-x.  5 1001 1001    4096 Mar 23  2017 recipes
drwxr-xr-x.  8 1001 1001    4096 Mar 23  2017 src
-rw-rw-r--.  1 1001 1001 1456729 Mar 23  2017 zookeeper-3.4.10.jar
-rw-rw-r--.  1 1001 1001     819 Mar 23  2017 zookeeper-3.4.10.jar.asc
-rw-rw-r--.  1 1001 1001      33 Mar 23  2017 zookeeper-3.4.10.jar.md5
-rw-rw-r--.  1 1001 1001      41 Mar 23  2017 zookeeper-3.4.10.jar.sha1
[root@bogon zookeeper-3.4.10]# cd bin
[root@bogon bin]# ll
total 36
-rwxr-xr-x. 1 1001 1001  232 Mar 23  2017 README.txt
-rwxr-xr-x. 1 1001 1001 1937 Mar 23  2017 zkCleanup.sh
-rwxr-xr-x. 1 1001 1001 1056 Mar 23  2017 zkCli.cmd
-rwxr-xr-x. 1 1001 1001 1534 Mar 23  2017 zkCli.sh
-rwxr-xr-x. 1 1001 1001 1628 Mar 23  2017 zkEnv.cmd
-rwxr-xr-x. 1 1001 1001 2696 Mar 23  2017 zkEnv.sh
-rwxr-xr-x. 1 1001 1001 1089 Mar 23  2017 zkServer.cmd
-rwxr-xr-x. 1 1001 1001 6773 Mar 23  2017 zkServer.sh
[root@bogon bin]# ./zkServer.sh
ZooKeeper JMX enabled by default
Using config: /root/dubbotest/zookeeper-3.4.10/bin/../conf/zoo.cfg
Usage: ./zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}
[root@bogon bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /root/dubbotest/zookeeper-3.4.10/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED 

  上面的vim操作中,紅色字體是你需要設置的,綠色字體“STARTED”,表示zookeeper服務開啓,這時腳本中會啓動一個java進程。

  注:需要先啓動zookeeper,後續的dubbo demo代碼運行才能使用zookeeper註冊中心的功能。

  2.創建maven項目

  項目結構主要分三大模塊:
  (1)dubbo-api : 存放公共接口;
  (2)dubbo-provider : 提供遠程服務;
  (3)dubbo-consumer : 調用遠程服務。

  我在這裏模擬一個使用場景:用戶在一個電商網站預先存有一筆款項(好比支付寶,用戶可以在支付寶裏先充值),然後登錄該電商網站購物消費;用戶每花一筆錢,餘額就會相應地減少。這時,我們定義一個api接口,專門用於提供查詢餘額和扣款的操作;接着定義另一個實現該接口的模塊,專門實現接口定義的功能,並把本模塊提供的服務註冊到zookeeper中;然後,我們再搭建一個用戶登錄操作的模塊,該模塊從zookeeper中調用餘額查詢與扣款操作的服務。

  

  

  (1)服務提供者主模塊DDDR_MONEY的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">
    <!--模型版本號-->
    <modelVersion>4.0.0</modelVersion>

    <!--本模塊的座標,g,a,v-->
    <groupId>com.itsztdddr</groupId>
    <artifactId>DDDR_MONEY</artifactId>
    <version>1.0</version>
    
    <!--包含的子模塊-->
    <modules>
        <module>money_interface</module>
        <module>money_impl</module>
    </modules>

  <!--本模塊的打包類型-->
    <packaging>pom</packaging>
</project>

   ①子模塊money_interface的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">
    <modelVersion>4.0.0</modelVersion>

    <!--本模塊的父模塊-->
    <parent>
        <artifactId>DDDR_MONEY</artifactId>
        <groupId>com.itsztdddr</groupId>
        <version>1.0</version>
    </parent>

    <!--本模塊的座標以及打包類型;在有父模塊時,本模塊的<version>標籤可以省略-->
    <groupId>com.itsztdddr</groupId>
    <artifactId>money_interface</artifactId>
    <packaging>jar</packaging>
</project>

   MoneyService.java源文件:

package com.itszt.money.service;
/**
 * 定義服務接口api
 */
public interface MoneyService {
    //查詢錢
    public Integer queryMoney();
    //消費扣款;餘額不能小於等於0,要花的錢不能超過餘額
    public boolean costMoney(int costMoney);
}

   ②子模塊money_impl的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">
    <modelVersion>4.0.0</modelVersion>

    <!--本模塊的父模塊-->
    <parent>
        <artifactId>DDDR_MONEY</artifactId>
        <groupId>com.itsztdddr</groupId>
        <version>1.0</version>
    </parent>

    <!--本模塊的座標及打包方式-->
    <groupId>com.itsztdddr</groupId>
    <artifactId>money_impl</artifactId>
    <packaging>war</packaging>

    <!--本模塊的屬性-->
    <properties>
        <!--規定本模塊中的源碼編碼格式-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!--本模塊的依賴庫-->
    <dependencies>
        <!--單元測試的依賴庫-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!--服務接口api的依賴庫;需要模塊money_interface先install(上傳本地庫)-->
        <dependency>
            <groupId>com.itsztdddr</groupId>
            <artifactId>money_interface</artifactId>
            <version>1.0</version>
        </dependency>
        <!--  Spring框架依賴(aop,context,web) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!--  Spring -->

        <!--   dubbo的zookeeper服務依賴  -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.7</version>
            <!--排除不需要的依賴-->
            <exclusions>
                <!--上面已經配置spring依賴,此處排除dubbo默認的spring依賴-->
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--dubbo客戶端框架的依賴-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>
        <!--   dubbo  -->
    </dependencies>

    <!--構建本模塊的插件-->
    <build>
        <finalName>dddrMoney</finalName>
        <plugins>
            <!--JDK編譯版本插件,默認1.5,改成1.8-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <!-- 配置tomcat插件 -->
                <!--同時要修改tomcat的conf/server.xml和tomcat-users.xml文件-->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <username>adminMoney</username>
                    <password>123456</password>
                    <port>8080</port>
                    <path>/</path>
                    <url>http://localhost:8080/manager/text</url>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

   其中,該模塊對應的tomcat的conf/tomcat-users.xml中的<tomcat-users></tomcat-users>之間添加如下配置:

<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<user password="123456" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-script,admin-gui" username="adminMoney"/>

   資源文件夾resources下的spring-config.xml文件配置:

<?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: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/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

     <!--SpringIoC對於註解的支持-->
    <context:component-scan base-package="com.itszt.money"></context:component-scan>

    <!--定義了提供方應用信息,用於計算依賴關係;在 dubbo-admin 或 dubbo-monitor 中會顯示這個名字,方便辨識-->
    <dubbo:application name="dddr-money" owner="lzy" organization="itszt"/>

    <!--使用 zookeeper 註冊中心對外暴露服務,注意要先開啓 zookeeper-->
    <dubbo:registry address="zookeeper://192.168.1.28:2181"/>

    <!-- 用dubbo協議在提供方服務器的20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880" />

    <!--使用 dubbo 協議實現定義好的 api.PermissionService 接口-->
    <dubbo:service interface="com.itszt.money.service.MoneyService" ref="MoneyService" protocol="dubbo" />
</beans>

   web.xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <display-name>cost-service</display-name>
  <!--上下文參數配置的文件-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-config.xml</param-value>
  </context-param>
  <!--監聽器;tomcat服務器一啓動,本網站服務就啓動-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app> 

  MoneyServiceImpl_v1.java源碼文件:

package com.itszt.money;
import com.itszt.money.service.MoneyService;
import org.springframework.stereotype.Service;
/**
 * 服務實現;具體向外提供服務
 */
@Service("MoneyService")
public class MoneyServiceImpl_v1 implements MoneyService{
    //示例;默認用戶賬戶的初始值
    private static int totalMoney=10000;
    @Override
    public Integer queryMoney() {
        return totalMoney;
    }

    @Override
    public boolean costMoney(int costMoney) {
        if(totalMoney>0 && (totalMoney>=costMoney)){
            totalMoney-=costMoney;
            return true;
        }
        return false;
    }
}

   (2)服務消費者模塊storedddr的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">
    <modelVersion>4.0.0</modelVersion>
    <!--本模塊的座標及打包方式-->
    <groupId>com.itsztdddr</groupId>
    <artifactId>storedddr</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <!--本模塊的屬性-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!--本模塊的依賴庫-->
    <dependencies>
        <!--單元測試依賴庫-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <!--餘額服務依賴庫-->
        <dependency>
            <groupId>com.itsztdddr</groupId>
            <artifactId>money_interface</artifactId>
            <version>1.0</version>
        </dependency>

        <!--  Spring框架依賴庫(含springmvc) -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.7.RELEASE</version>
        </dependency>
        <!--  Spring -->

        <!--   dubbo的zookeeper服務依賴庫  -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.9</version>
        </dependency>
        <!-- dubbo -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.7</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>
        <!--   dubbo  -->
    </dependencies>

    <!--本模塊的插件配置-->
    <build>
        <finalName>storedddr</finalName>
        <plugins>
            <!--JDK編譯版本插件,默認1.5,改成1.8-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>

            <plugin>
                <!-- 配置tomcat插件 -->
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <configuration>
                    <username>adminStore</username>
                    <password>123456</password>
                    <port>7070</port>
                    <path>/</path>
                    <url>http://localhost:7070/manager/text</url>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

   本模塊的resources資源文件夾下的spring-mvc-config.xml文件:

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!--springmvc的註解支持-->
    <context:component-scan base-package="com.itszt.storedddr.controller"></context:component-scan>

    <!--通過註解支持映射請求路徑和控制器處理-->
    <mvc:annotation-driven>
    </mvc:annotation-driven>

    <!--視圖解析器配置-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

    <!--定義了消費方的應用信息,用於計算依賴關係;在 dubbo-admin 或 dubbo-monitor 會顯示這個名字,方便辨識-->
    <dubbo:application name="dddr-store" owner="lzy" organization="itszt"/>

    <!--使用 zookeeper 註冊中心暴露服務,注意要先開啓 zookeeper-->
    <dubbo:registry address="zookeeper://192.168.1.28:2181"/>

    <!--引用MoneyService的遠程服務給我們提供實現bean,這是RPC(遠程方法調用)的一個具體實現-->
    <dubbo:reference id="moneyService" interface="com.itszt.money.service.MoneyService"/>
</beans> 

  本war模塊的web.xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
  <display-name>store-consumer</display-name>
  <!--處理web訪問請求的分發中心配置-->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
</web-app>

   本模塊的webapp下的入口文件index.jsp:

<%@page contentType="text/html; charset=UTF-8" language="java" %>
<html>
<body>
<jsp:forward page="/index.html"></jsp:forward>
</body>
</html>

   WEB-INF下的文件storeCenter.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
調用結算系統進行結算...

當前您的餘額是:${moneyNow}
<hr>
進行消費:
<form action="/costMoney.html" method="post">
    <input type="text" name="moneyCost" placeholder="請輸入要消費的錢數">
    <input type="submit" value="消費">
</form>

${errorInfo}
</body>
</html>

   處理web請求的控制器StoreController.java文件:

package com.itszt.storedddr.controller;

import com.itszt.money.service.MoneyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/**
 * 處理web請求的控制器
 */
@Controller
public class StoreController {

    @Autowired
    private MoneyService moneyService;
    @RequestMapping("index")
    public String goToIndex(Model model){
        Integer money = moneyService.queryMoney();
        model.addAttribute("moneyNow",money);
        return "storeCenter";
    }
    @RequestMapping("costMoney")
    public String costMoney(int moneyCost,Model model){
        boolean b = moneyService.costMoney(moneyCost);
        if (b) {
            model.addAttribute("errorInfo","消費成功 !這麼多錢: "+moneyCost);
        }else {
            model.addAttribute("errorInfo","餘額不足 !這麼多錢: "+moneyCost);
        }
        return "forward:index.html";
    }
}

   到此爲止,在確保zookeeper開啓的情況下,先開啓服務提供方的服務器,再開啓服務消費方的服務器。然後,再服務消費方的頁面上“消費”一定數額後,餘額會相應減少:

  接下來,將監控服務提供方和服務消費方的監控中心dubbo-admin.war放到另一個tomcat(擬訂該tomcat的http訪問端口爲10080,與其他端口不衝突的情況下)的webapps文件夾下,配置dubbo-admin/web-inf/dubbo.properties文件(確保與zookeeper所在服務器信息一致):

dubbo.registry.address=zookeeper://192.168.1.28:2181
dubbo.admin.root.password=china2018
dubbo.admin.guest.password=guest

   這時訪問該監控中心,登錄頁面如下:

  登錄成功後可以顯示出服務提供者和消費者的信息,還可以予以相應控制:

  至此,一個比較完整的dubbo Demo就完成了。

  總的來說,dubbo涉及的方面比較多,有zookeeper註冊中心,提供服務接口的api,服務提供者,服務消費者;其中還涉及到了linux的操作,tomcat配置等知識。爲此,我們需要理清思路,做好設計,從而一步一步地用好dubbo技術。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章