dubbo三

九、最佳實(shí)踐
分布式應(yīng)用和單體應(yīng)用的主要區(qū)別是本地調(diào)用和遠(yuǎn)程調(diào)用,解決的主要問(wèn)題都是和遠(yuǎn)程調(diào)用相關(guān)。首先,遠(yuǎn)程調(diào)用的性能差于本地調(diào)用;其次,遠(yuǎn)程調(diào)用受網(wǎng)絡(luò)狀況影響,有一定的失敗率,框架和應(yīng)用需要對(duì)失敗進(jìn)行處理;再次,分布式場(chǎng)景下,事務(wù)控制會(huì)變得及其復(fù)雜;第四,分布式調(diào)用和調(diào)用本地API的不同。
遠(yuǎn)程調(diào)用的性能:遠(yuǎn)程調(diào)用的復(fù)雜性和流程遠(yuǎn)超本地調(diào)用,包括序列化反序列化,網(wǎng)絡(luò)傳輸,反射調(diào)用等重量級(jí)開(kāi)銷。要保證高性能,除了框架自身之外,應(yīng)用的實(shí)現(xiàn)也應(yīng)該盡可能高性能話,最佳實(shí)踐包括:1、盡可能異步或并行化服務(wù)調(diào)用,提高服務(wù)吞吐量,降低服務(wù)調(diào)用時(shí)延,或者使次要事件不影響響應(yīng)時(shí)間;2、減小調(diào)用傳輸量,包括dubbo在內(nèi)的很多分部式服務(wù)框架在服務(wù)的消費(fèi)者和提供者之間使用單一長(zhǎng)連接,傳輸量大會(huì)嚴(yán)重降低服務(wù)吞吐量,增大調(diào)用時(shí)延;3、在消費(fèi)者端控制超時(shí)時(shí)延,避免慢響應(yīng)的服務(wù)引起故障擴(kuò)散;4、做好服務(wù)隔離,避免次要服務(wù)消耗過(guò)多資源,影響重要服務(wù)的吞吐量或性能。
容災(zāi)容錯(cuò):在分布式服務(wù)框架和應(yīng)用中需要做好被調(diào)用服務(wù)出錯(cuò)或不可用的準(zhǔn)備,并進(jìn)行兼容,避免次要服務(wù)引起整個(gè)業(yè)務(wù)無(wú)法進(jìn)行的狀況。前面在服務(wù)降級(jí)中進(jìn)行過(guò)詳細(xì)描述,此處不再細(xì)講。
分布式事務(wù)的一致性:?jiǎn)误w應(yīng)用中,事務(wù)是個(gè)極其簡(jiǎn)單的控制,spring的聲明式事務(wù)提供了很多事務(wù)控制策略,代碼中幾乎不需要考慮事務(wù)一致性問(wèn)題。服務(wù)分布化之后,每個(gè)服務(wù)都擁有自己的數(shù)據(jù)庫(kù),服務(wù)之間的調(diào)用也變成了遠(yuǎn)程調(diào)用,事務(wù)一致性幾乎無(wú)法通過(guò)框架來(lái)保證,事務(wù)一致性控制可能是分布式應(yīng)用和單體應(yīng)用的最大區(qū)別。通常,兩階段提交時(shí)企業(yè)應(yīng)用保證分布式事務(wù)的常規(guī)策略,然而,兩階段提交采用悲觀鎖策略策略所表現(xiàn)出的低吞吐量和在出現(xiàn)故障時(shí)的脆弱性,幾乎不被互聯(lián)網(wǎng)應(yīng)用所采納。回到問(wèn)題的本質(zhì),我們之所以采用事務(wù),是為了數(shù)據(jù)的一致性,而為了達(dá)到數(shù)據(jù)一致性,不一定只有事務(wù)一種方式,尤其是在分布式場(chǎng)景下,采用分布式事務(wù)帶來(lái)的吞吐量下降是無(wú)法接受的。我們考慮在整個(gè)業(yè)務(wù)處理過(guò)程中,保證數(shù)據(jù)在任何時(shí)間內(nèi)強(qiáng)一致的必要性,在很多業(yè)務(wù)場(chǎng)景下用戶對(duì)短暫的數(shù)據(jù)不一致是可以理解和容忍的,只要最終數(shù)據(jù)是一致的即可。使用最終一致性,就不需要使用強(qiáng)一致的兩階段提交型分布式事務(wù),從而使得系統(tǒng)的吞吐量得到保證。常用的最終一致性方案,要么在整個(gè)業(yè)務(wù)過(guò)程中記錄每個(gè)調(diào)用其他服務(wù)事務(wù)性操作的結(jié)果,對(duì)失敗的操作進(jìn)行重試,如果某個(gè)關(guān)鍵性服務(wù)返回失敗,例如支付時(shí)余額不足,則對(duì)每個(gè)成功的事務(wù)性操作進(jìn)行補(bǔ)償性操作調(diào)用,以達(dá)到事務(wù)回滾的效果;要么使用帶有事務(wù)功能的MQ做中間人角色,做本地事務(wù)之前向MQ發(fā)送prepare消息,然后執(zhí)行本地事務(wù),執(zhí)行成功的話向MQ發(fā)送commit消息,執(zhí)行失敗則發(fā)送rollback消息。對(duì)于最終一致性,一個(gè)很關(guān)鍵的點(diǎn)就是:對(duì)于網(wǎng)絡(luò)超時(shí)的事務(wù)性請(qǐng)求,不能假設(shè)為失敗,必須查詢后,根據(jù)查詢結(jié)果決定下一步的操作,如果成功則進(jìn)行下一步操作,失敗則重試。
分布式調(diào)用與本地調(diào)用的不同:遠(yuǎn)程調(diào)用比本地調(diào)用復(fù)雜,所以有一些通用的最佳實(shí)踐。
分包:建議將服務(wù)接口,服務(wù)模型,服務(wù)異常等放在api包中;
粒度:服務(wù)接口盡可能大粒度,每個(gè)服務(wù)方法應(yīng)代表一個(gè)功能,而不是某功能的一個(gè)步驟,否則將面臨分布式事務(wù)問(wèn)題;
序列化:服務(wù)參數(shù)及返回值建議使用POJO對(duì)象,即通過(guò)set,get方法表示屬性的對(duì)象,服務(wù)參數(shù)及返回值都必需是byValue的,而不能是byRef的,遠(yuǎn)程調(diào)用出現(xiàn)byRef可能出現(xiàn)難以預(yù)料的問(wèn)題;
異常:建議使用異常匯報(bào)錯(cuò)誤,而不是返回錯(cuò)誤碼,異常信息能攜帶更多信息,以及語(yǔ)義更友好。

作為本系列的終結(jié)篇,強(qiáng)調(diào)最后一次,在分布式應(yīng)用中,一定要處理好異常,處理好調(diào)用失敗,處理好網(wǎng)絡(luò)超時(shí)等各種非正常的場(chǎng)景。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容