分布式系統(tǒng)原理

高可用是指系統(tǒng)無(wú)中斷的執(zhí)行功能的能力柱查,代表了系統(tǒng)的可用程度廓俭,是進(jìn)行系統(tǒng)設(shè)計(jì)時(shí)必須要遵守的準(zhǔn)則之一。
而高可用的實(shí)現(xiàn)方案唉工,無(wú)外乎就是冗余研乒,就存儲(chǔ)的高可用而言,問題不在于如何進(jìn)行數(shù)據(jù)備份淋硝,而在于如何規(guī)避數(shù)據(jù)不一致對(duì)業(yè)務(wù)造成的影響雹熬。
對(duì)于分布式系統(tǒng)而言,要保證分布式系統(tǒng)中的數(shù)據(jù)一致性就需要一種方案谣膳,可以保證數(shù)據(jù)在子系統(tǒng)中始終保持一致竿报,避免業(yè)務(wù)出現(xiàn)問題。
這種實(shí)現(xiàn)方案就叫做分布式事務(wù)继谚,要么一起成功烈菌,要么一起失敗,必須是一個(gè)整體性的事務(wù)犬庇。

1僧界、理論基礎(chǔ)

1.1 CAP

CAP,Consistency Availability Partition tolerance 的簡(jiǎn)寫:

Consistency:一致性臭挽,對(duì)某個(gè)客戶端來(lái)說(shuō)捂襟,讀操作能夠返回最新的寫操作結(jié)果。
Availability:可用性欢峰,非故障節(jié)點(diǎn)在合理的時(shí)間內(nèi)返回合理的響應(yīng)葬荷。
Partition tolerance:分區(qū)容錯(cuò)性涨共,分布式系統(tǒng)中系統(tǒng)肯定部署在多臺(tái)機(jī)器上,無(wú)法保證網(wǎng)絡(luò)做到 100% 的可靠宠漩,所以網(wǎng)絡(luò)分區(qū)一定存在举反,即 P 一定存在。

在出現(xiàn)網(wǎng)絡(luò)分區(qū)后扒吁,就出現(xiàn)了可用性和一致性的問題火鼻,我們必須要在這兩者之間進(jìn)行取舍,因此就有了兩種架構(gòu):

  • CP 架構(gòu)
  • AP 架構(gòu)

1.2 BASE理論

BASE 理論指的是基本可用 Basically Available雕崩,軟狀態(tài) Soft State魁索,最終一致性 Eventual Consistency,核心思想是即便無(wú)法做到強(qiáng)一致性盼铁,但應(yīng)該采用適合的方式保證最終一致性粗蔚。

BASE,Basically Available Soft State Eventual Consistency 的簡(jiǎn)寫:
BA:Basically Available 基本可用饶火,分布式系統(tǒng)在出現(xiàn)故障的時(shí)候鹏控,允許損失部分可用性,即保證核心可用肤寝。
S:Soft State 軟狀態(tài)当辐,允許系統(tǒng)存在中間狀態(tài)鲤看,而該中間狀態(tài)不會(huì)影響系統(tǒng)整體可用性瀑构。
E:Consistency 最終一致性,系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過(guò)一定時(shí)間后刨摩,最終能夠達(dá)到一致的狀態(tài)。

BASE 理論本質(zhì)上是對(duì) CAP 理論的延伸世吨,是對(duì) CAP 中 AP 方案的一個(gè)補(bǔ)充澡刹。

2、分布式事務(wù)協(xié)議

2.1 二階段提交協(xié)議:2PC

2.1.1 概述

二階段提交(Two-phase Commit)耘婚,是指罢浇,為了使基于分布式系統(tǒng)架構(gòu)下的所有節(jié)點(diǎn)在進(jìn)行事務(wù)提交時(shí)保持一致性而設(shè)計(jì)的一種算法(Algorithm)。通常沐祷,二階段提交也被稱為是一種協(xié)議(Protocol)颤诀。

在分布式系統(tǒng)中薪鹦,每個(gè)節(jié)點(diǎn)雖然可以知曉自己的操作是成功或者失敗,卻無(wú)法知道其他節(jié)點(diǎn)的操作是成功或失敗。

