以前,咱們討論過Nginx+tomcat組成的集羣,這已是很是靈活的集羣技術,可是當咱們的系統遇到更大的瓶頸,所有應用的單點服務器已經不能知足咱們的需求,這時,咱們要考慮另一種,咱們熟悉的內容,就是分佈式,而當下流行的Dubbo框架,不容咱們忽視,這裏,我們一塊兒來探討一下這個框架的使用。html
之前咱們須要遠程調用他人的接口,咱們是這麼作的:linux
咱們遇到的問題:git
(1) 當服務愈來愈多時,服務URL配置管理變得很是困難,F5硬件負載均衡器的單點壓力也愈來愈大。
此時須要一個服務註冊中心,動態的註冊和發現服務,使服務的位置透明。
並經過在消費方獲取服務提供方地址列表,實現軟負載均衡和Failover,下降對F5硬件負載均衡器的依賴,也能減小部分紅本。
(2) 當進一步發展,服務間依賴關係變得錯蹤複雜,甚至分不清哪一個應用要在哪一個應用以前啓動,架構師都不能完整的描述應用的架構關係。
這時,須要自動畫出應用間的依賴關係圖,以幫助架構師理清理關係。
(3) 接着,服務的調用量愈來愈大,服務的容量問題就暴露出來,這個服務須要多少機器支撐?何時該加機器?
爲了解決這些問題,第一步,要將服務如今天天的調用量,響應時間,都統計出來,做爲容量規劃的參考指標。
其次,要能夠動態調整權重,在線上,將某臺機器的權重一直加大,並在加大的過程當中記錄響應時間的變化,直到響應時間到達閥值,記錄此時的訪問量,再以此訪問量乘以機器數反推總容量。 github
爲解決這些問題,Dubbo爲咱們作了什麼呢:web
負載均衡:算法
這就是所謂的軟負載均衡!spring
如今讓咱們一塊兒來接觸下這個優秀的框架:數據庫
架構如圖:apache
節點角色說明:windows
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務註冊與發現的註冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
調用關係說明:
0. 服務容器負責啓動,加載,運行服務提供者。
1. 服務提供者在啓動時,向註冊中心註冊本身提供的服務。
2. 服務消費者在啓動時,向註冊中心訂閱本身所需的服務。
3. 註冊中心返回服務提供者地址列表給消費者,若是有變動,註冊中心將基於長鏈接推送變動數據給消費者。
4. 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,若是調用失敗,再選另外一臺調用。
5. 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
Dubbo 提供了不少協議, Dubbo 協 議、RMI 協議 、 Hessian 協議, 咱們查看 Dubbo 源代碼,有各類協議的實現,如圖所示:
咱們以前沒用 Dubbo 以前時,大部分都使用 Hessian來使用咱們服務的暴露和調用,利用 HessianProxyFactory 調用遠程接口。
上面是參考了 Dubbo 官方網介紹,接下來咱們來介紹 SpringMVC 、 Dubbo 、 Zookeeper 整合使用。
Zookeeper 做爲 Dubbo 服務的註冊中心, Dubbo 原先基於數據庫的註冊中心,沒采用 Zookeeper , Zookeeper 一個分佈式的服務框架,是樹型的目錄服務 的數據存儲,能作到集羣管理數據 ,這裏能很好的做爲 Dubbo 服務的註冊中心, Dubbo 能與 Zookeeper 作到集羣部署,當提供者出現斷電等異常停機時, Zookeeper 註冊中心能自動刪除提供者信息,當提供者重啓時,能自動恢復註冊數據,以及訂閱請求。咱們先在 linux 上安裝 Zookeeper ,咱們安裝最簡單的單點,集羣比較麻煩。
先須要安裝JdK,從Oracle的Java網站下載,安裝很簡單,就再也不詳述。
單機模式
單機安裝很是簡單,只要獲取到 Zookeeper 的壓縮包並解壓到某個目錄如:C:\zookeeper-3.4.5\下,Zookeeper 的啓動腳本在 bin 目錄下,Windows 下的啓動腳本是 zkServer.cmd。
在你執行啓動腳本以前,還有幾個基本的配置項須要配置一下,Zookeeper 的配置文件在 conf 目錄下,這個目錄下有 zoo_sample.cfg 和 log4j.properties,你須要作的就是將 zoo_sample.cfg 更名爲 zoo.cfg,由於 Zookeeper 在啓動時會找這個文件做爲默認配置文件。下面詳細介紹一下,這個配置文件中各個配置項的意義。
1 <span style="font-size:18px;"># The number of milliseconds of each tick 2 tickTime=2000 3 # The number of ticks that the initial 4 # synchronization phase can take 5 initLimit=10 6 # The number of ticks that can pass between 7 # sending a request and getting an acknowledgement 8 syncLimit=5 9 # the directory where the snapshot is stored. 10 # do not use /tmp for storage, /tmp here is just 11 # example sakes. 12 dataDir=C:\\zookeeper-3.4.5\\data 13 dataLogDir=C:\\zookeeper-3.4.5\\log 14 # the port at which the clients will connect 15 clientPort=2181 16 # 17 # Be sure to read the maintenance section of the 18 # administrator guide before turning on autopurge. 19 # 20 # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance 21 # 22 # The number of snapshots to retain in dataDir 23 #autopurge.snapRetainCount=3 24 # Purge task interval in hours 25 # Set to "0" to disable auto purge feature 26 #autopurge.purgeInterval=1</span>
當這些配置項配置好後,你如今就能夠啓動 Zookeeper 了,啓動後要檢查 Zookeeper 是否已經在服務,能夠經過 netstat – ano 命令查看是否有你配置的 clientPort 端口號在監聽服務。
(1)下載 dubbo-admin-2.4.1.war 包,在 windows 的 tomcat 部署,先把 dubbo-admin-2.4.1 放在 tomcat 的 webapps/ROOT 下,而後進行解壓
(2)而後到 webapps/ROOT/WEB-INF 下,有一個 dubbo.properties 文件,裏面指向Zookeeper ,使用的是Zookeeper 的註冊中心,如圖所示:
1 <span style="font-size:18px;">dubbo.registry.address=zookeeper://127.0.0.1:2181 2 dubbo.admin.root.password=root 3 dubbo.admin.guest.password=guest</span>
(3)而後啓動 tomcat 服務,用戶名和密碼: root,並訪問服務,顯示登錄頁面,說明dubbo-admin部署成功, 如圖所示:
第一: 咱們先開發服務註冊的,就是提供服務,項目結構如圖所示:
(1)test-maven-api項目加入了一個服務接口,代碼以下:
1 public interface TestRegistryService { 2 public String hello(String name); 3 }
(2)test-maven-console在pom .xml 加入 Dubbo 和Zookeeper的 jar 包、引用 test-maven-api 的 jar 包,代碼以下:
1 <span style="font-size:18px;"><dependency> 2 <groupId>cn.test</groupId> 3 <artifactId>test-maven-api</artifactId> 4 <version>0.0.1-SNAPSHOT</version> 5 </dependency> 6 <dependency> 7 <groupId>com.alibaba</groupId> 8 <artifactId>dubbo</artifactId> 9 <version>2.5.3</version> 10 </dependency> 11 <dependency> 12 <groupId>org.apache.zookeeper</groupId> 13 <artifactId>zookeeper</artifactId> 14 <version>3.4.6</version> 15 </dependency> 16 <dependency> 17 <groupId>com.github.sgroschupf</groupId> 18 <artifactId>zkclient</artifactId> 19 <version>0.1</version> 20 </dependency></span>
(3)test-maven-console實現具體的服務,代碼以下:
1 @Service("testRegistryService") 2 public class TestRegistryServiceImpl implements TestRegistryService { 3 public String hello(String name) { 4 return "hello"+name; 5 } 6 }
(4)咱們服務以及實現好了,這時要暴露服務,代碼以下:
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:jee="http://www.springframework.org/schema/jee" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 <span style="color:#cc0000;">xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"</span> 7 xmlns:context="http://www.springframework.org/schema/context" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 10 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd 11 <span style="color:#990000;">http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd</span> 12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" 13 default-lazy-init="false" > 14 <!-- 提供方應用名稱信息,這個至關於起一個名字,咱們dubbo管理頁面比較清晰是哪一個應用暴露出來的 --> 15 <dubbo:application name="dubbo_provider"></dubbo:application> 16 <!-- 使用zookeeper註冊中心暴露服務地址 --> 17 <dubbo:registry address="zookeeper://127.0.0.1:2181" check="false" subscribe="false" register=""></dubbo:registry> 18 <!-- 要暴露的服務接口 --> 19 <dubbo:service interface="cn.test.dubbo.registry.service.TestRegistryService" ref="testRegistryService" /> 20 </beans>
說明:
dubbo:registry 標籤一些屬性的說明:
1 ) register 是否向此註冊中心註冊服務,若是設爲 false ,將只訂閱,不註冊 。
2 ) check 註冊中心不存在時,是否報錯。
3 ) subscribe 是否向此註冊中心訂閱服務,若是設爲 false ,將只註冊,不訂閱 。
4 ) timeout 註冊中心請求超時時間 ( 毫秒 ) 。
5 ) address 能夠 Zookeeper 集羣配置 ,地址能夠多個以逗號隔開等。
dubbo:service 標籤的一些屬性說明:
1 ) interface服務接口的路徑
2 ) ref引用對應的實現類的 Bean 的 ID
3 ) registry向指定註冊中心註冊,在多個註冊中心時使用,值爲 <dubbo:registry> 的 id 屬性,多個註冊中心 ID 用逗號分隔,若是不想將該服務註冊到任何 registry ,可將值設爲 N/A
4 ) register 默認true ,該協議的服務是否註冊到註冊中心。
(5)啓動項目,而後咱們在 Dubbo 管理頁面上顯示,已經暴露的服務,但顯示尚未消費者,由於咱們還沒實現消費者服務,如圖所示:
第二:咱們在開發服務消費者,就是調用服務,咱們在新建一個新的消費者項目:
(1)test-maven-server-console的 pom.xml 引入 Dubbo 和Zookeeper的 jar 包、 test-maven-api 的 jar 包,由於引入 test-maven-api 的 jar 包,咱們在項目中調用像在本地調用同樣。代碼以下:
1 <span style="font-size:18px;"><dependency> 2 <groupId>cn.test</groupId> 3 <artifactId>test-maven-api</artifactId> 4 <version>0.0.1-SNAPSHOT</version> 5 </dependency> 6 <dependency> 7 <groupId>com.alibaba</groupId> 8 <artifactId>dubbo</artifactId> 9 <version>2.5.3</version> 10 </dependency> 11 <dependency> 12 <groupId>org.apache.zookeeper</groupId> 13 <artifactId>zookeeper</artifactId> 14 <version>3.4.6</version> 15 </dependency> 16 <dependency> 17 <groupId>com.github.sgroschupf</groupId> 18 <artifactId>zkclient</artifactId> 19 <version>0.1</version> 20 </dependency></span>
(2)test-maven-server-console項目的具體實現,代碼以下:
1 @Controller 2 public class IndexController { 3 4 @Autowired 5 private TestRegistryService testRegistryService; 6 7 @RequestMapping("/hello") 8 public String index(Model model){ 9 String name=testRegistryService.hello("zz"); 10 System.out.println("xx=="+name); 11 return ""; 12 } 13 14 }
(3)咱們要引用的地址,代碼以下:
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:jee="http://www.springframework.org/schema/jee" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 <span style="background-color: rgb(255, 255, 255);"><span style="color:#990000;">xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"</span></span> 7 xmlns:context="http://www.springframework.org/schema/context" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 9 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 10 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd 11 <span style="color:#990000;">http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd</span> 12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" 13 default-lazy-init="false" > 14 15 <dubbo:application name="dubbo_consumer"></dubbo:application> 16 <!-- 使用zookeeper註冊中心暴露服務地址 --> 17 <dubbo:registry address="zookeeper://192.168.74.129:2181" check="false"></dubbo:registry> 18 <!-- 要引用的服務 --> 19 <dubbo:reference interface="cn.test.dubbo.registry.service.TestRegistryService" id="testRegistryService"></dubbo:reference> 20 </beans>
說明:
dubbo:reference 的一些屬性的說明:
1 ) interface調用的服務接口
2 ) check 啓動時檢查提供者是否存在, true 報錯, false 忽略
3 ) registry 從指定註冊中心註冊獲取服務列表,在多個註冊中心時使用,值爲 <dubbo:registry> 的 id 屬性,多個註冊中心 ID 用逗號分隔
4 ) loadbalance 負載均衡策略,可選值: random,roundrobin,leastactive ,分別表示:隨機,輪循,最少活躍調用
(4)項目啓動, Dubbo 管理頁面,能看到消費者,如圖所示:
(5)而後訪問消費者項目, Controller 層能像調用本地同樣調用服務的具體實現,如圖所示:
通過一系列的操做以後,咱們感受,的確很簡單,dubbo給咱們封裝了不少操做,讓咱們不須要過多考慮具體的實現細節,配置化生成我們的應用,這樣的思想,如今在IT行業正在盛行!