不久前达舒,我們討論過(guò)Nginx+tomcat組成的集群灿渴,這已經(jīng)是非常靈活的集群技術(shù),但是當(dāng)我們的系統(tǒng)遇到更大的瓶頸艺沼,全部應(yīng)用的單點(diǎn)服務(wù)器已經(jīng)不能滿足我們的需求册舞,這時(shí),我們要考慮另外一種澳厢,我們熟悉的內(nèi)容环础,就是分布式囚似,而當(dāng)下流行的Dubbo框架,不容我們忽視线得,這里饶唤,咱們一起來(lái)探討一下這個(gè)框架的使用。
一贯钩,背景
以前我們需要遠(yuǎn)程調(diào)用他人的接口募狂,我們是這么做的:
我們遇到的問(wèn)題:
(1) 當(dāng)服務(wù)越來(lái)越多時(shí),服務(wù)URL配置管理變得非常困難角雷,F(xiàn)5硬件負(fù)載均衡器的單點(diǎn)壓力也越來(lái)越大祸穷。
此時(shí)需要一個(gè)服務(wù)注冊(cè)中心,動(dòng)態(tài)的注冊(cè)和發(fā)現(xiàn)服務(wù)勺三,使服務(wù)的位置透明雷滚。
并通過(guò)在消費(fèi)方獲取服務(wù)提供方地址列表,實(shí)現(xiàn)軟負(fù)載均衡和Failover吗坚,降低對(duì)F5硬件負(fù)載均衡器的依賴祈远,也能減少部分成本。
(2) 當(dāng)進(jìn)一步發(fā)展商源,服務(wù)間依賴關(guān)系變得錯(cuò)蹤復(fù)雜车份,甚至分不清哪個(gè)應(yīng)用要在哪個(gè)應(yīng)用之前啟動(dòng),架構(gòu)師都不能完整的描述應(yīng)用的架構(gòu)關(guān)系牡彻。
這時(shí)扫沼,需要自動(dòng)畫出應(yīng)用間的依賴關(guān)系圖,以幫助架構(gòu)師理清理關(guān)系庄吼。
(3) 接著缎除,服務(wù)的調(diào)用量越來(lái)越大,服務(wù)的容量問(wèn)題就暴露出來(lái)霸褒,這個(gè)服務(wù)需要多少機(jī)器支撐伴找?什么時(shí)候該加機(jī)器?
為了解決這些問(wèn)題废菱,第一步技矮,要將服務(wù)現(xiàn)在每天的調(diào)用量,響應(yīng)時(shí)間殊轴,都統(tǒng)計(jì)出來(lái)衰倦,作為容量規(guī)劃的參考指標(biāo)。
其次旁理,要可以動(dòng)態(tài)調(diào)整權(quán)重樊零,在線上,將某臺(tái)機(jī)器的權(quán)重一直加大,并在加大的過(guò)程中記錄響應(yīng)時(shí)間的變化驻襟,直到響應(yīng)時(shí)間到達(dá)閥值夺艰,記錄此時(shí)的訪問(wèn)量,再以此訪問(wèn)量乘以機(jī)器數(shù)反推總?cè)萘俊?/p>
為解決這些問(wèn)題沉衣,Dubbo為我們做了什么呢:
負(fù)載均衡:
這就是所謂的軟負(fù)載均衡郁副!
現(xiàn)在讓我們一起來(lái)接觸下這個(gè)優(yōu)秀的框架:
簡(jiǎn)介
架構(gòu)如圖:
節(jié)點(diǎn)角色說(shuō)明:
Provider:暴露服務(wù)的服務(wù)提供方。
Consumer:調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方豌习。
Registry:服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心存谎。
Monitor:統(tǒng)計(jì)服務(wù)的調(diào)用次調(diào)和調(diào)用時(shí)間的監(jiān)控中心。
Container:服務(wù)運(yùn)行容器肥隆。
調(diào)用關(guān)系說(shuō)明:
0.服務(wù)容器負(fù)責(zé)啟動(dòng)既荚,加載,運(yùn)行服務(wù)提供者栋艳。
1.服務(wù)提供者在啟動(dòng)時(shí)恰聘,向注冊(cè)中心注冊(cè)自己提供的服務(wù)。
2.服務(wù)消費(fèi)者在啟動(dòng)時(shí)吸占,向注冊(cè)中心訂閱自己所需的服務(wù)憨琳。
3.注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更旬昭,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給消費(fèi)者。
4.服務(wù)消費(fèi)者菌湃,從提供者地址列表中问拘,基于軟負(fù)載均衡算法,選一臺(tái)提供者進(jìn)行調(diào)用惧所,如果調(diào)用失敗骤坐,再選另一臺(tái)調(diào)用。
5.服務(wù)消費(fèi)者和提供者下愈,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間纽绍,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心。
Dubbo提供了很多協(xié)議势似,Dubbo協(xié)議拌夏、RMI協(xié)議、Hessian協(xié)議履因,我們查看Dubbo源代碼障簿,有各種協(xié)議的實(shí)現(xiàn),如圖所示:
我們之前沒(méi)用Dubbo之前時(shí)栅迄,大部分都使用Hessian來(lái)使用我們服務(wù)的暴露和調(diào)用站故,利用HessianProxyFactory調(diào)用遠(yuǎn)程接口。
上面是參考了Dubbo官方網(wǎng)介紹毅舆,接下來(lái)我們來(lái)介紹SpringMVC西篓、Dubbo愈腾、Zookeeper整合使用。
第三:Dubbo與Zookeeper岂津、SpringMVC整合使用
第一步:在Linux上安裝Zookeeper
Zookeeper作為Dubbo服務(wù)的注冊(cè)中心虱黄,Dubbo原先基于數(shù)據(jù)庫(kù)的注冊(cè)中心,沒(méi)采用Zookeeper寸爆,Zookeeper一個(gè)分布式的服務(wù)框架礁鲁,是樹(shù)型的目錄服務(wù)的數(shù)據(jù)存儲(chǔ),能做到集群管理數(shù)據(jù)?赁豆,這里能很好的作為Dubbo服務(wù)的注冊(cè)中心仅醇,Dubbo能與Zookeeper做到集群部署,當(dāng)提供者出現(xiàn)斷電等異常停機(jī)時(shí)魔种,Zookeeper注冊(cè)中心能自動(dòng)刪除提供者信息析二,當(dāng)提供者重啟時(shí),能自動(dòng)恢復(fù)注冊(cè)數(shù)據(jù)节预,以及訂閱請(qǐng)求叶摄。我們先在linux上安裝Zookeeper,我們安裝最簡(jiǎn)單的單點(diǎn)安拟,集群比較麻煩蛤吓。
先需要安裝JdK,從Oracle的Java網(wǎng)站下載糠赦,安裝很簡(jiǎn)單会傲,就不再詳述。
單機(jī)模式
單機(jī)安裝非常簡(jiǎn)單拙泽,只要獲取到 Zookeeper 的壓縮包并解壓到某個(gè)目錄如:C:/zookeeper-3.4.5/下淌山,Zookeeper 的啟動(dòng)腳本在 bin 目錄下,Windows 下的啟動(dòng)腳本是 zkServer.cmd顾瞻。
在你執(zhí)行啟動(dòng)腳本之前泼疑,還有幾個(gè)基本的配置項(xiàng)需要配置一下,Zookeeper 的配置文件在 conf 目錄下荷荤,這個(gè)目錄下有 zoo_sample.cfg 和 log4j.properties退渗,你需要做的就是將 zoo_sample.cfg 改名為 zoo.cfg,因?yàn)?Zookeeper 在啟動(dòng)時(shí)會(huì)找這個(gè)文件作為默認(rèn)配置文件梅猿。下面詳細(xì)介紹一下氓辣,這個(gè)配置文件中各個(gè)配置項(xiàng)的意義。
# 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=C://zookeeper-3.4.5//data dataLogDir=C://zookeeper-3.4.5//log # the port at which the clients will connect clientPort=2181 # # 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 # # The number of snapshots to retain in dataDir #autopurge.snapRetainCount=3 # Purge task interval in hours # Set to "0" to disable auto purge feature #autopurge.purgeInterval=1
tickTime:這個(gè)時(shí)間是作為 Zookeeper 服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時(shí)間間隔袱蚓,也就是每個(gè) tickTime 時(shí)間就會(huì)發(fā)送一個(gè)心跳钞啸。
dataDir:顧名思義就是 Zookeeper 保存數(shù)據(jù)的目錄,默認(rèn)情況下,Zookeeper 將寫數(shù)據(jù)的日志文件也保存在這個(gè)目錄里体斩。
dataLogDir:顧名思義就是 Zookeeper 保存日志文件的目錄
clientPort:這個(gè)端口就是客戶端連接 Zookeeper 服務(wù)器的端口梭稚,Zookeeper 會(huì)監(jiān)聽(tīng)這個(gè)端口,接受客戶端的訪問(wèn)請(qǐng)求絮吵。
當(dāng)這些配置項(xiàng)配置好后弧烤,你現(xiàn)在就可以啟動(dòng) Zookeeper 了,啟動(dòng)后要檢查 Zookeeper 是否已經(jīng)在服務(wù)蹬敲,可以通過(guò) netstat – ano 命令查看是否有你配置的 clientPort 端口號(hào)在監(jiān)聽(tīng)服務(wù)暇昂。
第二步:配置dubbo-admin的管理頁(yè)面,方便我們管理頁(yè)面
(1)下載dubbo-admin-2.4.1.war包伴嗡,在windows的tomcat部署急波,先把dubbo-admin-2.4.1放在tomcat的webapps/ROOT下,然后進(jìn)行解壓
(2)然后到webapps/ROOT/WEB-INF下瘪校,有一個(gè)dubbo.properties文件澄暮,里面指向Zookeeper?,使用的是Zookeeper?的注冊(cè)中心阱扬,如圖所示:
dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.admin.root.password=root dubbo.admin.guest.password=guest
(3)然后啟動(dòng)tomcat服務(wù)泣懊,用戶名和密碼:root,并訪問(wèn)服務(wù),顯示登陸頁(yè)面麻惶,說(shuō)明dubbo-admin部署成功馍刮,如圖所示:
第三步:SpringMVC與Dubbo的整合,這邊使用的Maven的管理項(xiàng)目
第一:我們先開(kāi)發(fā)服務(wù)注冊(cè)的窃蹋,就是提供服務(wù)渠退,項(xiàng)目結(jié)構(gòu)如圖所示:
(1)test-maven-api項(xiàng)目加入了一個(gè)服務(wù)接口,代碼如下:
public interface TestRegistryService {? ? public String hello(String name); }
(2)test-maven-console在pom.xml加入Dubbo和Zookeeper的jar包脐彩、引用test-maven-api的jar包,代碼如下:
? ? cn.test? ? test-maven-api? ? 0.0.1-SNAPSHOT? ? ? ? ? ? ? ? ? ? ? ? ? com.alibaba? ? ? ? ? ? dubbo? ? ? ? ? ? 2.5.3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.apache.zookeeper? ? zookeeper? ? 3.4.6? ? ? ? ? ? ? ? ? ? ? ? ? com.github.sgroschupf? ? zkclient? ? 0.1
(3)test-maven-console實(shí)現(xiàn)具體的服務(wù)姊扔,代碼如下:
@Service("testRegistryService") public class TestRegistryServiceImpl implements TestRegistryService {? public String hello(String name) {? ? return "hello"+name;? } }
(4)我們服務(wù)以及實(shí)現(xiàn)好了惠奸,這時(shí)要暴露服務(wù),代碼如下:
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"? xmlns:context="http://www.springframework.org/schema/context"? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd? http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd? http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd? http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"? default-lazy-init="false" >? ? ? ? ? ? ? ? ? ? ? ? ? ?
說(shuō)明:
dubbo:registry標(biāo)簽一些屬性的說(shuō)明:
1)register是否向此注冊(cè)中心注冊(cè)服務(wù)恰梢,如果設(shè)為false佛南,將只訂閱,不注冊(cè)嵌言。
2)check注冊(cè)中心不存在時(shí)嗅回,是否報(bào)錯(cuò)。
3)subscribe是否向此注冊(cè)中心訂閱服務(wù)摧茴,如果設(shè)為false绵载,將只注冊(cè),不訂閱。
4)timeout注冊(cè)中心請(qǐng)求超時(shí)時(shí)間(毫秒)娃豹。
5)address可以Zookeeper集群配置焚虱,地址可以多個(gè)以逗號(hào)隔開(kāi)等。
dubbo:service標(biāo)簽的一些屬性說(shuō)明:
1)interface服務(wù)接口的路徑
2)ref引用對(duì)應(yīng)的實(shí)現(xiàn)類的Bean的ID
3)registry向指定注冊(cè)中心注冊(cè)懂版,在多個(gè)注冊(cè)中心時(shí)使用鹃栽,值為的id屬性,多個(gè)注冊(cè)中心ID用逗號(hào)分隔躯畴,如果不想將該服務(wù)注冊(cè)到任何registry民鼓,可將值設(shè)為N/A
4)register?默認(rèn)true?,該協(xié)議的服務(wù)是否注冊(cè)到注冊(cè)中心蓬抄。
(5)啟動(dòng)項(xiàng)目丰嘉,然后我們?cè)贒ubbo管理頁(yè)面上顯示,已經(jīng)暴露的服務(wù)倡鲸,但顯示還沒(méi)有消費(fèi)者供嚎,因?yàn)槲覀冞€沒(méi)實(shí)現(xiàn)消費(fèi)者服務(wù),如圖所示:
第二:我們?cè)陂_(kāi)發(fā)服務(wù)消費(fèi)者峭状,就是調(diào)用服務(wù)克滴,我們?cè)谛陆ㄒ粋€(gè)新的消費(fèi)者項(xiàng)目:
(1)test-maven-server-console的pom.xml引入Dubbo和Zookeeper的jar包、test-maven-api的jar包优床,因?yàn)橐雝est-maven-api的jar包劝赔,我們?cè)陧?xiàng)目中調(diào)用像在本地調(diào)用一樣。代碼如下:
? ? cn.test? ? test-maven-api? ? 0.0.1-SNAPSHOT? ? ? ? ? ? ? ? ? ? ? ? ? com.alibaba? ? ? ? ? ? dubbo? ? ? ? ? ? 2.5.3? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? org.apache.zookeeper? ? zookeeper? ? 3.4.6? ? ? ? ? ? ? ? ? ? ? ? ? com.github.sgroschupf? ? zkclient? ? 0.1
(2)test-maven-server-console項(xiàng)目的具體實(shí)現(xiàn)胆敞,代碼如下:
@Controller public class IndexController {? ? @Autowired? private TestRegistryService testRegistryService;? ? @RequestMapping("/hello")? public String index(Model model){? ? ? String name=testRegistryService.hello("zz");? ? ? System.out.println("xx=="+name);? return "";? }? }
(3)我們要引用的地址着帽,代碼如下:
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"? xmlns:context="http://www.springframework.org/schema/context"? xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd? http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd? http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd? http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd? http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"? default-lazy-init="false" >? ? ? ? ? ? ? ? ? ? ? ? ?
說(shuō)明:
dubbo:reference的一些屬性的說(shuō)明:
1)interface調(diào)用的服務(wù)接口
2)check?啟動(dòng)時(shí)檢查提供者是否存在,true報(bào)錯(cuò)移层,false忽略
3)registry從指定注冊(cè)中心注冊(cè)獲取服務(wù)列表仍翰,在多個(gè)注冊(cè)中心時(shí)使用,值為的id屬性观话,多個(gè)注冊(cè)中心ID用逗號(hào)分隔
4)loadbalance?負(fù)載均衡策略予借,可選值:random,roundrobin,leastactive,分別表示:隨機(jī)频蛔,輪循灵迫,最少活躍調(diào)用
(4)項(xiàng)目啟動(dòng),Dubbo管理頁(yè)面晦溪,能看到消費(fèi)者瀑粥,如圖所示:
(5)然后訪問(wèn)消費(fèi)者項(xiàng)目,Controller層能像調(diào)用本地一樣調(diào)用服務(wù)的具體實(shí)現(xiàn)三圆,如圖所示:
總結(jié):
經(jīng)過(guò)一系列的操作之后狞换,我們感覺(jué)避咆,的確很簡(jiǎn)單,dubbo給我們封裝了很多操作哀澈,讓我們不需要過(guò)多考慮具體的實(shí)現(xiàn)細(xì)節(jié)牌借,配置化生成咱們的應(yīng)用,這樣的思想割按,現(xiàn)在在IT行業(yè)正在盛行膨报!
核心技術(shù):Maven,Springmvc mybatis shiro, Druid, Restful, Dubbo, ZooKeeper,Redis,FastDFS,ActiveMQ,Nginx
1.?????項(xiàng)目核心代碼結(jié)構(gòu)截圖
項(xiàng)目模塊依賴
特別提醒:開(kāi)發(fā)人員在開(kāi)發(fā)的時(shí)候可以將自己的業(yè)務(wù)REST服務(wù)化或者Dubbo服務(wù)化
2.????項(xiàng)目依賴介紹
2.1?后臺(tái)管理系統(tǒng)、Rest服務(wù)系統(tǒng)适荣、Scheculer定時(shí)調(diào)度系統(tǒng)依賴如下圖:
2.2?Dubbo獨(dú)立服務(wù)項(xiàng)目依賴如下圖:
3.??項(xiàng)目功能部分截圖:
zookeeper现柠、dubbo服務(wù)啟動(dòng)
dubbo管控臺(tái)
REST服務(wù)平臺(tái)