當(dāng)一個(gè)事務(wù)跨越多個(gè)節(jié)點(diǎn)時(shí)养叛,為了保持事務(wù)的 ACID 特性,需要引入一個(gè)作為協(xié)調(diào)者的組件來(lái)統(tǒng)一掌控所有節(jié)點(diǎn)(稱作參與者)的操作結(jié)果并最終指示這些節(jié)點(diǎn)是否要把操作結(jié)果進(jìn)行真正的提交(比如將更新后的數(shù)據(jù)寫入磁盤等等)猎醇。

因此,二階段提交的算法思路可以概括為:參與者將操作成敗通知協(xié)調(diào)者顺饮,再由協(xié)調(diào)者根據(jù)所有參與者的反饋情報(bào)決定各參與者是否要提交操作還是中止操作。

2.1.2 二階段提交過(guò)程
  • 投票階段
image.png

投票階段執(zhí)行流程:

  1. 協(xié)調(diào)者向所有參與者詢問是否可以執(zhí)行提交操作凌那,并開始等待各參與者的響應(yīng)兼雄。
  2. 參與者執(zhí)行事務(wù)操作,如果執(zhí)行成功就返回 Yes 響應(yīng)帽蝶,如果執(zhí)行失敗就返回 No 響應(yīng)赦肋。
  3. 如果協(xié)調(diào)者接受參與者響應(yīng)超時(shí),也會(huì)認(rèn)為執(zhí)行事務(wù)操作失敗励稳。
  • 提交階段
image.png

提交階段執(zhí)行流程:

  1. 如果第一階段匯總所有參與者都返回 Yes 響應(yīng)佃乘,協(xié)調(diào)者向所有參與者發(fā)出提交請(qǐng)求,所有參與者提交事務(wù)麦锯。
  2. 如果第一階段中有一個(gè)或者多個(gè)參與者返回 No 響應(yīng)恕稠,協(xié)調(diào)者向所有參與者發(fā)出回滾請(qǐng)求,所有參與者進(jìn)行回滾操作扶欣。
2.1.3 優(yōu)缺點(diǎn)
  • 優(yōu)點(diǎn)
    盡量保證了數(shù)據(jù)的強(qiáng)一致鹅巍,但不是 100% 一致

  • 缺點(diǎn)

    1. 單點(diǎn)故障,由于協(xié)調(diào)者的重要性料祠,一旦協(xié)調(diào)者發(fā)生故障骆捧,參與者會(huì)一直阻塞,尤其是在第二階段髓绽,協(xié)調(diào)者發(fā)生故障敛苇,那么所有的參與者都處于鎖定事務(wù)資源的狀態(tài)中,而無(wú)法繼續(xù)完成事務(wù)操作顺呕。
    2. 同步阻塞枫攀,由于所有節(jié)點(diǎn)在執(zhí)行操作時(shí)都是同步阻塞的,當(dāng)參與者占有公共資源時(shí)株茶,其他第三方節(jié)點(diǎn)訪問公共資源不得不處于阻塞狀態(tài)来涨。
    3. 數(shù)據(jù)不一致,在第二階段中启盛,當(dāng)協(xié)調(diào)者向參與者發(fā)送提交事務(wù)請(qǐng)求之后蹦掐,發(fā)生了局部網(wǎng)絡(luò)異常或者在發(fā)送提交事務(wù)請(qǐng)求過(guò)程中協(xié)調(diào)者發(fā)生了故障僵闯,這會(huì)導(dǎo)致只有一部分參與者接收到了提交事務(wù)請(qǐng)求卧抗。
      而在這部分參與者接到提交事務(wù)請(qǐng)求之后就會(huì)執(zhí)行提交事務(wù)操作。但是其他部分未接收到提交事務(wù)請(qǐng)求的參與者則無(wú)法提交事務(wù)鳖粟。從而導(dǎo)致分布式系統(tǒng)中的數(shù)據(jù)不一致社裆。

2.2 三階段提交協(xié)議:3PC

2.2.1 概述

