您好,登錄后才能下訂單哦!
這篇文章主要介紹了apache rocketmq中柔性事務(wù)一致性的示例分析,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
TCC分段提交適用分布式架構(gòu)中對一致性、實(shí)時(shí)性要求較高的業(yè)務(wù)場景,在實(shí)際業(yè)務(wù)中也存在實(shí)時(shí)性比較低的業(yè)務(wù),例如常見的短信通知,客戶端消息,運(yùn)營體系更新等業(yè)務(wù),這時(shí)候?yàn)榱藴p輕核心流程的復(fù)雜度和壓力,可以采取最大努力通知方式實(shí)現(xiàn)柔性事務(wù)的管理。
例如常見的第三方支付業(yè)務(wù)中,本地業(yè)務(wù)和支付端業(yè)務(wù)處理完成之后都會(huì)生成消息通知,基本流程如下:
本地業(yè)務(wù)預(yù)處理完成之后;
請求第三方支付服務(wù);
支付操作成功對該賬號發(fā)送消息;
支付服務(wù)回調(diào)本地業(yè)務(wù);
本地業(yè)務(wù)生成系統(tǒng)通知消息;
上述流程的消息場景中有一些基礎(chǔ)特點(diǎn),在核心業(yè)務(wù)處理完成之后,發(fā)送消息通知,允許失敗,在指定時(shí)間段內(nèi)或者指定重試次數(shù)之后,允許消息丟失情況存在,即消息的不可靠性。
在實(shí)際的支付系統(tǒng)中,啟動(dòng)每日對賬校驗(yàn)時(shí)會(huì)對當(dāng)日的流水做校驗(yàn),如果發(fā)現(xiàn)支付流水有未完成的流程,會(huì)有狀態(tài)彌補(bǔ),后續(xù)可以繼續(xù)處理,這種手段在對賬中很常用。
分布式事務(wù)基于可靠消息最終一致性的實(shí)現(xiàn)方案,既然是可靠消息,則要求MQ必須支持事務(wù)管理,這樣才能保證業(yè)務(wù)前后一致性。
RocketMQ在4.3版中開始支持分布式事務(wù)消息,采用2PC的思想來實(shí)現(xiàn)了提交事務(wù)消息,同時(shí)增加一個(gè)補(bǔ)償邏輯來處理二階段超時(shí)或者失敗的消息,如下圖所示:
上圖說明了事務(wù)消息的大致方案,其中分為兩個(gè)流程:正常事務(wù)消息的發(fā)送及提交、事務(wù)消息的補(bǔ)償流程。
1.1 發(fā)送及提交
(1)發(fā)送消息(half消息,即發(fā)送但不被消費(fèi));
(2)服務(wù)端響應(yīng)消息寫入結(jié)果;
(3)根據(jù)發(fā)送結(jié)果執(zhí)行本地事務(wù),如果寫入失敗,此時(shí)half消息對業(yè)務(wù)不可見,本地邏輯不執(zhí)行;
(4) 根據(jù)本地事務(wù)狀態(tài)執(zhí)行Commit或者Rollback(Commit操作生成消息索引,消息對消費(fèi)者可見)
1.1 補(bǔ)償流程
(1)對沒有Commit/Rollback的事務(wù)消息(pending狀態(tài)的消息),從服務(wù)端發(fā)起一次“回查”;
(2)Producer收到回查消息,檢查回查消息對應(yīng)的本地事務(wù)的狀態(tài);
(3)根據(jù)本地事務(wù)狀態(tài),重新Commit或者Rollback;
其中,補(bǔ)償階段用于解決消息Commit或者Rollback發(fā)生超時(shí)或者失敗的情況。
1.3 設(shè)計(jì)原理
在RocketMQ事務(wù)消息的主要流程中,一階段的消息如何對用戶不可見。其中,事務(wù)消息相對普通消息最大的特點(diǎn)就是一階段發(fā)送的消息對用戶是不可見的。那么,如何做到寫入消息但是對用戶不可見呢?RocketMQ事務(wù)消息的做法是:如果消息是half消息,將備份原消息的主題與消息消費(fèi)隊(duì)列,然后改變主題為RMQ_SYS_TRANS_HALF_TOPIC。由于消費(fèi)組未訂閱該主題,故消費(fèi)端無法消費(fèi)half類型的消息,然后RocketMQ會(huì)開啟一個(gè)定時(shí)任務(wù),從Topic為RMQ_SYS_TRANS_HALF_TOPIC中拉取消息進(jìn)行消費(fèi),根據(jù)生產(chǎn)者組獲取一個(gè)服務(wù)提供者發(fā)送回查事務(wù)狀態(tài)請求,根據(jù)事務(wù)狀態(tài)來決定是提交或回滾消息。
基于上述RocketMQ事務(wù)消息可靠性的特點(diǎn),即可以實(shí)現(xiàn)某類業(yè)務(wù)下事務(wù)的最終一致性。消息發(fā)送一致性是指產(chǎn)生消息的業(yè)務(wù)動(dòng)作與消息發(fā)送一致,也就是說如果業(yè)務(wù)操作成功,那么由這個(gè)業(yè)務(wù)操作所產(chǎn)生的異步消息一定要發(fā)送出去,否則就業(yè)務(wù)失敗回滾,消息也會(huì)丟棄。
流程基本如下:
發(fā)送half事務(wù)消息,無法被消費(fèi);
本地業(yè)務(wù)代碼邏輯處理完成;
發(fā)送確認(rèn)消息,標(biāo)識該消息可以消費(fèi);
如果消息生產(chǎn)方異常,取消整體動(dòng)作;
該流程主要針對消息生產(chǎn)方,在實(shí)際開發(fā)中,消息的消費(fèi)方也一樣很難處理,要保證最終一致性,必然會(huì)面對一個(gè)問題,消費(fèi)方異常,消息不斷的重試,可能存在部分業(yè)務(wù)處理成功,部分業(yè)務(wù)處理失敗的情況,這時(shí)候就要解決服務(wù)接口的冪等性問題。
編程中一個(gè)冪等操作的特點(diǎn)是其任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。就是說,一次和多次請求某一個(gè)資源會(huì)產(chǎn)生同樣的作用影響。
在復(fù)雜的異步流程中,尤其注意失敗重試問題,通常支付流程中,每次接口被請求,對每一步數(shù)據(jù)更新的操作,都會(huì)前置一步狀態(tài)查詢的流程,用來判斷下一步的數(shù)據(jù)更新是否該執(zhí)行。
在系統(tǒng)服務(wù)接口請求中,任何明確的接口響應(yīng),例如失敗或成功,這樣業(yè)務(wù)流程都好處理,但是例如支付場景如果請求超時(shí),如何判斷服務(wù)的結(jié)果狀態(tài):客戶端請求超時(shí),本地服務(wù)超時(shí),請求支付超時(shí),支付回調(diào)超時(shí),客戶端響應(yīng)超時(shí)等,或者基于MQ的不斷重試機(jī)制,在部分業(yè)務(wù)異常狀態(tài)下,始終沒有返回成功,則消息會(huì)一直重試。
這就需要設(shè)計(jì)流程化的狀態(tài)管理,尤其在消息重試機(jī)制下,很少會(huì)再次對重試的業(yè)務(wù)接口使用重度的事務(wù)控制,有些業(yè)務(wù)被執(zhí)行完畢,只需要判斷一個(gè)狀態(tài),下次消息重試跳過即可,只需要把未處理的業(yè)務(wù)補(bǔ)償處理即可,在重試機(jī)制下,在部分業(yè)務(wù)沒有全部執(zhí)行成功之前,消息會(huì)一直重試,直到最終全部完成。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“apache rocketmq中柔性事務(wù)一致性的示例分析”這篇文章對大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。