1. 分布式
- 什么是分布式:
分布式或者說(shuō)SOA分布式重要的就是面向服務(wù)殴俱,簡(jiǎn)單地說(shuō)分布式就是把整個(gè)系統(tǒng)拆分成不同的服務(wù)敛摘,然后將這些服務(wù)放在不同的服務(wù)器上削茁,以減輕單體服務(wù)的壓力提高并發(fā)量和性能聪建。如果某一個(gè)服務(wù)的訪問(wèn)量較大的話也可以將這個(gè)服務(wù)同時(shí)部署在多臺(tái)機(jī)器上略贮。 - 為什么使用分布式:
- 從開(kāi)發(fā)者角度來(lái)講單體應(yīng)用的代碼都集中在一起甚疟,而分布式系統(tǒng)的代碼根據(jù)業(yè)務(wù)被拆分。所以逃延,每個(gè)團(tuán)隊(duì)可以負(fù)責(zé)一個(gè)服務(wù)的開(kāi)發(fā)古拴,這樣提升了開(kāi)發(fā)效率。另外真友,代碼根據(jù)不同業(yè)務(wù)被拆分以后更加便于維護(hù)和擴(kuò)展黄痪。
- 把整個(gè)系統(tǒng)拆分成不同的服務(wù)/系統(tǒng),然后每個(gè)服務(wù)/系統(tǒng)部署在不同的機(jī)器上盔然,將會(huì)很大程度提升服務(wù)性能桅打。
- 不同的服務(wù)/系統(tǒng)之間的協(xié)同工作就要用到高性能的RPC框架 dubbo。dubbo作為分布式系統(tǒng)的橋梁愈案。
2. RPC框架
2.1 什么是RPC框架
- RPC(Remote Procedure Call)——遠(yuǎn)程過(guò)程調(diào)用挺尾,它是一種通過(guò)網(wǎng)絡(luò),從遠(yuǎn)程計(jì)算機(jī)上請(qǐng)求服務(wù)站绪,而不需要了解低層網(wǎng)絡(luò)技術(shù)的協(xié)議遭铺。
- RPC 協(xié)議假定某些傳輸協(xié)議的存在,如TCP或UDP恢准,為通信程序之間攜帶信息數(shù)據(jù)魂挂。在OSI網(wǎng)絡(luò)通信模型中,RPC跨越了傳輸層和應(yīng)用層馁筐。RPC使得開(kāi)發(fā)分布式程序就像開(kāi)發(fā)本地程序一樣簡(jiǎn)單涂召。
- RPC采用客戶端(服務(wù)調(diào)用方)/服務(wù)器端(服務(wù)提供方)模式,都運(yùn)行在自己的JVM中敏沉」客戶端只需要引入要使用的接口炎码,接口的實(shí)現(xiàn)和運(yùn)行都在服務(wù)器端。RPC主要依賴的技術(shù)包括序列化秋泳、反序列化潦闲、數(shù)據(jù)傳輸協(xié)議,這是一種定義與實(shí)現(xiàn)相分離的設(shè)計(jì)迫皱。
- 比如兩個(gè)不同的服務(wù)A歉闰、B部署在兩臺(tái)不同的機(jī)器上,那么服務(wù)A想要調(diào)用服務(wù)B中的某個(gè)方法怎么辦呢舍杜?使用HTTP請(qǐng)求可以,但是可能會(huì)比較慢而且一些優(yōu)化做得不好赵辕。RPC的出現(xiàn)就是為了解決這個(gè)問(wèn)題既绩。
- 目前Java使用較多的RPC方案主要有RMI(JDK自帶)、Hessian还惠、Dubbo饲握、Thrift等。
注意:RPC主要指內(nèi)部服務(wù)之間的調(diào)用蚕键,RESTful也可以用于內(nèi)部服務(wù)之間的調(diào)用救欧,但其主要用途還在于外部系統(tǒng)提供服務(wù)。
2.2 RPC的原理
- 服務(wù)消費(fèi)方(client)以本地調(diào)用方式調(diào)用服務(wù)锣光;
- client stub 接收到調(diào)用后負(fù)責(zé)將方法、參數(shù)等組裝成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw;(序列化用于傳輸?shù)臄?shù)據(jù)結(jié)構(gòu)虱黄、對(duì)象)
- client stub 找到服務(wù)地址畴博,并將消息發(fā)送到服務(wù)端;
- server stub 接到消息后進(jìn)行解碼频丘;(反序列化)
- server stub 根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)办成;
- 本地服務(wù)執(zhí)行并將結(jié)果返回給server stub;
- server stub 將返回結(jié)果打包成消息并發(fā)送至消費(fèi)方搂漠;(序列化)
- client stub 接收到消息迂卢,并進(jìn)行解碼;(反序列化)
-
服務(wù)消費(fèi)方得到最終結(jié)果桐汤;
1570506169241.png
2.3 常見(jiàn)RPC框架
RMI(JDK自帶)
-
Dubbo
基于TCP協(xié)議
-
Hessian
基于HTTP協(xié)議
Hessian是一個(gè)輕量級(jí)的remotingohttp工具而克,使用最簡(jiǎn)單的方法提供了RMI的功能。相比WebService怔毛,Hessian更簡(jiǎn)單拍摇、快捷。采用的是二進(jìn)制RPC協(xié)議馆截,因?yàn)椴捎玫氖嵌M(jìn)制協(xié)議充活,所以它很適合發(fā)送二進(jìn)制數(shù)據(jù)蜂莉。
-
Thrift
基于TCP協(xié)議
Apache Thrift是facebook開(kāi)源的跨語(yǔ)言的RPC通信框架。由于其跨語(yǔ)言特性和出色的性能混卵,在很多互聯(lián)網(wǎng)公司得到應(yīng)用映穗。有能力的公司甚至?xí)趖hrift研發(fā)一套分布式服務(wù)框架,增加諸如服務(wù)注冊(cè)幕随、服務(wù)發(fā)現(xiàn)等功能蚁滋。
如何進(jìn)行選擇:
- 是否允許代碼侵入:即需要響應(yīng)的代碼生成器生成相應(yīng)的代碼,比如Thrift赘淮;
- 是否需要長(zhǎng)連接獲取高性能:如果對(duì)于性能需求較高的haul辕录,那么可以果斷選擇基于TCP的Thrift、Dubbo梢卸;
- 是否需要跨越網(wǎng)段走诞、跨越防火墻:這種情況一般選擇基于HTTP協(xié)議的Hessian和Thrift的HTTP Transport。
3. dubbo
3.1 Dubbo簡(jiǎn)介
Apache Dubbo 是一款高性能蛤高、輕量級(jí)的開(kāi)源java RPC框架蚣旱,它提供了三大核心能力:
- 面向接口的遠(yuǎn)程方法調(diào)用;
- 智能容錯(cuò)和負(fù)載均衡戴陡;
- 服務(wù)自動(dòng)注冊(cè)和發(fā)現(xiàn)塞绿。
簡(jiǎn)單來(lái)說(shuō)Dubbo是一個(gè)分布式服務(wù)框架,致力于提供高性能和透明化的RPC遠(yuǎn)程服務(wù)調(diào)用方案恤批,以及SOA服務(wù)治理方案异吻。
3.2 why dubbo
Dubbo的誕生和SOA分布式架構(gòu)的流行有著莫大的關(guān)系。
SOA(Service Oriented Architecture)面向服務(wù)架構(gòu):也就是把工程按照業(yè)務(wù)邏輯拆分成服務(wù)層喜庞、表現(xiàn)層兩個(gè)工程涧黄。服務(wù)層中包含業(yè)務(wù)邏輯,只需要對(duì)外提供服務(wù)即可赋荆。表現(xiàn)層只需要處理和頁(yè)面的交互笋妥,業(yè)務(wù)邏輯都是調(diào)用服務(wù)層的服務(wù)來(lái)實(shí)現(xiàn)。SOA架構(gòu)中有兩個(gè)主要的角色:服務(wù)提供者(provider)和服務(wù)消費(fèi)者(consumer)窄潭。
如果要開(kāi)發(fā)分布式程序春宣,也可以直接基于HTTP接口進(jìn)行通信,但是為什么要用dubbo呢嫉你? 因?yàn)閐ubbo提供以下四種特性:
- 負(fù)載均衡——同一個(gè)服務(wù)部署在不同的機(jī)器時(shí)該調(diào)用哪一臺(tái)機(jī)器上的服務(wù)月帝;
- 服務(wù)調(diào)用鏈路生成——隨著系統(tǒng)的發(fā)展,服務(wù)越來(lái)越多幽污,服務(wù)間依賴關(guān)系變得錯(cuò)綜復(fù)雜嚷辅,甚至分不清哪個(gè)應(yīng)用要在哪個(gè)應(yīng)用之前啟動(dòng)。Dubbo可以為我們解決服務(wù)之間互相是如何調(diào)用的距误;
- 服務(wù)訪問(wèn)壓力以及時(shí)長(zhǎng)統(tǒng)計(jì)簸搞、資源調(diào)度和治理——基于訪問(wèn)壓力實(shí)時(shí)管理集群容量扁位,提供集群利用率;
- 服務(wù)降級(jí)——某個(gè)服務(wù)掛掉后調(diào)用備用服務(wù)趁俊;
良好的RPC調(diào)用是面向服務(wù)的封裝域仇,針對(duì)服務(wù)的可用性和效率等都做了優(yōu)化,單純的使用http調(diào)用則缺少了這些特性寺擂。
3.3 dubbo框架
節(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)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心
- Container:服務(wù)運(yùn)行容器
注冊(cè)中心Registry:
一個(gè)完整的dubbo應(yīng)該是包括注冊(cè)中心的暇务。
注冊(cè)中心用來(lái)注冊(cè)服務(wù)和進(jìn)行負(fù)載均衡,哪一個(gè)服務(wù)由哪一個(gè)機(jī)器來(lái)提供必需讓調(diào)用者知道怔软,簡(jiǎn)單來(lái)說(shuō)就是IP地址和服務(wù)名稱的對(duì)應(yīng)關(guān)系垦细。
dubbo官方提供了幾種實(shí)現(xiàn)注冊(cè)中心的方式:
- Multicast 注冊(cè)中心;
- Zookeeper 注冊(cè)中心挡逼;
- Redis 注冊(cè)中心括改;
- Simple 注冊(cè)中心;
調(diào)用關(guān)系說(shuō)明:
- 服務(wù)容器負(fù)責(zé)啟動(dòng)挚瘟、加載叹谁,運(yùn)行服務(wù)提供者饲梭;
- 服務(wù)提供者在啟動(dòng)時(shí)乘盖,向注冊(cè)中心注冊(cè)自己提供的服務(wù);
- 服務(wù)消費(fèi)者在啟動(dòng)時(shí)憔涉,向注冊(cè)中心訂閱自己所需要的服務(wù)订框;
- 注冊(cè)中心返回服務(wù)提供者地址列表給消費(fèi)者,如果有變更兜叨,注冊(cè)中心將基于長(zhǎng)連接推送變更數(shù)據(jù)給服務(wù)消費(fèi)者穿扳;
- 服務(wù)消費(fèi)者,從提供者地址列表中国旷,基于軟負(fù)載均衡算法矛物,選一臺(tái)提供者進(jìn)行調(diào)用,如果調(diào)用失敗跪但,再選另一臺(tái)進(jìn)行調(diào)用履羞;
- 服務(wù)消費(fèi)者和提供者,在內(nèi)存中累計(jì)調(diào)用次數(shù)和調(diào)用時(shí)間屡久,定時(shí)每分鐘發(fā)送一次統(tǒng)計(jì)數(shù)據(jù)到監(jiān)控中心忆首;
重要知識(shí)點(diǎn)總結(jié):
- 注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù)被环,服務(wù)提供者和消費(fèi)者只在啟動(dòng)時(shí)與注冊(cè)中心交互糙及,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較猩富丁浸锨;
- 監(jiān)控中心負(fù)責(zé)統(tǒng)計(jì)各服務(wù)調(diào)用次數(shù)唇聘、調(diào)用時(shí)間等,統(tǒng)計(jì)現(xiàn)在內(nèi)存匯總后每分鐘一次發(fā)送到監(jiān)控中心服務(wù)器揣钦,并以報(bào)表展示雳灾;
- 注冊(cè)中心、服務(wù)提供者冯凹、服務(wù)消費(fèi)者三者之間均為長(zhǎng)連接谎亩,監(jiān)控中心除外;
- 注冊(cè)中心通過(guò)長(zhǎng)連接感知服務(wù)提供者的存在宇姚,服務(wù)提供者宕機(jī)匈庭,注冊(cè)中心將立即推送事件通知消費(fèi)者;
- 注冊(cè)中心和監(jiān)控中心全部宕機(jī)浑劳,不影響已運(yùn)行的提供者和消費(fèi)者阱持,消費(fèi)者在本地緩存了服務(wù)提供者列表;
- 注冊(cè)中心和監(jiān)控中心都是可選的魔熏,服務(wù)消費(fèi)者可以直連服務(wù)提供者衷咽;
- 服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后蒜绽,不影響使用镶骗;
- 服務(wù)提供者全部宕掉后,服務(wù)消費(fèi)者應(yīng)用將無(wú)法使用躲雅,并無(wú)限次重連等待服務(wù)提供者恢復(fù)鼎姊;
3.4 Dubbo工作原理
各層說(shuō)明:
- service層:接口層,給服務(wù)提供者和消費(fèi)者來(lái)實(shí)現(xiàn)的相赁;
- config層:配置層相寇,主要是對(duì)dubbo進(jìn)行各種配置的;
- proxy層:服務(wù)接口透明代理钮科,生成服務(wù)的客戶端Stub和服務(wù)器端Skeleton唤衫;
- registry層:服務(wù)注冊(cè)層,負(fù)責(zé)服務(wù)的注冊(cè)與發(fā)現(xiàn)绵脯;
- cluster層:集群層佳励,封裝多個(gè)服務(wù)提供者的路由以及負(fù)載均衡,將多個(gè)實(shí)例組合成一個(gè)服務(wù)桨嫁;
- monitor層:監(jiān)控層植兰,對(duì)RPC接口的調(diào)用次數(shù)和調(diào)用時(shí)間進(jìn)行監(jiān)控;
- protocol層:遠(yuǎn)程調(diào)用層璃吧,封裝RPC調(diào)用楣导;
- exchange層:信息交換層,封裝請(qǐng)求響應(yīng)模式畜挨,同步轉(zhuǎn)異步筒繁;
- transport層:網(wǎng)絡(luò)傳輸層噩凹,抽象mina和netty為統(tǒng)一接口;
- serialize層:數(shù)據(jù)序列化層毡咏,網(wǎng)絡(luò)傳輸需要驮宴;
從下至上分為十層,各層均為單向依賴呕缭,每一層都可以剝離上一層被復(fù)用堵泽,其中,Service 和 Config 層為API恢总,其它各層均為API迎罗。
3.5 Dubbo負(fù)載均衡策略
負(fù)載均衡通俗解釋?zhuān)?/strong>
比如我們系統(tǒng)中某個(gè)服務(wù)的訪問(wèn)量特別大,我們將這個(gè)服務(wù)部署在多臺(tái)機(jī)器上片仿,當(dāng)客戶端發(fā)起請(qǐng)求的時(shí)候纹安,多臺(tái)服務(wù)器都可以處理這個(gè)請(qǐng)求,那么砂豌,如何正確選擇處理該請(qǐng)求的服務(wù)器就很關(guān)鍵厢岂。假如只需要一臺(tái)服務(wù)器來(lái)處理全部請(qǐng)求,那該服務(wù)部署在多臺(tái)服務(wù)器的意義就不復(fù)存在了阳距。
負(fù)載均衡就是為了避免單個(gè)服務(wù)器響應(yīng)同一請(qǐng)求塔粒,容易造成服務(wù)器宕機(jī),崩潰等問(wèn)題娄涩。
Dubbo 的負(fù)責(zé)均衡策略:
在集群負(fù)載均衡時(shí)窗怒,Dubbo提供了多種均衡策略映跟,默認(rèn)為random隨機(jī)調(diào)用蓄拣。可以自行擴(kuò)展負(fù)載均衡策略努隙。
3.5.1 Random LoadBalance
默認(rèn)的負(fù)載均衡策略球恤,基于權(quán)重的隨機(jī)負(fù)載均衡機(jī)制;
-
在一個(gè)界面上碰撞概率高荸镊,但調(diào)用量越大分布越均勻咽斧,而且按概率使用權(quán)重后也比較均勻,有利于動(dòng)態(tài)調(diào)整提供者權(quán)重躬存。
1570591465252.png
3.5.2 RoundRobin LoadBalance
- 輪詢张惹,按公約后的權(quán)重設(shè)置輪詢比率(不推薦,基于權(quán)重的輪詢負(fù)載均衡機(jī)制)
- 算法原理:生成一個(gè)服務(wù)器序列岭洲,每當(dāng)有請(qǐng)求到來(lái)時(shí)宛逗,就依次從該序列中取出下一個(gè)服務(wù)器用于處理該請(qǐng)求。比如上面的例子盾剩,基于權(quán)重的輪詢算法會(huì)生成序列{1雷激,2替蔬,3,1屎暇,2承桥,2,2}根悼,這樣凶异,每收到7個(gè)請(qǐng)求,會(huì)把其中的2個(gè)轉(zhuǎn)發(fā)給service 1挤巡,把其中的4個(gè)轉(zhuǎn)發(fā)給service 2唠帝,把其中的1個(gè)轉(zhuǎn)發(fā)給service 3,收到第8個(gè)請(qǐng)求玄柏,重新從該序列的頭部開(kāi)始輪詢襟衰。
- 存在慢的提供者累積請(qǐng)求的問(wèn)題,比如:第二臺(tái)機(jī)器很慢粪摘,但沒(méi)掛瀑晒,當(dāng)請(qǐng)求調(diào)到第二臺(tái)時(shí)就卡在那兒,久而久之徘意,所有請(qǐng)求都卡在第二臺(tái)上苔悦。
3.5.3 LeastActive LoadBalance
- 最少活躍調(diào)用數(shù),相同活躍數(shù)的隨機(jī)椎咧,活躍數(shù)指調(diào)用前后計(jì)數(shù)差玖详。
- 使慢的提供者收到更少請(qǐng)求,因?yàn)樵铰奶峁┱叩恼{(diào)用前后計(jì)數(shù)差會(huì)越大勤讽。
3.5.4 ConsistenHash LoadBalance
- 一致性Hash蟋座,相同參數(shù)的請(qǐng)求總是發(fā)到同一服務(wù)提供者。(如果你需要的不是隨機(jī)負(fù)載均衡脚牍,是要一類(lèi)請(qǐng)求都到一個(gè)節(jié)點(diǎn)向臀,那就走這個(gè)一致性hash策略)
- 當(dāng)某一臺(tái)服務(wù)提供者掛掉時(shí),原本發(fā)往該提供者的請(qǐng)求诸狭,基于虛擬節(jié)點(diǎn)券膀,平攤到其他提供者,不會(huì)引起劇烈變動(dòng)驯遇。
3.6 zookeeper宕機(jī)與dubbo直連的情況
在實(shí)際生產(chǎn)中芹彬,假如zookeeper注冊(cè)中心宕掉,一段時(shí)間內(nèi)服務(wù)消費(fèi)方還是能夠調(diào)用服務(wù)提供方的服務(wù)的叉庐,實(shí)際上它使用的是本地緩存進(jìn)行通訊舒帮,這只是dubbo健壯性的一種體現(xiàn)。
dubbo健壯性表現(xiàn):
- 監(jiān)控中心宕掉不影響使用,只是丟失部分采樣數(shù)據(jù)会前;
- 數(shù)據(jù)庫(kù)宕掉后好乐,注冊(cè)中心仍然能通過(guò)緩存提供服務(wù)列表查詢,但不能注冊(cè)新服務(wù)瓦宜;
- 注冊(cè)中心對(duì)等集群蔚万,任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)临庇;
- 注冊(cè)中心全部宕掉后反璃,服務(wù)提供者和服務(wù)消費(fèi)者仍能通過(guò)本地緩存通訊;
- 服務(wù)提供者無(wú)狀態(tài)假夺,任意一臺(tái)宕掉后淮蜈,不影響使用;
- 服務(wù)提供者全部宕掉后已卷,服務(wù)消費(fèi)者應(yīng)用將無(wú)法使用梧田,并無(wú)限次重連等待服務(wù)提供者恢復(fù)。
前面提到:注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找侧蘸,相當(dāng)于目錄服務(wù)裁眯,服務(wù)提供者和消費(fèi)者只在啟動(dòng)的時(shí)候與注冊(cè)中心交互,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求讳癌,壓力較小穿稳。所以,我們可以完全繞過(guò)注冊(cè)中心——采用dubbo直連晌坤,即在服務(wù)消費(fèi)方配置服務(wù)提供方的位置信息逢艘。
<dubbo:reference id="userService" interface="com.zang.gmall.service.UserService" url="dubbo://localhost:20880" />