三階段提交(Three-phase commit),是為解決兩階段提交協(xié)議的缺點(diǎn)而設(shè)計(jì)的牺弹。與兩階段提交不同的是浦马,三階段提交是“非阻塞”協(xié)議时呀。

三階段提交在兩階段提交的第一階段與第二階段之間插入了一個(gè)準(zhǔn)備階段,使得原先在兩階段提交中晶默,參與者在投票之后谨娜,由于協(xié)調(diào)者發(fā)生崩潰或錯(cuò)誤,而導(dǎo)致參與者處于無(wú)法知曉是否提交或者中止的“不確定狀態(tài)”所產(chǎn)生的可能相當(dāng)長(zhǎng)的延時(shí)的問題得以解決磺陡。

2.2.2 三階段提交過(guò)程
image.png

詢問階段:CanCommit
協(xié)調(diào)者向參與者發(fā)送 Commit 請(qǐng)求趴梢,參與者如果可以提交就返回 Yes 響應(yīng),否則返回 No 響應(yīng)币他。

準(zhǔn)備階段:PreCommit
協(xié)調(diào)者根據(jù)參與者在詢問階段的響應(yīng)判斷是否執(zhí)行事務(wù)還是中斷事務(wù):
如果所有參與者都返回 Yes坞靶,則執(zhí)行事務(wù)。
如果參與者有一個(gè)或多個(gè)參與者返回 No 或者超時(shí)蝴悉,則中斷事務(wù)彰阴。
參與者執(zhí)行完操作之后返回 ACK 響應(yīng),同時(shí)開始等待最終指令

提交階段:DoCommit
協(xié)調(diào)者根據(jù)參與者在準(zhǔn)備階段的響應(yīng)判斷是否執(zhí)行事務(wù)還是中斷事務(wù):
如果所有參與者都返回正確的 ACK 響應(yīng)拍冠,則提交事務(wù)尿这。
如果參與者有一個(gè)或多個(gè)參與者收到錯(cuò)誤的 ACK 響應(yīng)或者超時(shí),則中斷事務(wù)庆杜。
如果參與者無(wú)法及時(shí)接收到來(lái)自協(xié)調(diào)者的提交或者中斷事務(wù)請(qǐng)求時(shí)射众,會(huì)在等待超時(shí)之后,會(huì)繼續(xù)進(jìn)行事務(wù)提交晃财。
協(xié)調(diào)者收到所有參與者的 ACK 響應(yīng)叨橱,完成事務(wù)。

2.2.3 解決二階段提交時(shí)的問題:

三階段提交解決了二階段提交中存在的由于協(xié)調(diào)者和參與者同時(shí)掛掉可能導(dǎo)致的數(shù)據(jù)一致性問題和單點(diǎn)故障問題断盛,并減少阻塞罗洗。
因?yàn)橐坏﹨⑴c者無(wú)法及時(shí)收到來(lái)自協(xié)調(diào)者的信息之后,他會(huì)默認(rèn)執(zhí)行提交事務(wù)(三階段)钢猛,而不會(huì)一直持有事務(wù)資源并處于阻塞狀態(tài)(二階段會(huì))栖博。

2.2.4 三階段提交的問題:

在提交階段如果發(fā)送的是中斷事務(wù)請(qǐng)求,但是由于網(wǎng)絡(luò)問題厢洞,導(dǎo)致部分參與者沒有接到請(qǐng)求。
那么參與者會(huì)在等待超時(shí)之后執(zhí)行提交事務(wù)操作典奉,這樣這些由于網(wǎng)絡(luò)問題導(dǎo)致提交事務(wù)的參與者的數(shù)據(jù)就與接受到中斷事務(wù)請(qǐng)求的參與者存在數(shù)據(jù)不一致的問題躺翻。

所以無(wú)論是 2PC 還是 3PC 都不能保證分布式系統(tǒng)中的數(shù)據(jù) 100% 一致。

2.3 ZAB——zookeeper 原子廣播協(xié)議

2.3.1 概述

