【注:本文參考《Dubbo入門---搭建一個最簡單的Demo框架》,感謝原創做者的知識探索與奉獻】html
一.Dubbo背景和簡介
Dubbo開始於電商系統,所以在這裏先從電商系統的演變講起。
1.單一應用框架(ORM)
當網站流量很小時,只需一個應用,將全部功能(以下單支付等)都部署在一塊兒,以減小部署節點和成本。此時,用於簡化增刪改查工做量的 數據訪問框架(ORM) 是關鍵。
缺點:單一的系統架構,使得在開發過程當中,佔用的資源愈來愈多,並且隨着流量的增長愈來愈難以維護。前端
2.垂直應用框架(MVC)
垂直應用架構解決了單一應用架構所面臨的擴容問題,流量可以分散到各個子系統當中,且系統的體積可控,必定程度上下降了開發人員之間協同以及維護的成本,提高了開發效率。此時,用於加速前端頁面開發的 Web框架(MVC) 是關鍵。
缺點:垂直架構中相同的邏輯代碼須要不斷的複製,不能複用。java
3.分佈式應用架構(RPC)
當垂直應用愈來愈多,應用之間交互不可避免,將核心業務抽取出來,做爲獨立的服務,逐漸造成穩定的服務中心。此時,用於提升業務複用及整合的 分佈式服務框架(RPC) 是關鍵。linux
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) 是關鍵。nginx
從以上電商系統的演變能夠看出架構演變的過程:web
那麼,Dubbo是什麼呢? 算法
Dubbo是: 一款分佈式服務框架 高性能和透明化的RPC遠程服務調用方案 SOA服務治理方案
迄今爲止,Dubbo天天爲2千多個服務提供大於30億次訪問量支持,並被普遍應用於阿里巴巴集團的各成員站點以及別的公司的業務中。spring
Dubbo架構:apache
Provider: 暴露服務的服務提供方。 Consumer: 調用遠程服務的服務消費方。 Registry: 服務註冊與通知的註冊中心。 Monitor: 統計服務的調用次數和調用時間的監控中心。
調用流程
①服務容器負責啓動,加載,運行服務提供者。
②服務提供者在啓動時,向註冊中心註冊本身提供的服務。
③服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
④註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
⑤服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
⑥服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心 vim
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技術。