1.好的微服務(wù)是什么樣的堕虹?
1.1.特點(diǎn)分析
首先看一下微服務(wù)架構(gòu)的定義:微服務(wù)(MSA)是一種架構(gòu)風(fēng)格趁冈,旨在通過將功能分解到各個(gè)離散的服務(wù)中以實(shí)現(xiàn)對(duì)解決方案的解耦。它有如下幾個(gè)特征:
小,且只干一件事情赊锚。
獨(dú)立部署和生命周期管理。
異構(gòu)性輕量級(jí)通信,RPC或者Restful骗灶。
1.2.設(shè)計(jì)原則
針對(duì)以上特點(diǎn)華為實(shí)踐經(jīng)驗(yàn)的微服務(wù)設(shè)計(jì)原則如下:
(1)功能完整性耙旦、職責(zé)單一性免都。
(2)粒度適中,團(tuán)隊(duì)可接受脓规。
(3)迭代演進(jìn)侨舆,非一蹴而就绢陌。
(4)API的版本兼容性優(yōu)先考慮脐湾。
1.3.落地實(shí)踐建議
(1)接口隔離,如管理接口和生產(chǎn)接口隔離愁铺,低性能接口隔離帜讲,大報(bào)文接口隔離椒拗;
(2)建議每服務(wù)應(yīng)用約2~5個(gè)微服務(wù)蚀苛,每個(gè)微服務(wù)10個(gè)以內(nèi)接口堵未;
(3)迭代設(shè)計(jì)和實(shí)現(xiàn)微服務(wù)接口渗蟹,每輪迭代都需要業(yè)務(wù)側(cè)實(shí)際使用微服務(wù),并及時(shí)反饋微服務(wù)接口問題授艰,以驗(yàn)證微服務(wù)接口設(shè)計(jì)世落。
(4)查詢服務(wù)(query)屉佳、驗(yàn)證服務(wù)(check)、管理服務(wù)(update,add,delete)和業(yè)務(wù)服務(wù)分類劃分服務(wù)圆凰,約定服務(wù)命名等規(guī)范专钉;
(5)減少不必要的數(shù)據(jù)返回干旁,批量接口争群,考慮限制分批條數(shù)。
(6)API版本兼容玉雾,考慮隱式傳參(框架層面使用通用參數(shù))复旬、業(yè)務(wù)擴(kuò)充使用BaseRequest 請(qǐng)求基類屬性Map expandAttribute
1.4.討論問題
1.4.1 接口設(shè)計(jì)遵循異常還是返回碼驹碍?
微服務(wù)接口設(shè)計(jì)是否借用java語言特性凡恍,接口拋異常還是使用返回碼機(jī)制嚼酝,需要結(jié)合實(shí)際情況分析。
下面是采用異常定義:
publicBindWoAccountResponse bindWoAccount(BindWoAccountRequest request) throwsForbiddenException, ParamNullException, ?BizException;
采用返回定義钧舌,則響應(yīng)response需要添加異常嗎描述
publicBindWoAccountResponse bindWoAccount(BindWoAccountRequest request)
結(jié)論:采用異常碼洼冻,原因
1).異常帶有語言特性,異構(gòu)語言無法處理?
2).加上異常之后驾荣,業(yè)務(wù)異常和通信異常播掷,客戶端捕獲容易混亂麻煩?
1.4.2 服務(wù)要不要版本號(hào)version撼班,如何管理砰嘁?
微服務(wù)的版本號(hào)有眾多好處,此處不再贅述斟冕,但是實(shí)際使用過程中磕蛇,很多團(tuán)隊(duì)為了方便并不設(shè)置版本號(hào)十办,這個(gè)需要討論向族,后期服務(wù)眾多的時(shí)候,再引入版本號(hào)再扭,問題如何處理霍衫?
2.同步、異步澄干、并行調(diào)用服務(wù)柠傍?
2.1.調(diào)用方式
客戶端調(diào)用服務(wù)端惧笛,存在分為同步患整、異步和并行調(diào)用各谚,不同的調(diào)用方式到千,框架的處理方式不一樣憔四,服務(wù)化的性能也不一樣,什么樣場(chǎng)景用什么調(diào)用方式潜支,需要具體分析冗酿。
2.2.同步調(diào)用
同步調(diào)用是最簡(jiǎn)單已烤,也是最常用的調(diào)用方式妓羊,客戶端發(fā)送請(qǐng)求等待,響應(yīng)通知裕循。
1.請(qǐng)求和響應(yīng)剥哑,服務(wù)處理短,實(shí)時(shí)要求高的場(chǎng)景
2.請(qǐng)求和響應(yīng)株婴,服務(wù)處長(zhǎng)困介,業(yè)務(wù)上同步轉(zhuǎn)異步的場(chǎng)景
比如,批量接口調(diào)用徒扶,服務(wù)接收請(qǐng)求后直接返回批次處理中(processing)姜骡,處理完后續(xù)主動(dòng)通知上層服務(wù)屿良。
2.3.異步調(diào)用
采用異步調(diào)用管引,可以避免線程阻塞,提升系統(tǒng)的吞吐量和可靠性谅将。但是在實(shí)際項(xiàng)目中異步調(diào)用也有一些缺點(diǎn)重慢,導(dǎo)致使用不是特別廣泛:需要寫異步回調(diào)邏輯似踱,與傳統(tǒng)的接口調(diào)用使用方式不一致,開發(fā)難度大一些囚戚。一些場(chǎng)景下需要緩存上下文信息驰坊,引入可靠性問題哮独。
使用場(chǎng)景:
1.單服務(wù)調(diào)用,主線程除了服務(wù)調(diào)用之外舟扎,本身還有大量耗時(shí)的業(yè)務(wù)操作而且業(yè)務(wù)操作與服務(wù)響應(yīng)無關(guān)睹限。
2.多服務(wù)調(diào)用,主線程調(diào)用服務(wù)之間不存在業(yè)務(wù)關(guān)聯(lián)删窒,而且服務(wù)處理時(shí)間不同顺囊,服務(wù)時(shí)間大的可以采用異步調(diào)用特碳。
下圖為實(shí)際例子:
2.4.并行調(diào)用
并行調(diào)用適用于多個(gè)服務(wù)調(diào)用沒有上下文依賴,邏輯上可以并行處理闸准,類似JDK的Fork/Join, 并行服務(wù)調(diào)用涉及到同步轉(zhuǎn)異步、異步轉(zhuǎn)同步蒸其、結(jié)果匯聚等摸袁,技術(shù)實(shí)現(xiàn)難度較大义屏,目前多數(shù)服務(wù)框架并不支持。采用并行服務(wù)調(diào)用蝶怔,可以把傳統(tǒng)串行的服務(wù)調(diào)用優(yōu)化成并行處理踢星,能夠極大的縮短服務(wù)調(diào)用時(shí)延察迟。
使用場(chǎng)景:多服務(wù)調(diào)用,主線程調(diào)用服務(wù)之間不存在業(yè)務(wù)關(guān)聯(lián)所踊,業(yè)務(wù)上使用并行調(diào)用優(yōu)化調(diào)用時(shí)間概荷。下面為業(yè)務(wù)使用多線程實(shí)現(xiàn)簡(jiǎn)單場(chǎng)景的并行調(diào)用。
備注:并行要求JAVA并發(fā)技術(shù):1.線程池 2.CountDownLatch 3.Future
3.如何做服務(wù)調(diào)優(yōu)修壕?
3.1.發(fā)現(xiàn)問題
(1)Load Runner 測(cè)試
(2)業(yè)務(wù)日志(業(yè)務(wù)日志慈鸠、aop切片日志查看方法灌具、sql執(zhí)行時(shí)間)咖楣、調(diào)用鏈日志
(3)緩存查看工具诱贿,性能指標(biāo)優(yōu)化
(4)服務(wù)治理頁面查看服務(wù)性能
3.2.調(diào)優(yōu)策略
(1)串行調(diào)用改為異步調(diào)用和并行調(diào)用
(2)引入緩存,消息隊(duì)列
(3)服務(wù)參數(shù)配置調(diào)優(yōu)料扰,線程池大小记罚,通道鏈個(gè)數(shù)壳嚎、JVM堆大小烟馅、日志級(jí)別郑趁、服務(wù)治理等
(4)同步轉(zhuǎn)異步
4.如何服務(wù)化共享緩存寡润?
服務(wù)化之后必須要面臨的問題一定包括共享緩存問題,目前主流共享緩存使用中間件redis躲惰。但是各個(gè)微服務(wù)應(yīng)用如何使用共享緩存础拨,分為集中化管理對(duì)外提供微服務(wù)和各個(gè)微服務(wù)獨(dú)立連接緩存。下圖做了簡(jiǎn)單的比較滔蝉,歡迎大家討論蝠引。
5.分布式事務(wù)建議芳悲?
分布式事務(wù)就是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上肮韧。
1.如果業(yè)務(wù)場(chǎng)景需要強(qiáng)一致性, 那么盡量避免將它們放在不同服務(wù)中, 也就是盡量使用本地事務(wù), 避免使用強(qiáng)一致性的分布式事務(wù).
2.如果業(yè)務(wù)場(chǎng)景能夠接受最終一致性, 那么最好是使用基于消息的最終一致性的方案(異步確保型)來解決.
3.如果業(yè)務(wù)場(chǎng)景需要強(qiáng)一致性, 并且只能夠進(jìn)行分布式服務(wù)部署, 那么最好是使用TCC方案而不是2PC方案來解決.
Q&A
對(duì)上述問題如果有好的建議和方案弄企,歡迎隨時(shí)留言.