ZAB 協(xié)議全稱是Zookeeper Atomic Broadcast卫玖,是為分布式協(xié)調(diào)服務(wù) Zookeeper 專門設(shè)計(jì)的一種支持 崩潰恢復(fù)原子廣播 協(xié)議公你。
ZAB 協(xié)議滿足CP,在選舉過(guò)程中假瞬,是不能對(duì)外提供服務(wù)的陕靠。

2.3.3 消息廣播

ZAB 協(xié)議的消息廣播過(guò)程(即數(shù)據(jù)同步過(guò)程)使用的是一個(gè)原子廣播協(xié)議迂尝,類似一個(gè) 二階段提交過(guò)程。對(duì)于客戶端發(fā)送的寫請(qǐng)求剪芥,全部由 Leader 接收垄开,Leader 將請(qǐng)求封裝成一個(gè)事務(wù) Proposal,將其發(fā)送給所有 Follwer 税肪,然后溉躲,根據(jù)所有 Follwer 的反饋,如果超過(guò)半數(shù)成功響應(yīng)益兄,則執(zhí)行 commit 操作(先提交自己锻梳,再發(fā)送 commit 給所有 Follwer)。

廣播流程

image.png
    1. 客戶端發(fā)起一個(gè)寫操作請(qǐng)求净捅。
    1. Leader 服務(wù)器將客戶端的請(qǐng)求轉(zhuǎn)化為事務(wù) Proposal 提案疑枯,同時(shí)為每個(gè) Proposal 分配一個(gè)全局的ID,即zxid蛔六。然后將需要廣播的Proposal 依次放到隊(duì)列中荆永,并且根據(jù) FIFO 策略進(jìn)行消息發(fā)送。
    1. Follower 接收到 Proposal 后古今,會(huì)首先將其以事務(wù)日志的方式寫入本地磁盤中屁魏,寫入成功后向 Leader 反饋一個(gè) Ack 響應(yīng)消息。
    1. Leader 接收到超過(guò)半數(shù)以上 Follower 的 Ack 響應(yīng)消息后捉腥,即認(rèn)為消息發(fā)送成功氓拼,可以發(fā)送 commit 消息。
    1. Leader 向所有 Follower 廣播 commit 消息抵碟,同時(shí)自身也會(huì)完成事務(wù)提交桃漾。Follower 接收到 commit 消息后,會(huì)將上一條事務(wù)提交拟逮。

注意:
1撬统、 Leader 服務(wù)器與每一個(gè) Follower 服務(wù)器之間都維護(hù)了一個(gè)單獨(dú)的 FIFO 消息隊(duì)列進(jìn)行收發(fā)消息,使用隊(duì)列消息可以做到異步解耦敦迄。 Leader 和 Follower 之間只需要往隊(duì)列中發(fā)消息即可
2恋追、Leader 在收到客戶端請(qǐng)求之后,會(huì)將這個(gè)請(qǐng)求封裝成一個(gè)事務(wù)罚屋,并給這個(gè)事務(wù)分配一個(gè)全局遞增的唯一 ID苦囱,稱為事務(wù)ID(ZXID),ZAB 協(xié)議需要保證事務(wù)的順序脾猛,因此必須將每一個(gè)事務(wù)按照 ZXID 進(jìn)行先后排序然后處理
3撕彤、可以認(rèn)為這是一種簡(jiǎn)化版本的 2PC,2PC的單點(diǎn)問題(Leader奔潰)這里也會(huì)遇到猛拴,ZAB是通過(guò)崩潰恢復(fù)來(lái)解決的

2.3.3 崩潰恢復(fù)

