Dubbo(服務(wù)治理框架)
RPC
各服務(wù)都要實現(xiàn)rpc協(xié)議,才能實現(xiàn)服務(wù)間的調(diào)用
rpc:遠程過程調(diào)用協(xié)議屎勘,是一種通過網(wǎng)絡(luò)從遠程計算機程序上請求服務(wù)
-
rpc原理:就是對象的序列化施籍,反序列化以及序列化后數(shù)據(jù)的傳輸 rpc底層原理.png
和Feign的區(qū)別:微服務(wù)中遠程調(diào)用Dubbo與Feign對比 - 懸鈴木pp - 博客園 (cnblogs.com)
-
注冊中心的作用
消費者根據(jù)我服務(wù)的名字調(diào)用服務(wù)就好,具體服務(wù)是放在哪里的不用關(guān)心
方便做集群和遷移概漱,哪一天我們服務(wù)的ip地址要變也之前項目中的調(diào)用也不受影響
-
注冊中心的原理
- 注冊中心原理.png
首先各個服務(wù)會把自己服務(wù)的名稱和ip地址丑慎,注冊到注冊中心去
如果某個服務(wù)有集群的話,那么在注冊中心就是一個服務(wù)名字對應(yīng)多個ip地址
服務(wù)消費方會向服務(wù)中心去訂閱消息瓤摧,一旦注冊中心的服務(wù)列表有變化竿裂,那么注冊中心就把最新的服務(wù)列表發(fā)給服務(wù)消費方
服務(wù)消費方會把拉取到的最新服務(wù)列表保存在本地,調(diào)用服務(wù)的時候是去保存在本地的服務(wù)列表里面找到對應(yīng)的服務(wù)和ip地址的
當項目運行的過程中注冊中心掛了照弥,是不影響現(xiàn)有的服務(wù)調(diào)用的铛绰,因為服務(wù)消費方用的都是本地的服務(wù)列表,但是會影響服務(wù)注冊方产喉,新的服務(wù)無法注冊了,服務(wù)消費方也拿不到最新的服務(wù)列表敢会,也就不知道有哪些服務(wù)有變化了
-
dubbo使用
-
原生生產(chǎn)者dubbo生產(chǎn)者2.png
其中的IUserService和User類是在一個member-api服務(wù)中曾沈,member-server服務(wù)包含了member-api服務(wù),在member-server服務(wù)中把要給別人調(diào)用的接口IUserService暴露出去(給到注冊中心)鸥昏,同時也把具體的實現(xiàn)類(UserServiceImpl)給到注冊中心塞俱,一一對應(yīng)
2.原生的消費者dubbo服務(wù)消費者.png
-
原生生產(chǎn)者
消費者把自己的名字設(shè)置好,設(shè)置好注冊中心的地址吏垮,設(shè)置好要消費的是哪一個接口障涯,當前端發(fā)來請求調(diào)用IUserService里面的方法(比如getId)時,那么dubbo會給IUserService對應(yīng)的遠程UserServiceImpl實現(xiàn)類創(chuàng)建一個動態(tài)代理類(也就是IUserService的一個實現(xiàn)類)膳汪,在這個代理類里面是可以拿到服務(wù)提供者(member-server)暴露出來的信息(我的推測是從注冊中心拿到的)唯蝶,那么我們就可以在代理類里面根據(jù)具體的url和UserServiceImpl實現(xiàn)類來執(zhí)行遠程的調(diào)用了。
-
常見問題
啟動時檢查:在dubbo中消費者必須在生產(chǎn)者之后啟動才不會報錯遗嗽,因為消費者會根據(jù)接口名去zookeeper中去找對應(yīng)的遠程服務(wù)路徑粘我,當生產(chǎn)者沒啟動時是找不到路徑的,就會報錯痹换,那如果a,b兩個服務(wù)之間互相消費征字,那么就怎么都啟動不了了,此時就要關(guān)閉啟動時檢查:<bubbo:reference interface="cn.sushen.BarService" check="false">娇豫,將check設(shè)為false
超時設(shè)置:由于服務(wù)的性能是有限的匙姜,當我們的消費者去調(diào)用生產(chǎn)者暴露的接口時,如果一下子來了太多請求冯痢,而生產(chǎn)者對應(yīng)接口中處理的速度又比較慢氮昧,那么就很可能導(dǎo)致生產(chǎn)者服務(wù)掛掉框杜,如果各服務(wù)關(guān)聯(lián)比較緊密的話,就可能導(dǎo)致服務(wù)器雪崩郭计,那么此時就要設(shè)置一個超時時間霸琴,比如消費者發(fā)送請求如果2秒沒有響應(yīng),就判斷超時了昭伸,要斷開連接了梧乘,如果我們想延長下超時時間,可以在<bubbo:reference設(shè)置timeout="3000",這就表示3秒沒用反應(yīng)才超時庐杨,超時時間一般不要設(shè)置超過2秒选调,否則可能導(dǎo)致服務(wù)器雪崩
上述2中設(shè)置的超時時間是針對整個BarService接口而言,如果我接口中有多個方法灵份,我們只想給某些特定的方法設(shè)置超時時間仁堪,那么既可以在<bubbo:reference中配置:<dubbo:method name="getById" time="3000"/>這就表示只給BarService接口中的getById方法設(shè)置了3秒的超時時間,并且方法級別配置的超時時間比直接陪在類上面的更高填渠,如果還單獨設(shè)置了超時時間<dubbo:consumer timeout="4000"/>那么這個單獨設(shè)置的全局超時時間是沒有針對接口設(shè)置的超時時間優(yōu)先級高的(如:<dubbo: id="my_barservice" interface="cn.sushen.BarService" check="false" timeout="1000"/>)
在生產(chǎn)者的spring中也是可以配置超時時間的弦聂,和消費者做對比時,優(yōu)先級是怎樣的呢氛什?1.第一先看超時的類型(方法(最高)莺葫,類(次之,這個類指的是暴露的接口類枪眉,對應(yīng)上述的<dubbo: id="my_barservice" interface="cn.sushen.BarService" check="false" timeout="1000"/>這種)捺檬,全局(最低)),不管是在生產(chǎn)者中還是在消費者中贸铜,比如在生產(chǎn)者中配置的是具體方法上的超時時間1秒堡纬,在消費者中配置的是類上的超時時間2秒,那么消費者消費的最終超時時間還是1秒蒿秦,而不是2秒烤镐,2.第二,如果消費者和生產(chǎn)者配置的類型時一樣的渤早,比如都是在類上做的配置职车,那么是以消費者的配置為準(作為消費的超時時間)
重試次數(shù):消費者調(diào)用服務(wù)時,如果失敗后會默認重試2次(加上第一次調(diào)用鹊杖,總共就是3次)悴灵,那么如果每個方法每個請求都這樣設(shè)置的話,一旦網(wǎng)絡(luò)波動或其他原因?qū)е律a(chǎn)者服務(wù)器變慢了骂蓖,就可能導(dǎo)致雪崩积瞒,所以對于明確不需要的重試的方法,我們要將重試的次數(shù)設(shè)為0,retries=0(可以在配置接口類interface的時候設(shè)置登下,也可以單獨設(shè)置茫孔,優(yōu)先級也是類覆蓋全局)
dubbo有重試的話叮喳,我們就要考慮冪等性問題,對于不是冪等性的方法缰贝,就不能配置重試操作馍悟,或者自己做好冪等性邏輯處理
-
dubbo多版本:用來進行灰度發(fā)布的,就是多個服務(wù)可以實現(xiàn)一個一個來升級剩晴,生產(chǎn)者可以發(fā)布多個版本锣咒,通過version來控制,消費者(可以配置version)也可以選擇要消費的版本來達到不同的消費者可以消費不同的生產(chǎn)者赞弥,從而實現(xiàn)灰度發(fā)布 dubbo參數(shù)配置詳解.png
-
本地存根:作用是先檢驗本地的參數(shù)毅整,當參數(shù)不合法時就不調(diào)用遠程服務(wù),減少遠程服務(wù)的壓力绽左,第二個作用:是可以做容錯處理悼嫉,如果調(diào)用遠程服務(wù)失敗時,可以返回一個空對象出去 本地存根.png
負載均衡策略:1.默認是缺省為random隨機調(diào)用(隨機是支持權(quán)重的拼窥,可以在dubbo監(jiān)控臺設(shè)置倍權(quán)和半權(quán)來改變權(quán)重)戏蔑,2.輪詢就是輪著來,3.最少活躍調(diào)用數(shù)就是dubbo每次調(diào)用服務(wù)時記錄下集群服務(wù)各服務(wù)的時間鲁纠,花的時間最少辛臊,就證明效率最高,下次就讓更多的請求去到那臺服務(wù)器房交,直到發(fā)現(xiàn)下次發(fā)現(xiàn)其他更低響應(yīng)時間的服務(wù),就往更低的那臺服務(wù)器發(fā)送請求伐割,4.一致性hash候味,對請求進行hash算法,求余看落到哪一個服務(wù)器上隔心,缺點就是可能導(dǎo)致某一臺服務(wù)器壓力過大白群,而其他服務(wù)器沒用上;在<dubbo:refrence中配置loadbalance=“roundrobin"就表示輪詢
集群容錯:默認是已經(jīng)處理了(自動切換)硬霍,當調(diào)用集群中一臺不成功時帜慢,就會調(diào)用集群中其他的服務(wù)器,也可以設(shè)置不同的集群容錯處理:1.快速失敗唯卖,只發(fā)起一次調(diào)用粱玲,失敗立即報錯,一般用來處理非冪等性的寫操作拜轨,2.失敗安全抽减,出現(xiàn)異常時直接忽略,一般用于寫日志橄碾,3.失敗自動恢復(fù)卵沉,后臺記錄失敗請求颠锉,定時重發(fā),一般用于消息通知史汗,4.并行調(diào)用多個服務(wù)器琼掠,只要一個成功即返回,一般用于實時性要求高的讀操作停撞,但是需要浪費更多服務(wù)資源瓷蛙,可通過fork=2來設(shè)置最大并行數(shù),5.廣播調(diào)用怜森,逐個調(diào)用所有的服務(wù)速挑,任意一臺報錯則報錯,一般用于通知所有提供者更新緩存或日志等本地資源信息
服務(wù)降級:在服務(wù)器壓力劇增時副硅,對一些服務(wù)和頁面有策略的不處理或換種簡單的方式處理姥宝,從而釋放服務(wù)器資源以保證服務(wù)器核心交易正常或高效運行
-
本地存根和遠程代理的關(guān)系本地存根和遠程代理的關(guān)系.png
當我們的消費者調(diào)用dubbo提供的遠程服務(wù)時恐疲,會在客戶端生成一個遠程動態(tài)代理類腊满,我們知道動態(tài)代理里面是有一個屬性擁有真實類的(通過注冊中心拿到具體的地址和實現(xiàn)類),在代理類中把我們要傳入的對象進行序列化后培己,再通過真正的遠程地址和實現(xiàn)類進行調(diào)用碳蛋,本地存根是干什么用的呢?本地存根也是我們要調(diào)用的接口的一個實現(xiàn)類省咨,dubbo會把動態(tài)代理類傳入到本地存根里來肃弟,我們可以在本地存根里面做自己的邏輯處理,如果參數(shù)異常我們就放棄通過遠程動態(tài)代理調(diào)用服務(wù)零蓉,減少生產(chǎn)者的壓力笤受,同時也可以做容錯處理,使用try catch,當調(diào)用遠程方法失敗時敌蜂,返回一個空數(shù)據(jù)給到前端然后做下友好界面的處理