微服务:知识点梳理(SOA、服务拆分、服务治理、分布式事务)
微服務(wù)基本
單體應(yīng)用
單體應(yīng)用的優(yōu)點(diǎn)?
--易于開發(fā)
--易于測試
--易于部署
存在的問題:
--代碼耦合,開發(fā)維護(hù)困難,提交代碼頻繁出現(xiàn)大量沖突
--主要業(yè)務(wù)和次要業(yè)務(wù)耦合,無法針對不同模塊進(jìn)行針對性優(yōu)化
--單點(diǎn)容錯(cuò)率低,并發(fā)能力差,無法水平擴(kuò)展
--技術(shù)選型成本高 ?
--交付周期長,小功能要積累到大版本才能上線,上線開總監(jiān)級別大會(huì)
微服務(wù)和SOA
微服務(wù):架構(gòu)本質(zhì)是帶自身特點(diǎn)的面向服務(wù)的分布式架構(gòu)模式。
SOA(Service Oriented Architecture):“面向服務(wù)的架構(gòu)”:他是一種設(shè)計(jì)方法,其中包含多個(gè)服務(wù), 服務(wù)之間通過相互依賴最終提供一系列的功能。
SOA特點(diǎn)
-- 有序(站在系統(tǒng)的角度,把原先散亂、無規(guī)劃的系統(tǒng)間的網(wǎng)狀結(jié)構(gòu),梳理成 規(guī)整、可治理的系統(tǒng)間星形結(jié)構(gòu))
-- 復(fù)用(站在功能的角度,把業(yè)務(wù)邏輯抽象成 可復(fù)用、可組裝的服務(wù))
-- 高效(站在企業(yè)的角度,把企業(yè)職能抽象成 可復(fù)用、可組裝的服務(wù))
微服務(wù)和SOA區(qū)別:
| 功能 | SOA | 微服務(wù) |
| 組件大小 | 大塊業(yè)務(wù)邏輯(粗粒度) | 單獨(dú)、小塊業(yè)務(wù)邏輯(細(xì)粒度) |
| 耦合 | 通常松耦合 | 總是松耦合 |
| 管理 | 著重中央管理 | 去中心化 |
| 通信 | 輕量級通信 | 企業(yè)服務(wù)總線(ESB)充當(dāng)服務(wù)之間通信的角色 |
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ??
微服務(wù)解決的問題
快速迭代
--提交代碼頻繁出現(xiàn)大量沖突
--小功能要積累到大版本才能上線,上線開總監(jiān)級別大會(huì)
高并發(fā)
--橫向擴(kuò)展流程復(fù)雜,主要業(yè)務(wù)和次要業(yè)務(wù)耦合
--熔斷降級全靠if-else
-
如果核心業(yè)務(wù)流程和邊角業(yè)務(wù)流程在同一個(gè)進(jìn)程中,就需要使用大量的if-else語句,根據(jù)下發(fā)的配置來判斷是否熔斷或者降級,這會(huì)使得配置異常復(fù)雜,難以維護(hù)。
-
如果核心業(yè)務(wù)和邊角業(yè)務(wù)分成兩個(gè)進(jìn)程,就可以使用標(biāo)準(zhǔn)的熔斷降級策略,配置在某種情況下,放棄對另一個(gè)進(jìn)程的調(diào)用,可以進(jìn)行統(tǒng)一的維護(hù)。
微服務(wù)的設(shè)計(jì)原則、特征
微服務(wù)體系結(jié)構(gòu)由輕量級、松散耦合的服務(wù)集合組成。每個(gè)服務(wù)都實(shí)現(xiàn)了單個(gè)業(yè)務(wù)功能。理想情況下,這些服務(wù)應(yīng)該是具有足夠的內(nèi)聚性,可以獨(dú)立地開發(fā)、測試、發(fā)布、部署、擴(kuò)展、集成和維護(hù)。
1. AKF拆分原則:以業(yè)務(wù)為中心
AKF擴(kuò)展立方體,是一個(gè)AKF公司的技術(shù)專家抽象總結(jié)的應(yīng)用擴(kuò)展的三個(gè)維度,理論上按照這三個(gè)擴(kuò)展模式,可以將一個(gè)單體系統(tǒng)進(jìn)行無限擴(kuò)展。
- Y軸(功能)——關(guān)注應(yīng)用中功能劃分,基于不同的業(yè)務(wù)拆分
- X軸(水平擴(kuò)展)——關(guān)注水平擴(kuò)展,也就是“加機(jī)器解決問題”
- Z軸(數(shù)據(jù)區(qū)分)——關(guān)注服務(wù)和數(shù)據(jù)的優(yōu)先級劃分,如按地域劃分
拆分后,每個(gè)服務(wù)代表了特定的業(yè)務(wù)邏輯、圍繞業(yè)務(wù)組織團(tuán)隊(duì)、能快速的響應(yīng)業(yè)務(wù)的變化。每個(gè)微服務(wù)也都可以動(dòng)態(tài)的進(jìn)行x軸和z軸的擴(kuò)展,并適應(yīng)云環(huán)境下的自動(dòng)化部署;
2.高內(nèi)聚低耦合、輕量級無狀態(tài)通信原則
- 關(guān)注微服務(wù)的范圍,而不是一味的把服務(wù)做小。一個(gè)服務(wù)的大小應(yīng)該等于滿足某個(gè)特定業(yè)務(wù)能力所需要的大小。緊密關(guān)聯(lián)的事物應(yīng)該放在一起,每個(gè)服務(wù)是針對一個(gè)單一職責(zé)的業(yè)務(wù)能力的封裝,專注做好一件事情。
- 輕量級的通信方式--同步RESTful能讓服務(wù)間的通信變得標(biāo)準(zhǔn)化并且無狀態(tài);異步(消息隊(duì)列/發(fā)布訂閱)
- 避免在服務(wù)與服務(wù)之間共享數(shù)據(jù)庫,避免產(chǎn)生頻繁的跨庫查詢,避免產(chǎn)生頻繁的分布式事務(wù)。
依據(jù)此,可實(shí)現(xiàn)單一職責(zé)、輕量級的通信方式、數(shù)據(jù)獨(dú)立的效果
?3. 去中心化、 高度自治原則
-- 能獨(dú)立的開發(fā)、部署、發(fā)布,進(jìn)程獨(dú)立,獨(dú)立的代碼庫、流水線
4. 彈性設(shè)計(jì)原則
設(shè)計(jì)可容錯(cuò)的系統(tǒng),設(shè)計(jì)具有自我保護(hù)能力的系統(tǒng)
-- 具有自我保護(hù)能力、可容錯(cuò) (Netfilix 提供了一個(gè)比較好的解決方案,具體的應(yīng)對措施包括:網(wǎng)絡(luò)超時(shí)/限制請求的次數(shù)/斷路器模式/提供回滾等)
5. 日志與監(jiān)控原則
聚合你的日志,聚合你的數(shù)據(jù),從而當(dāng)你遇到問題時(shí),可以深入分析原因。
--日志聚合,監(jiān)控與警告
開源產(chǎn)品ELK可以用于日志的收集,聚合,展現(xiàn),并提供搜索功能,基于一定條件,觸發(fā)郵件警告。
Spring boot admin也可以用于服務(wù)可用性的監(jiān)控, hystrix除了提供熔斷器機(jī)制外,它還收集了一些請求的基本信息(比如請求響應(yīng)時(shí)間,訪問計(jì)算,錯(cuò)誤統(tǒng)計(jì)等),并提供現(xiàn)成的dashboard將信息可視化。
6. 自動(dòng)化原則
在微服務(wù)架構(gòu)下,面臨如下挑戰(zhàn):
- 分布式系統(tǒng)
- 多服務(wù),多實(shí)例
- 手動(dòng)測試,部署,發(fā)布太消耗時(shí)間
- 反饋周期太長
傳統(tǒng)的手工運(yùn)維方式必然要被淘汰,微服務(wù)的實(shí)施是有一定的先決條件:那就是自動(dòng)化,當(dāng)服務(wù)規(guī)模化后需要更多自動(dòng)化和標(biāo)準(zhǔn)化的手段來提升效能和降低成本。
--微服務(wù)是松耦合的,微服務(wù)架構(gòu)模式使得持續(xù)化部署成為可能。持續(xù)集成、持續(xù)交付
參考鏈接:
https://www.jianshu.com/p/4e582616d565
https://yq.aliyun.com/articles/666604
https://www.servicemesher.com/blog/design-patterns-for-microservices/
https://yq.aliyun.com/articles/618043
https://isdxh.com/86.html
微服務(wù)的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
強(qiáng)模塊化邊界
可獨(dú)立部署
技術(shù)多樣性
缺點(diǎn):
服務(wù)拆分復(fù)雜性
分布式復(fù)雜性
最終一致性(分布式事務(wù))
測試、運(yùn)維復(fù)雜性
微服務(wù)拆分
微服務(wù)拆分原則
服務(wù)劃分的合理性
服務(wù)的業(yè)務(wù)范圍,是否破壞服務(wù)依賴原則,是否滿足單一職責(zé)
服務(wù)所屬團(tuán)隊(duì)的規(guī)模
服務(wù)能否獨(dú)立交付
微服務(wù)的設(shè)計(jì)模式
鏈?zhǔn)皆O(shè)計(jì)模式(按照數(shù)據(jù)流向就行數(shù)據(jù)拆分)
--先后調(diào)用多個(gè)服務(wù),產(chǎn)生一個(gè)經(jīng)過合并的響應(yīng)給客戶
--在整個(gè)鏈?zhǔn)秸{(diào)用完成之前,客戶端會(huì)一直阻塞
--服務(wù)調(diào)用鏈不宜過長,以免客戶端長時(shí)間等待
聚合器(API Gateway\BFF\邊緣服務(wù)Edge Service)
異步消息傳遞
--同步請求會(huì)造成阻塞, 可以選擇使用消息隊(duì)列代替同步請求/響應(yīng):
事件溯源模式
--采用已事件為中心的方法保存業(yè)務(wù)實(shí)體
物化視圖模式
--多個(gè)服務(wù)的常用的聚合數(shù)據(jù),生成視圖,方便查詢
CQRS模式(讀寫分離)
服務(wù)治理
微服務(wù)出現(xiàn)了什么問題?
服務(wù)治理要做什么
- 服務(wù)治理就是對服務(wù)復(fù)雜度膨脹問題的管控及管理。
服務(wù)的線上的治理
--服務(wù)限流
--集群容錯(cuò)
--服務(wù)降級、熔斷
--故障定界定位
--容量規(guī)劃
--資源治理
--線上生命周期管理
服務(wù)的線下的治理
項(xiàng)目管理、版本管理、測試、運(yùn)維
架構(gòu)管理
--異常處理、舊版本兼容
開發(fā)管理
--代碼質(zhì)量
測試管理
--測試覆蓋度
構(gòu)建調(diào)測能力
協(xié)同管理治理
服務(wù)限流
漏桶算法及令牌桶算法
集群限流的情況要更復(fù)雜一些,首先在各個(gè)微服務(wù)節(jié)點(diǎn)上要有一個(gè)計(jì)數(shù)器,對單位時(shí)間片內(nèi)的調(diào)用進(jìn)行計(jì)數(shù),算出這個(gè)時(shí)間片的總調(diào)用量和預(yù)先定義的限流閾值進(jìn)行比對,計(jì)算出一個(gè)限流比例
服務(wù)降級、熔斷
服務(wù)降級與熔斷
- 聯(lián)系
- 區(qū)別
服務(wù)降級手段:
- 容錯(cuò)降級
- 我們常說的熔斷,本質(zhì)上也是容錯(cuò)降級策略的一種,只不過它比一般容錯(cuò)降級提供了更為豐富的容錯(cuò)托底策略,支持半開降級及全開降級模式
- 靜態(tài)返回值降級
- Mock 降級
- 備用服務(wù)降級
故障定界定位
調(diào)用鏈本質(zhì)上也是基于日志,只不過它比常規(guī)的日志更重視日志之間的關(guān)系。在一個(gè)請求剛發(fā)起的時(shí)候,調(diào)用鏈會(huì)賦予它一個(gè)跟蹤號(traceID),這個(gè)跟蹤號會(huì)隨著請求穿越不同的網(wǎng)絡(luò)節(jié)點(diǎn),并隨著日志落盤,日志被收集后,可以根據(jù) traceID 來對日志做聚合,找到所有的關(guān)聯(lián)日志,并按順序排序,就能構(gòu)建出這個(gè)請求跨網(wǎng)絡(luò)的調(diào)用鏈,它能詳細(xì)描述請求的整個(gè)生命周期的狀況。
分布一致性
強(qiáng)一致性、弱一致性、最終一致性
CAP理論
一致性(C:Consistency)
可用性(A:Availability)
分區(qū)容錯(cuò)性(P:Partition tolerance)
- CA?? ?放棄分區(qū)容錯(cuò)性,加強(qiáng)一致性和可用性,其實(shí)就是傳統(tǒng)的單機(jī)數(shù)據(jù)庫的選擇
- AP?? ?放棄一致性(這里說的一致性是強(qiáng)一致性),追求分區(qū)容錯(cuò)性和可用性,這是很多分布式系統(tǒng)設(shè)計(jì)時(shí)的選擇,例如很多NoSQL系統(tǒng)就是如此
- CP?? ?放棄可用性,追求一致性和分區(qū)容錯(cuò)性,基本不會(huì)選擇,網(wǎng)絡(luò)問題會(huì)直接讓整個(gè)系統(tǒng)不可用
C A 滿足的情況下,P不能滿足的原因:
? ? ? ?數(shù)據(jù)同步(C)需要時(shí)間,也要正常的時(shí)間內(nèi)響應(yīng)(A),那么機(jī)器數(shù)量就要少,所以P就不滿足
?? ??? ?
CP 滿足的情況下,A不能滿足的原因:
?? ??? ??? ?數(shù)據(jù)同步(C)需要時(shí)間, 機(jī)器數(shù)量也多(P),但是同步數(shù)據(jù)需要時(shí)間,所以不能再正常時(shí)間內(nèi)響應(yīng),所以A就不滿足
AP 滿足的情況下,C不能滿足的原因:
?? ??? ??? ?機(jī)器數(shù)量也多(P),正常的時(shí)間內(nèi)響應(yīng)(A),那么數(shù)據(jù)就不能及時(shí)同步到其他節(jié)點(diǎn),所以C不滿足
BASE理論
BASE理論是對CAP中一致性和可用性權(quán)衡的結(jié)果
Basically Available(基本可用)
- 基本可用是指分布式系統(tǒng)在出現(xiàn)不可預(yù)知故障的時(shí)候,允許損失部分可用性
Soft state(軟狀態(tài))
- 軟狀態(tài)指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認(rèn)為該中間狀態(tài)的存在不會(huì)影響系統(tǒng)的整體可用性,即允許系統(tǒng)在不同節(jié)點(diǎn)的數(shù)據(jù)副本之間進(jìn)行數(shù)據(jù)同步的過程存在延時(shí)
Eventually consistent(最終一致性)
- 最終一致性的本質(zhì)是需要系統(tǒng)保證最終數(shù)據(jù)能夠達(dá)到一致,而不需要實(shí)時(shí)保證系統(tǒng)數(shù)據(jù)的強(qiáng)一致性。
服務(wù)注冊與發(fā)現(xiàn)
服務(wù)注冊中心本質(zhì)上是為了解耦服務(wù)提供者和服務(wù)消費(fèi)者。
對于任何一個(gè)微服務(wù),原則上都應(yīng)存在或者支持多個(gè)提供者,這是由微服務(wù)的分布式屬性決定的。更進(jìn)一步,為了支持彈性擴(kuò)縮容特性,一個(gè)微服務(wù)的提供者的數(shù)量和分布往往是動(dòng)態(tài)變化的,也是無法預(yù)先確定的。
因此,原本在單體應(yīng)用階段常用的靜態(tài)LB機(jī)制就不再適用了,需要引入額外的組件來管理微服務(wù)提供者的注冊與發(fā)現(xiàn),而這個(gè)組件就是服務(wù)注冊中心。
注冊中心選擇:
Zookeeper:CP設(shè)計(jì),保證了一致性,集群搭建的時(shí)候,某個(gè)節(jié)點(diǎn)失效,則會(huì)進(jìn)行選舉行的leader,或者半數(shù)以上節(jié)點(diǎn)不可用,則無法提供服務(wù),因此可用性沒法滿足
Eureka:AP原則,無主從節(jié)點(diǎn),一個(gè)節(jié)點(diǎn)掛了,自動(dòng)切換其他節(jié)點(diǎn)可以使用,去中心化
注冊中心分類
應(yīng)用內(nèi):直接集成到應(yīng)用中,依賴于應(yīng)用自身完成服務(wù)的注冊與發(fā)現(xiàn),最典型的是Netflix提供的Eureka、nacos
應(yīng)用外:把應(yīng)用當(dāng)成黑盒,通過應(yīng)用外的某種機(jī)制將服務(wù)注冊到注冊中心,最小化對應(yīng)用的侵入性,HashiCorp的Consul
Consul強(qiáng)一致性(C)帶來的是:
服務(wù)注冊相比Eureka會(huì)稍慢一些。因?yàn)镃onsul的raft協(xié)議要求必須過半數(shù)的節(jié)點(diǎn)都寫入成功才認(rèn)為注冊成功
Leader掛掉時(shí),重新選舉期間整個(gè)consul不可用。
保證了強(qiáng)一致性但犧牲了可用性。
Eureka保證高可用(A)和最終一致性:
服務(wù)注冊相對要快,因?yàn)椴恍枰茸孕畔eplicate到其他節(jié)點(diǎn),也不保證注冊信息是否replicate成功
當(dāng)數(shù)據(jù)出現(xiàn)不一致時(shí),雖然A, B上的注冊信息不完全相同,但每個(gè)Eureka節(jié)點(diǎn)依然能夠正常對外提供服務(wù),這會(huì)出現(xiàn)查詢服務(wù)信息時(shí)如果請求A查不到,但請求B就能查到。如此保證了可用性但犧牲了一致性。
其他方面,eureka就是個(gè)servlet程序,跑在servlet容器中; Consul則是go編寫而成。
Nacos = Spring Cloud注冊中心 + Spring Cloud配置中心。
服務(wù)優(yōu)雅上下線
-- 停止服務(wù)前先截?cái)喾?wù)的流量
--注冊中心通知所有服務(wù)干掉下線實(shí)例
--處理完手頭事務(wù)后停止
Eureka 中服務(wù)下線的幾種方式
1、直接停掉服務(wù)
根據(jù)默認(rèn)的策略,如果在一定的時(shí)間內(nèi),客戶端沒有向注冊中心發(fā)送續(xù)約請求,那么注冊中心就會(huì)將該實(shí)例從注冊中心移除,但是有缺陷,因?yàn)榉?wù)直接停掉后,實(shí)例仍然會(huì)在注冊中心存在一小段時(shí)間(90s),也有可能注冊中心直接認(rèn)為你的服務(wù)down掉,但是實(shí)例仍然存在于注冊中心
2、通過注冊中心接口強(qiáng)制下線
為了讓注冊中心馬上知道服務(wù)要下線, 可以向eureka 注冊中心發(fā)送delete 請求
// 注冊中心zone
eureka:client:serviceUrl:defaultZone發(fā)送一個(gè)delete 請求
格式為 /eureka/apps/{application.name}/
http://你的注冊中心zone/apps/你的實(shí)例名稱/你的實(shí)例地址加端口
實(shí)例名稱就是Application,地址加端口就是Status的右邊
值得注意的是,Eureka客戶端每隔一段時(shí)間(默認(rèn)30秒)會(huì)發(fā)送一次心跳到注冊中心續(xù)約。如果通過這種方式下線了一個(gè)服務(wù),而沒有及時(shí)停掉的話,該服務(wù)很快又會(huì)回到服務(wù)列表中。
所以,可以先停掉服務(wù),再發(fā)送請求將其從列表中移除。
3、客戶端主動(dòng)下線
// 客戶端(SpringBoot應(yīng)用)可以通過如下代碼主動(dòng)通知注冊中心下線
DiscoveryManager.getInstance().shutdownComponent();
更多參考:
Spring Cloud : 如何優(yōu)雅下線微服務(wù)?
Eureka:常見問題總結(jié)
反向代理與負(fù)載均衡
Nginx通過反向代理可以實(shí)現(xiàn)服務(wù)的負(fù)載均衡,避免了服務(wù)器單節(jié)點(diǎn)故障,把請求按照一定的策略轉(zhuǎn)發(fā)到不同的服務(wù)器上,達(dá)到負(fù)載的效果。
常用的負(fù)載均衡策略有
1、輪詢
將請求按順序輪流地分配到后端服務(wù)器上,它均衡地對待后端的每一臺服務(wù)器,而不關(guān)心服務(wù)器實(shí)際的連接數(shù)和當(dāng)前的系統(tǒng)負(fù)載。
2、加權(quán)輪詢
給配置高、負(fù)載低的機(jī)器配置更高的權(quán)重,讓其處理更多的請求
3、ip_hash(源地址哈希法)
根據(jù)獲取客戶端的IP地址,通過哈希函數(shù)計(jì)算得到一個(gè)數(shù)值,用該數(shù)值對服務(wù)器列表的大小進(jìn)行取模運(yùn)算,得到的結(jié)果便是客戶端要訪問服務(wù)器的序號。
4、隨機(jī)
5、least_conn(最小連接數(shù)法)
動(dòng)態(tài)地選取其中當(dāng)前積壓連接數(shù)最少的一臺服務(wù)器來處理當(dāng)前的請求
服務(wù)網(wǎng)關(guān)
客戶端訪問這些后端的多個(gè)微服務(wù),遇到的問題?
--每個(gè)業(yè)務(wù)都會(huì)需要鑒權(quán)、限流、權(quán)限校驗(yàn)等邏輯
--每上線一個(gè)新的服務(wù),都需要運(yùn)維參與,申請域名、配置Nginx等,當(dāng)上線、下線服務(wù)器時(shí),同樣也需要運(yùn)維參與,另外采用域名這種方式,對于環(huán)境的隔離也不太友好
--后端每個(gè)微服務(wù)可能是由不同語言編寫的、采用了不同的協(xié)議,比如HTTP、Dubbo、GRPC等,但是你不可能要求客戶端去適配這么多種協(xié)議
--后期如果需要對微服務(wù)進(jìn)行重構(gòu)的話,也會(huì)變的非常麻煩,需要客戶端配合你一起進(jìn)行改造
網(wǎng)關(guān)做的不僅僅只是簡單的轉(zhuǎn)發(fā),也會(huì)針對流量做一些擴(kuò)展,比如鑒權(quán)、限流、權(quán)限、熔斷、協(xié)議轉(zhuǎn)換、錯(cuò)誤碼統(tǒng)一、緩存、日志、監(jiān)控、告警等
服務(wù)網(wǎng)關(guān)關(guān)注:
API注冊
--(業(yè)務(wù)方如何接入網(wǎng)關(guān)?Swagger的注解、手動(dòng)錄入)
協(xié)議轉(zhuǎn)換
服務(wù)發(fā)現(xiàn)
服務(wù)調(diào)用
緩存
-- 一些重復(fù)的請求,可以在網(wǎng)關(guān)層直接處理,而不用打到業(yè)務(wù)線,降低業(yè)務(wù)方的壓力
限流
--令牌桶等方案。還需要考慮根據(jù)什么限流,比如是IP、接口、用戶維度、還是請求參數(shù)中的某些值,這里可以采用表達(dá)式,相對比較靈活
日志
--提供一個(gè)統(tǒng)一的traceId方便關(guān)聯(lián)所有的日志,可以將這個(gè)traceId置于響應(yīng)頭中,方便排查問題。
優(yōu)雅下線
--Nginx自身是支持健康監(jiān)測機(jī)制的,如果檢測到某一個(gè)節(jié)點(diǎn)已經(jīng)掛掉了,就會(huì)把這個(gè)節(jié)點(diǎn)摘掉,
對于應(yīng)用正常下線,需要結(jié)合發(fā)布系統(tǒng),首先進(jìn)行邏輯下線,然后對后續(xù)Nginx的健康監(jiān)測請求直接返回失敗(比如直接返回500),然后等待一段時(shí)間(根據(jù)Nginx配置決定),然后再將應(yīng)用實(shí)際下線掉。
服務(wù)網(wǎng)關(guān)不足
目前的網(wǎng)關(guān)還是中心化的架構(gòu),所有的請求都需要走一次網(wǎng)關(guān)
目前比較流行的ServiceMesh,采用去中心化的方案,將網(wǎng)關(guān)的邏輯下沉到sidecar中,sidecar和應(yīng)用部署到同一個(gè)節(jié)點(diǎn),并接管應(yīng)用流入、流出的流量,這樣大促時(shí),只需要對相關(guān)的業(yè)務(wù)壓測,并針對性擴(kuò)容即可,另外升級也會(huì)更平滑,
中心化的網(wǎng)關(guān),即使灰度發(fā)布,但是理論上所有業(yè)務(wù)方的流量都會(huì)流入到新版本的網(wǎng)關(guān),如果出了問題,會(huì)影響到所有的業(yè)務(wù),
但這種去中心化的方式,可以先針對非核心業(yè)務(wù)升級,觀察一段時(shí)間沒問題后,再全量推上線。另外ServiceMesh的方案,對于多語言支持也更友好。
分布式事務(wù)
具體參考:微服務(wù):分布式事務(wù)
--事務(wù)提供一種機(jī)制將一個(gè)活動(dòng)涉及的所有操作納入到一個(gè)不可分割的執(zhí)行單元,組成事務(wù)的所有操作
-- 要么什么都不做,要么做全套(All or Nothing)
事務(wù)的ACID屬性
--原子性(Atomicity)要么全部完成,要么全部不完成
--一致性(Consistency)在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫數(shù)據(jù)的一致性約束沒有被破壞
--隔離性(Isolation)數(shù)據(jù)庫允許多個(gè)并發(fā)事務(wù)同時(shí)對數(shù)據(jù)進(jìn)行讀寫和修改的能力
--持久性(Durability) 事務(wù)處理結(jié)束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會(huì)丟失
分布式事務(wù)的實(shí)現(xiàn)方案
二階段提交協(xié)議(Two-phase Commit,即2PC)
階段1:準(zhǔn)備階段
階段2:提交階段
2PC方案實(shí)現(xiàn)起來簡單,實(shí)際項(xiàng)目中使用比較少,主要因?yàn)橐韵聠栴}:
性能問題 :
所有參與者在事務(wù)提交階段處于同步阻塞狀態(tài),占用系統(tǒng)資源,容易導(dǎo)致性能瓶頸。
可靠性問題 :
如果協(xié)調(diào)者存在單點(diǎn)故障問題,如果協(xié)調(diào)者出現(xiàn)故障,參與者將一直處于鎖定狀態(tài)。
數(shù)據(jù)一致性問題:
在階段2中,如果發(fā)生局部網(wǎng)絡(luò)問題,一部分事務(wù)參與者收到了提交消息,另一部分事務(wù)參與者沒收到提交消息,那么就導(dǎo)致了節(jié)點(diǎn)之間數(shù)據(jù)的不一致。
3PC(三階段提交)
--與二階段提交不同的是,引入超時(shí)機(jī)制
階段1:canCommit 檢查是否可以提交
階段2:preCommit 執(zhí)行事務(wù)操作
階段3:do Commit 該階段進(jìn)行真正的事務(wù)提交
方案總結(jié)
優(yōu)點(diǎn)
相比二階段提交,三階段貼近降低了阻塞范圍,在等待超時(shí)后協(xié)調(diào)者或參與者會(huì)中斷事務(wù)。避免了協(xié)調(diào)者單點(diǎn)問題,階段3中協(xié)調(diào)者出現(xiàn)問題時(shí),參與者會(huì)繼續(xù)提交事務(wù)。
缺點(diǎn)
數(shù)據(jù)不一致問題依然存在,當(dāng)在參與者收到preCommit請求后等待do commite指令時(shí),此時(shí)如果協(xié)調(diào)者請求中斷事務(wù),而協(xié)調(diào)者無法與參與者正常通信,會(huì)導(dǎo)致參與者繼續(xù)提交事務(wù),造成數(shù)據(jù)不一致。
TCC (Try-Confirm-Cancel)事務(wù) —— 最終一致性
?
--Try操作作為一階段,負(fù)責(zé)資源的檢查和預(yù)留。
--Confirm操作作為二階段提交操作,執(zhí)行真正的業(yè)務(wù)。
--Cancel是預(yù)留資源的取消。
TCC事務(wù)機(jī)制相對于傳統(tǒng)事務(wù)機(jī)制(X/Open XA),TCC事務(wù)機(jī)制相比于上面介紹的XA事務(wù)機(jī)制,有以下優(yōu)點(diǎn):
性能提升: 具體業(yè)務(wù)來實(shí)現(xiàn)控制資源鎖的粒度變小,不會(huì)鎖定整個(gè)資源。
數(shù)據(jù)最終一致性: 基于Confirm和Cancel的冪等性,保證事務(wù)最終完成確認(rèn)或者取消,保證數(shù)據(jù)的一致性。
可靠性: 解決了XA協(xié)議的協(xié)調(diào)者單點(diǎn)故障問題,由主業(yè)務(wù)方發(fā)起并控制整個(gè)業(yè)務(wù)活動(dòng),業(yè)務(wù)活動(dòng)管理器也變成多點(diǎn),引入集群。
缺點(diǎn):
TCC的Try、Confirm和Cancel操作功能要按具體業(yè)務(wù)來實(shí)現(xiàn),業(yè)務(wù)耦合度較高,提高了開發(fā)成本。
本地消息表 —— 最終一致性
事務(wù)主動(dòng)發(fā)起方額外新建事務(wù)消息表,事務(wù)發(fā)起方處理業(yè)務(wù)和記錄事務(wù)消息在本地事務(wù)中完成,輪詢事務(wù)消息表的數(shù)據(jù)發(fā)送事務(wù)消息,事務(wù)被動(dòng)方基于消息中間件消費(fèi)事務(wù)消息表中的事務(wù)。
這樣設(shè)計(jì)可以避免”業(yè)務(wù)處理成功 + 事務(wù)消息發(fā)送失敗",或"業(yè)務(wù)處理失敗 + 事務(wù)消息發(fā)送成功"的棘手情況出現(xiàn),保證2個(gè)系統(tǒng)事務(wù)的數(shù)據(jù)一致性。
MQ事務(wù) —— 最終一致性
基于MQ的分布式事務(wù)方案其實(shí)是對本地消息表的封裝,將本地消息表基于MQ 內(nèi)部,
相比本地消息表方案,MQ事務(wù)方案優(yōu)點(diǎn)是:
- 消息數(shù)據(jù)獨(dú)立存儲 ,降低業(yè)務(wù)系統(tǒng)與消息系統(tǒng)之間的耦合。
- 吞吐量高
缺點(diǎn)是:
- 一次消息發(fā)送需要兩次網(wǎng)絡(luò)請求(half消息 + commit/rollback消息)
- 業(yè)務(wù)處理服務(wù)需要實(shí)現(xiàn)消息狀態(tài)回查接口
Saga事務(wù) —— 最終一致性
每個(gè)Saga事務(wù)由一系列冪等的有序子事務(wù)(sub-transaction) Ti 組成。
每個(gè)Ti 都有對應(yīng)的冪等補(bǔ)償動(dòng)作Ci,補(bǔ)償動(dòng)作用于撤銷Ti造成的結(jié)果。
Saga事務(wù)常見的有兩種不同的實(shí)現(xiàn)方式:
1、命令協(xié)調(diào)(Order Orchestrator):中央?yún)f(xié)調(diào)器負(fù)責(zé)集中處理事件的決策和業(yè)務(wù)邏輯排序。
中央?yún)f(xié)調(diào)器(Orchestrator,簡稱OSO)以命令/回復(fù)的方式與每項(xiàng)服務(wù)進(jìn)行通信,全權(quán)負(fù)責(zé)告訴每個(gè)參與者該做什么以及什么時(shí)候該做什么。
2、事件編排 (Event Choreography):沒有中央?yún)f(xié)調(diào)器(沒有單點(diǎn)風(fēng)險(xiǎn))時(shí),每個(gè)服務(wù)產(chǎn)生并觀察其他服務(wù)的事件,并決定是否應(yīng)采取行動(dòng)。
集群容錯(cuò)
容錯(cuò)模式
艙壁隔離模式
- 微服務(wù)容器分組、線程池隔離避免一個(gè)服務(wù)拖垮整個(gè)系統(tǒng)
熔斷模式
- 熔斷后快速失敗
限流模式
- 高峰期限制訪問的并發(fā)量
失敗轉(zhuǎn)移模式
容錯(cuò)機(jī)制
Failover 失敗自動(dòng)切換
- 當(dāng)出現(xiàn)失敗,重試其它服務(wù)器,通常用于讀操作(推薦使用)。 重試會(huì)帶來更長延遲。
Failfast??快速失敗
- 只發(fā)起一次調(diào)用,失敗立即報(bào)錯(cuò),通常用于非冪等性的寫操作。 如果有機(jī)器正在重啟,可能會(huì)出現(xiàn)調(diào)用失敗 。
Failsafe 失敗安全
- 出現(xiàn)異常時(shí),直接忽略,通常用于寫入審計(jì)日志等操作。 調(diào)用信息丟失 可用于生產(chǎn)環(huán)境 Monitor。
Failback??失敗自動(dòng)恢復(fù)
- 后臺記錄失敗請求,定時(shí)重發(fā)。通常用于消息通知操作 不可靠,重啟丟失。 可用于生產(chǎn)環(huán)境 Registry。
Forking ?并行調(diào)用多個(gè)服務(wù)器
- 只要一個(gè)成功即返回,通常用于實(shí)時(shí)性要求較高的讀操作。 需要浪費(fèi)更多服務(wù)資源 ? 。
Broadcast?
- 廣播調(diào)用,所有提供逐個(gè)調(diào)用,任意一臺報(bào)錯(cuò)則報(bào)錯(cuò)。通常用于更新提供方本地狀態(tài) 速度慢,任意一臺報(bào)錯(cuò)則報(bào)錯(cuò) 。?
容器監(jiān)控
監(jiān)控主要解決的是感知系統(tǒng)的狀況
為什么需要監(jiān)控?
要監(jiān)控什么
冪等機(jī)制
一個(gè)冪等操作的特點(diǎn)是指其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。
冪等場景
冪等解決方案
總結(jié)
以上是生活随笔為你收集整理的微服务:知识点梳理(SOA、服务拆分、服务治理、分布式事务)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python爬虫利器五Selenium用
- 下一篇: 手把手教你做产品经理,视频课教程已经发布