所謂崩潰恢復(fù)羹铅,是指當(dāng)leader崩潰(單點(diǎn)故障)后蚀狰,重新選舉leader并且數(shù)據(jù)保持一致性(數(shù)據(jù)同步)。

  • leader選舉:
    選舉是通過(guò)投票來(lái)的职员,主要分為以下幾個(gè)階段麻蹋,
  1. 變更狀態(tài):Leader掛后,余下的Flower服務(wù)器都會(huì)將自己的服務(wù)器狀態(tài)變更為L(zhǎng)OOKING廉邑,然后再開始進(jìn)入Leader選舉過(guò)程哥蔚;

  2. 發(fā)起投票:首輪投票,每個(gè)節(jié)點(diǎn)發(fā)出一個(gè)投票蛛蒙,先投票給自己糙箍,然后再把投票結(jié)果廣播到集群中別的節(jié)點(diǎn),其他機(jī)器牵祟。投票內(nèi)容包含節(jié)點(diǎn)的myid(zookeeper安裝時(shí)要設(shè)置的值深夯,表示當(dāng)前節(jié)點(diǎn)id)和zxid(事務(wù)id),比如ZK1的投票為(1, 0)诺苹,ZK2的投票為(2, 0)

  3. 驗(yàn)證投票:每個(gè)節(jié)點(diǎn)都投票給自己并且廣播之后咕晋,那么節(jié)點(diǎn)就會(huì)收到別的節(jié)點(diǎn)的投票結(jié)果,在收到投票后可以驗(yàn)證投票的有效性收奔,如檢查是否是本輪投票掌呜、是否來(lái)自LOOKING狀態(tài)的服務(wù)器,

  4. 變更投票:驗(yàn)證完收到的投票結(jié)果后坪哄,處理投票质蕉,針對(duì)每一個(gè)投票,服務(wù)器都需要將別人的投票和自己的投票進(jìn)行比較翩肌,規(guī)則如下
    · 優(yōu)先檢查ZXID模暗。ZXID比較大的服務(wù)器優(yōu)先作為L(zhǎng)eader;
    · 如果ZXID相同念祭,那么就比較myid兑宇。myid較大的服務(wù)器作為L(zhǎng)eader服務(wù)器;

  5. 統(tǒng)計(jì)投票:根據(jù)以上規(guī)則變更自己的投票粱坤,然后廣播第二輪投票隶糕,還是同樣的過(guò)程,先驗(yàn)證投票站玄,然后變更投票若厚,變更完成以后統(tǒng)計(jì)票倉(cāng)(本輪投票過(guò)程中接收到的別的節(jié)點(diǎn)的投票信息)中,是否有超過(guò)半數(shù)的相同投票蜒什,如果有,則其就是新的leader疤估,選舉結(jié)束灾常;如果沒有霎冯,則繼續(xù)發(fā)起投票,知道選出leader钞瀑。

  6. **改變服務(wù)器狀態(tài) **:選出leader后沈撞,變更各服務(wù)器狀態(tài),leader從LOOKING變成Leader雕什,別的機(jī)器變成Flower缠俺,然后同步leader數(shù)據(jù)。

image.png

由上面規(guī)則可知贷岸,通常那臺(tái)服務(wù)器上的數(shù)據(jù)越新(ZXID會(huì)越大)壹士,其成為L(zhǎng)eader的可能性越大,也就越能夠保證數(shù)據(jù)的恢復(fù)偿警。如果ZXID相同躏救,則SID越大機(jī)會(huì)越大。

  • 數(shù)據(jù)同步:
    上面的leader選舉結(jié)束后螟蒸,只有當(dāng)新的leader和follower同步數(shù)據(jù)之后盒使,才能對(duì)外提供服務(wù)。
    同步分為以下幾個(gè)階段:
  1. 所有follower上報(bào)自己最后接收的事務(wù)的任期epoch(每個(gè)Proposal都包含了一個(gè)epoch值七嫌,用來(lái)代表當(dāng)前的Leader 周期)少办;leader比較所有的任期,選取最大的epoch诵原,加1后作為當(dāng)前的任期E=E+1英妓,并且將任期epoch廣播給所有follower;follower將任期改為leader發(fā)過(guò)來(lái)的值之后皮假,返回給leader當(dāng)前follewer節(jié)點(diǎn)上的事務(wù)隊(duì)列L鞋拟;

  2. leader從隊(duì)列集合中選取任期最大的隊(duì)列,如果有多個(gè)隊(duì)列任期都是最大惹资,則選取事務(wù)編號(hào)n最大的隊(duì)列Lmax(通常就是leader節(jié)點(diǎn)自己的事務(wù)隊(duì)列贺纲,因?yàn)檫x舉leader時(shí),就是選出的事務(wù)zxid最大的節(jié)點(diǎn))褪测,并將其廣播給各個(gè)follower猴誊,follower接收隊(duì)列替換自己的事務(wù)隊(duì)列,并且執(zhí)行隊(duì)列中的事務(wù)(執(zhí)行過(guò)跳過(guò)侮措,未執(zhí)行執(zhí)行)懈叹,執(zhí)行完以后反饋給leader 表明自己已經(jīng)完成同步(追上來(lái)了),leader 收到過(guò)半反饋后分扎,發(fā)送commit 消息澄成;follower 接收到commit 消息后,提交事務(wù);
    至此各個(gè)節(jié)點(diǎn)的數(shù)據(jù)達(dá)成一致墨状,zookeeper恢復(fù)正常服務(wù)卫漫。

