您好,登錄后才能下訂單哦!
這篇文章主要講解了“怎么用Dubbo+Zookeeper+Spring實現Demo”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么用Dubbo+Zookeeper+Spring實現Demo”吧!
Dubbo是一個分布式服務框架,致力于提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。 微服務使用最廣泛的框架就是SpringCloud跟Dubbo。Dubbo比較專注于服務治理這塊,而SpringCloud全家桶則提供了微服務的一整套解決方案
遠程通訊: 提供對多種基于長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
集群容錯: 提供基于接口方法的透明遠程過程調用,包括多協議支持,以及軟負載均衡,失敗容錯,地址路由,動態配置等集群支持。
自動發現: 基于注冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
服務自動注冊與發現,不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址,并且能夠平滑添加或刪除服務提供者。
Dubbo采用全Spring配置方式,透明化接入應用,對應用沒有任何API侵入,不管是Provider還是Consumer都可以通過Spring的配置文件進行配置,配置完之后,就可以像使用springbean一樣進行服務暴露和調用了,完全看不到dubboapi的存在。Dubbo基于Spring的Schema擴展進行加載。
現在還可以通過 API 的方式進行調用。
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務注冊與發現的注冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
架構圖
調用關系說明:
服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心。
服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給消費者。
服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
服務提供者在啟動時,向注冊中心注冊自己提供的服務。
服務容器負責啟動,加載,運行服務提供者。
連通性:連通性說明他們之間都存在著關系,比如說Provider,Consumer和Registry三者之間都是長連接,而Provider,Consumer向Registry注冊服務以及訂閱服務的時間都得向Monitor匯報
健壯性:而健壯性說明具有穩定性,比如說注冊中心對等集群中的任意一臺宕掉后,將自動切換到另一臺。就算注冊中心全部宕掉,服務者和消費者仍可以通過本地緩存進行通訊。
伸縮性:伸縮性就是可以通過增加機器部署實例進行添加新的注冊中心和服務提供者
升級性:文檔中提到的對未來架構的設想,比起目前框架它的特點是可以實現自動部署服務的本地代理以及可以通過訪問壓力來自動增減服務提供者
本demo中用的是Zookeeper 3.4.14版本,用哪個版本都行,記得改下demo中的pom文件里的ZK依賴配置就可以。下載和安裝步驟可以參考以下鏈接:https://blog.csdn.net/tlk20071/article/details/52028945
為什么采用Zookeeper?
本demo中采用Zookeeper作為Dubbo的注冊中心時,ZK是一個樹型的目錄服務,支持變更推送,可以作為集群的管理工具使用。可以集中管理配置文件。
(1)服務提供者在初始化啟動時,會在Zookeeper下的Dubbo節點下的服務節點下的providers節點下的節點創建一個子節點并寫入URL,路徑類似為 /dubbo/servicename/providers/ ,該路徑下的所有子節點均為服務提供者。此時這些子節點都為臨時節點,因為臨時節點的生命周期與客戶端會話相關,所以一旦提供者所在的機器出現故障導致提供者無法提供服務,該臨時節點就會自動從Zookeeper刪除。
此時因為服務者,注冊中心,消費者之間是長連接,注冊中心能感知服務者宕機,會告知消費者。
而監控中心是Dubbo服務治理體系中重要的一部分,它需要知道所有的服務提供者和消費者的變化情況 。所以它在啟動時會在服務節點上注冊一個watcher來監聽子節點變化,路徑為 /dubbo/servicename/ ,所以它也能感知服務提供者的宕機。
(2)還有一個特性就是Zookeeper的節點結構設計(樹形),它以服務名和類型,也就是 /dubbo/servicename/類型 作為節點路徑,符合Dubbo訂閱和通知的需求,保證了以服務為粒度的變更通知,通知范圍易于控制。所以即使服務提供者和消費者頻繁變更,對Zookeeper的性能也不會造成多大影響。
創建Maven項目project,然后在工程里面創建三大模塊moudle,分別為: dubbo-api (公共服務接口) 、 dubbo-consumer(消費者,調用遠程服務)、 dubbo-provider(提供遠程服務)。
(1)其中需要在整個項目的pom.xml文件中添加相關依賴:這里需要注意dubbo的版本問題,下面會講到,這里插個眼先。
<?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.test</groupId> <artifactId>dubbo_demo</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>dubbo_consumer</module> <module>dubbo_provider</module> <module>dubbo_api</module> </modules> <packaging>pom</packaging> <name>dubbo_demo Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.4.RELEASE</version> </dependency> <!-- 添加 日志依賴包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.24</version> </dependency> <!-- 添加 dubbo 依賴包 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.3</version> </dependency> <!-- 添加 zookeeper 相關依賴包 --> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.14</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>2.8.0</version> </dependency> <!-- 添加 zkclient 依賴包 --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> </dependencies> <build> <finalName>dubbo_demo</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
(2) 創建dubbo_api moudle,在項目中定義服務接口:該接口需單獨打包,在服務提供方和消費方共享 在dubbo-api中定義服務接口DemoService,如下:
package com.test; public interface DemoService { public String sayHello(String name); }
(3)創建dubbo_provider moudle,然后在dubbo_provider中實現上述接口。為什么這里能實現跨moudle調用接口并且完成接口實現,因為在provider的pom.xml文件中添加了dubbo_api作為依賴,故能引入上述接口。如圖
其中接口實現類DemoServiceImpl代碼如下:
import com.test.DemoService; public class DemoServiceImpl implements DemoService { public String sayHello(String name) { return "hello"+name; } }
同時在此moudle下寫一個啟動測試類,便于后面啟動provider:
import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; public class ProviderTest { public static void main(String[] args){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:dubbo-provider.xml"); applicationContext.start(); System.out.println("Dubbo provider start,啟動服務提供.."); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } } }
(4)創建dubbo_consumer moudle,然后在dubbo_consumer中寫一個啟動測試類,便于后面啟動consumer調用provider提供的服務:
import com.test.DemoService; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.io.IOException; public class ConsumerTest { public static void main(String[] args){ ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:dubbo-consumer.xml"); applicationContext.start(); DemoService demoService = (DemoService) applicationContext.getBean("ddemoService"); System.out.println(demoService.sayHello(" guy")); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } } }
(5)上述代碼寫好后,好像各個moudle看起來好像沒有聯系?大家都好奇就是Dubbo是怎么實現服務的發布和遠程調用的吧。接下來是重點,進行provider和consumer的配置
a. 在dubbo_provider的resource中新建dubbo_provider.xml文件,實現dubbo中provider的配置:
首先完成應用配置,配置當前提供方應用名為dubbo_provider。
然后完成注冊中心配置,將Zookeeper作為注冊中心,設定其地址。
然后進行協議配置,用于配置提供服務的協議信息,協議只由provider指定,使用port="20880"作為服務提供的接口,供consumer調用。
最后進行服務配置,用于暴露一個服務接口,其絕對路徑interface="com.test.DemoService",代號為ref="demoService"
這里還需要為接口實現類配置一個bean,以供在provider的啟動測試類中調用bean中的方法。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 提供方應用信息,用于計算依賴關系 --> <dubbo:application name="dubbo_provider" /> <!-- 使用zookeeper注冊中心暴露服務地址 --> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20880" /> <!-- 和本地bean一樣實現服務 --> <bean id="demoService" class="DemoServiceImpl" /> <!-- 聲明需要暴露的服務接口 --> <dubbo:service interface="com.test.DemoService" ref="demoService" /> </beans>
b. 在dubbo_consumer的resource中新建dubbo_consumer.xml文件,實現dubbo中consumer的配置。
首先完成應用配置,配置當前消費方應用名為dubbo_consumer;
然后完成完成注冊中心配置,將Zookeeper作為注冊中心,設定其地址。消費方向注冊中心訂閱自己所需的服務;
最后生成遠程服務代理,調用到了絕對路徑為interface="com.test.DemoService" 的接口,設定其代號為id="ddemoService",可以和本地bean一樣使用ddemoService、
(這里可能大家有個問題,為什么這里多了個d,因為為了和dubbo_provider.xml暴露的服務接口和bean做區別。說明消費方調用到此接口服務后,相當于自己的本地有了這個接口,所以接口名可以和provider的不一樣。相當于我在別人那里拿了一個蘋果,在我這里我就可以不叫他蘋果,我叫他梨也可以,因為這個東西是在我手上(本地),我怎么用本地都清楚,不需要外人(provider)清楚)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!-- 消費方應用名,用于計算依賴關系,不是匹配條件,不要與提供方一樣 --> <dubbo:application name="dubbo_consumer" /> <!-- 使用zookeeper注冊中心暴露發現服務地址 --> <dubbo:registry protocol="zookeeper" address="zookeeper://127.0.0.1:2181" /> <!-- 生成遠程服務代理,可以和本地bean一樣使用demoService --> <dubbo:reference id="ddemoService" interface="com.test.DemoService" /> </beans>
(6)項目結構如下,具體可以在文末下載本項目demo。
依次啟動zookeeper(打開bin文件下的zkServer.cmd,并且不要關閉。如果閃退的會可以用cmd調用文件名打開)、運行dubbo-provider、運行dubbo-consumer獲得測試結果如下。
本項目遇到了一個比較奇葩的問題找了我一天,每次在運行provider和consumer的時候都會出現下述問題。
問題:找不到Spring命名空間處理程序。
Offending resource: class path resource [dubbo-consumer.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://dubbo.apache.org/schema/dubbo]
Offending resource: class path resource [dubbo-consumer.xml]
就是下圖紅框的兩個地址有問題,可是這兩個地址都是可以打開的。
問題所在:最終發現之前有段時間dubbo被關閉了一段時間,那段時間dubbo的域名是code.alibabatech.com ,網上找到別人的案例里面配置的都是下面這種地址,結果發現這些地址都失效。按道理我現在程序里用最新的應該沒錯,為什么還會報錯了。又只能繼續到處找bug。
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
后來開始懷疑是不是我一開始用的版本比較舊(2.5.X);然后發現果然如此。問題在于: dubbo-config-spring-2.6.1.jar --> META-INF-->spring.handlers 中的配置還是之前的域名 code.alibabatech.com , 但是這個域名已經不可用了,所以用dubbo舊版本的需要注意下這個問題(參考https://blog.csdn.net/huweijun_2012/article/details/80239803)
但是現在2.6.2以上都版本都不出現這個問題了,spring.handlers 中的配置還是之前的域名 包含舊的和新的域名,相當于可以兼容。但是由于code.alibabatech.com 域名已經不可用,所以解決辦法只能是在pom.xml文件中修改dubbo的版本,使用至少2.6.2以上版本就不會出現此問題。
感謝各位的閱讀,以上就是“怎么用Dubbo+Zookeeper+Spring實現Demo”的內容了,經過本文的學習后,相信大家對怎么用Dubbo+Zookeeper+Spring實現Demo這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。