注意:在zk選舉中,通過(guò)投票已經(jīng)確認(rèn)leader服務(wù)器是最大的zxid的節(jié)點(diǎn)了肾砂,所以同步過(guò)程沒有那么復(fù)雜列赎。
同步階段主要是利用 Leader 前一階段獲得的最新 Proposal 歷史,同步集群中所有的副本镐确。只有當(dāng)超過(guò)半數(shù)的節(jié)點(diǎn)都同步完成包吝,準(zhǔn) Leader 才會(huì)成為真正的 Leader。Follower 只會(huì)處理 zxid 比自己 lastZxid 大的 Proposal源葫。

3诗越、最終一致性分布式事務(wù)方案

3.1 本地消息表

本地消息表的核心思想是將分布式事務(wù)拆分成本地事務(wù)進(jìn)行處理。

例如臼氨,在訂單系統(tǒng)新增一條消息表掺喻,將新增訂單和新增消息放到一個(gè)事務(wù)里完成,然后通過(guò)輪詢的方式去查詢消息表储矩,將消息推送到 MQ感耙,庫(kù)存系統(tǒng)去消費(fèi) MQ。

image.png
執(zhí)行流程:
  1. 訂單系統(tǒng)持隧,添加一條訂單和一條消息即硼,在一個(gè)事務(wù)里提交。

  2. 訂單系統(tǒng)屡拨,使用定時(shí)任務(wù)輪詢查詢狀態(tài)為未同步的消息表只酥,發(fā)送到 MQ,如果發(fā)送失敗呀狼,就重試發(fā)送裂允。

  3. 庫(kù)存系統(tǒng),接收 MQ 消息哥艇,修改庫(kù)存表绝编,需要保證冪等操作。

  4. 如果修改成功貌踏,調(diào)用 RPC 接口修改訂單系統(tǒng)消息表的狀態(tài)為已完成或者直接刪除這條消息十饥。
    如果修改失敗,可以不做處理祖乳,等待重試逗堵。

訂單系統(tǒng)中的消息有可能由于業(yè)務(wù)問題會(huì)一直重復(fù)發(fā)送,所以為了避免這種情況可以記錄一下發(fā)送次數(shù)眷昆,當(dāng)達(dá)到次數(shù)限制之后報(bào)警蜒秤,人工接入處理汁咏;庫(kù)存系統(tǒng)需要保證冪等,避免同一條消息被多次消費(fèi)造成數(shù)據(jù)一致作媚。

本地消息表這種方案實(shí)現(xiàn)了最終一致性梆暖,需要在業(yè)務(wù)系統(tǒng)里增加消息表,業(yè)務(wù)邏輯中多一次插入的 DB 操作掂骏,所以性能會(huì)有損耗,而且最終一致性的間隔主要由定時(shí)任務(wù)的間隔時(shí)間決定厚掷。

3.2 MQ 消息事務(wù)

消息事務(wù)的原理是將兩個(gè)事務(wù)通過(guò)消息中間件進(jìn)行異步解耦弟灼。

image.png

從上面可以看出,消息事務(wù)一定要保證業(yè)務(wù)操作與消息發(fā)送的一致性冒黑,如果業(yè)務(wù)操作成功田绑,這條消息也一定投遞成功。

消息事務(wù)依賴于消息中間件的事務(wù)消息抡爹,基于消息中間件的二階段提交實(shí)現(xiàn)的掩驱,RocketMQ 就支持事務(wù)消息。RabbitMQ也支持事務(wù)消息

執(zhí)行流程:
  1. 發(fā)送 Prepare 消息到消息中間件冬竟。
  2. 發(fā)送成功后欧穴,執(zhí)行本地事務(wù)。
  3. 如果事務(wù)執(zhí)行成功泵殴,則 Commit涮帘,消息中間件將消息下發(fā)至消費(fèi)端。
  4. 如果事務(wù)執(zhí)行失敗笑诅,則回滾调缨,消息中間件將這條 Prepare 消息刪除。
  5. 消費(fèi)端接收到消息進(jìn)行消費(fèi)吆你,如果消費(fèi)失敗弦叶,則不斷重試。

這種方案也是實(shí)現(xiàn)了最終一致性妇多,對(duì)比本地消息表實(shí)現(xiàn)方案伤哺,不需要再建消息表,不再依賴本地?cái)?shù)據(jù)庫(kù)事務(wù)了砌梆,所以這種方案更適用于高并發(fā)的場(chǎng)景默责。

3.3 最大努力通知

最大努力通知相比前兩種方案實(shí)現(xiàn)簡(jiǎn)單,適用于一些最終一致性要求較低的業(yè)務(wù)咸包,比如支付通知桃序,短信通知這種業(yè)務(wù)。
以支付通知為例烂瘫,業(yè)務(wù)系統(tǒng)調(diào)用支付平臺(tái)進(jìn)行支付媒熊,支付平臺(tái)進(jìn)行支付奇适,進(jìn)行操作支付之后支付平臺(tái)會(huì)盡量去通知業(yè)務(wù)系統(tǒng)支付操作是否成功,但是會(huì)有一個(gè)最大通知次數(shù)芦鳍。
如果超過(guò)這個(gè)次數(shù)后還是通知失敗嚷往,就不再通知,業(yè)務(wù)系統(tǒng)自行調(diào)用支付平臺(tái)提供一個(gè)查詢接口柠衅,供業(yè)務(wù)系統(tǒng)進(jìn)行查詢支付操作是否成功皮仁。

image.png
執(zhí)行流程:
  1. 業(yè)務(wù)系統(tǒng)調(diào)用支付平臺(tái)支付接口, 并在本地進(jìn)行記錄菲宴,支付狀態(tài)為支付中贷祈。
  2. 支付平臺(tái)進(jìn)行支付操作之后,無(wú)論成功還是失敗喝峦,都需要給業(yè)務(wù)系統(tǒng)一個(gè)結(jié)果通知势誊。
  3. 如果通知一直失敗則根據(jù)重試規(guī)則進(jìn)行重試,達(dá)到最大通知次數(shù)后谣蠢,不再通知粟耻。
  4. 支付平臺(tái)提供查詢訂單支付操作結(jié)果接口。
  5. 業(yè)務(wù)系統(tǒng)根據(jù)一定業(yè)務(wù)規(guī)則去支付平臺(tái)查詢支付結(jié)果眉踱。

這種方案也是實(shí)現(xiàn)了最終一致性挤忙。

3.4 補(bǔ)償事務(wù) TCC

TCC,Try-Confirm-Cancel 的簡(jiǎn)稱勋锤,針對(duì)每個(gè)操作饭玲,都需要有一個(gè)其對(duì)應(yīng)的確認(rèn)和取消操作。
當(dāng)操作成功時(shí)調(diào)用確認(rèn)操作叁执,當(dāng)操作失敗時(shí)調(diào)用取消操作茄厘,類似于二階段提交,只不過(guò)是這里的提交和回滾是針對(duì)業(yè)務(wù)上的谈宛,所以基于 TCC 實(shí)現(xiàn)的分布式事務(wù)也可以看做是對(duì)業(yè)務(wù)的一種補(bǔ)償機(jī)制次哈。

3.4.1 TCC 的三個(gè)階段:
  • Try 階段:對(duì)業(yè)務(wù)系統(tǒng)做檢測(cè)及資源預(yù)留、凍結(jié)吆录。

  • Confirm 階段:對(duì)業(yè)務(wù)系統(tǒng)做確認(rèn)提交窑滞,Try 階段執(zhí)行成功并開始執(zhí)行 Confirm 階段時(shí),默認(rèn) Confirm 階段是不會(huì)出錯(cuò)的恢筝。即:只要 Try 成功哀卫,Confirm 一定成功。

  • Cancel 階段:在業(yè)務(wù)執(zhí)行錯(cuò)誤撬槽,需要回滾的狀態(tài)下執(zhí)行的業(yè)務(wù)取消此改,預(yù)留資源釋放。

在 Try 階段侄柔,是對(duì)業(yè)務(wù)系統(tǒng)進(jìn)行檢查及資源預(yù)覽共啃,比如訂單和存儲(chǔ)操作占调,需要檢查庫(kù)存剩余數(shù)量是否夠用,并進(jìn)行預(yù)留移剪,預(yù)留操作的話就是新建一個(gè)可用庫(kù)存數(shù)量字段究珊,Try 階段操作是對(duì)這個(gè)可用庫(kù)存數(shù)量進(jìn)行操作。

3.4.2 TCC執(zhí)行流程:

步驟一(Try 階段):訂單系統(tǒng)將當(dāng)前訂單狀態(tài)設(shè)置為支付中纵苛,庫(kù)存系統(tǒng)校驗(yàn)當(dāng)前剩余庫(kù)存數(shù)量是否大于 2剿涮,然后將可用庫(kù)存數(shù)量設(shè)置為庫(kù)存剩余數(shù)量 -2,并且設(shè)置凍結(jié)庫(kù)存為2

  • image.png

步驟二(Confirm 階段):如果 Try 階段執(zhí)行成功攻人,執(zhí)行 Confirm 階段幔虏,將訂單狀態(tài)修改為支付成功,庫(kù)存剩余數(shù)量修改為可用庫(kù)存數(shù)量贝椿。

  • image.png

步驟三(Cancel 階段):如果 Try 階段執(zhí)行失敗,執(zhí)行 Cancel 階段陷谱,將訂單狀態(tài)修改為支付失敗烙博,可用庫(kù)存數(shù)量修改為庫(kù)存剩余數(shù)量。

  • image.png
image.png
3.4.3 基于 TCC 實(shí)現(xiàn)的分布式事務(wù)框架:

ByteTCC烟逊,github.com/liuyangming
tcc-transaction:github.com/changmingxi

參考:https://mp.weixin.qq.com/s/Rowg-rEQZnaSaupJ9Q7kJw

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渣窜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宪躯,更是在濱河造成了極大的恐慌乔宿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件访雪,死亡現(xiàn)場(chǎng)離奇詭異详瑞,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)臣缀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門坝橡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)眯勾,“玉大人嫂易,你說(shuō)我怎么就攤上這事〕捉” “怎么了脂倦?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵番宁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我赖阻,道長(zhǎng)蝶押,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任政供,我火速辦了婚禮播聪,結(jié)果婚禮上朽基,老公的妹妹穿的比我還像新娘。我一直安慰自己离陶,他們只是感情好稼虎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著招刨,像睡著了一般霎俩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沉眶,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天打却,我揣著相機(jī)與錄音,去河邊找鬼谎倔。 笑死柳击,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的片习。 我是一名探鬼主播捌肴,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼藕咏!你這毒婦竟也來(lái)了状知?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤孽查,失蹤者是張志新(化名)和其女友劉穎饥悴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盲再,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡西设,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了答朋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片济榨。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绿映,靈堂內(nèi)的尸體忽然破棺而出擒滑,到底是詐尸還是另有隱情,我是刑警寧澤叉弦,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布丐一,位于F島的核電站,受9級(jí)特大地震影響淹冰,放射性物質(zhì)發(fā)生泄漏库车。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一樱拴、第九天 我趴在偏房一處隱蔽的房頂上張望柠衍。 院中可真熱鬧洋满,春花似錦、人聲如沸珍坊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阵漏。三九已至驻民,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間履怯,已是汗流浹背回还。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叹洲,地道東北人柠硕。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像运提,于是被迫代替她去往敵國(guó)和親仅叫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355