分布式事務(wù):Saga模式

1 Saga相關(guān)概念

1987年普林斯頓大學(xué)的Hector Garcia-Molina和Kenneth Salem發(fā)表了一篇Paper Sagas,講述的是如何處理long lived transaction(長(zhǎng)活事務(wù))声搁。Saga是一個(gè)長(zhǎng)活事務(wù)可被分解成可以交錯(cuò)運(yùn)行的子事務(wù)集合泥从。其中每個(gè)子事務(wù)都是一個(gè)保持?jǐn)?shù)據(jù)庫(kù)一致性的真實(shí)事務(wù)。
論文地址:sagas

1.1 Saga的組成

  • 每個(gè)Saga由一系列sub-transaction Ti 組成
  • 每個(gè)Ti 都有對(duì)應(yīng)的補(bǔ)償動(dòng)作Ci,補(bǔ)償動(dòng)作用于撤銷Ti造成的結(jié)果

可以看到贩汉,和TCC相比盖桥,Saga沒有“預(yù)留”動(dòng)作,它的Ti就是直接提交到庫(kù)镊讼。

Saga的執(zhí)行順序有兩種:

  • T1, T2, T3, ..., Tn
  • T1, T2, ..., Tj, Cj,..., C2, C1宽涌,其中0 < j < n

Saga定義了兩種恢復(fù)策略:

  • backward recovery,向后恢復(fù)蝶棋,補(bǔ)償所有已完成的事務(wù)卸亮,如果任一子事務(wù)失敗。即上面提到的第二種執(zhí)行順序玩裙,其中j是發(fā)生錯(cuò)誤的sub-transaction兼贸,這種做法的效果是撤銷掉之前所有成功的sub-transation,使得整個(gè)Saga的執(zhí)行結(jié)果撤銷吃溅。
  • forward recovery溶诞,向前恢復(fù),重試失敗的事務(wù)决侈,假設(shè)每個(gè)子事務(wù)最終都會(huì)成功螺垢。適用于必須要成功的場(chǎng)景,執(zhí)行順序是類似于這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中j是發(fā)生錯(cuò)誤的sub-transaction甩苛。該情況下不需要Ci蹂楣。

顯然,向前恢復(fù)沒有必要提供補(bǔ)償事務(wù)讯蒲,如果你的業(yè)務(wù)中痊土,子事務(wù)(最終)總會(huì)成功,或補(bǔ)償事務(wù)難以定義或不可能墨林,向前恢復(fù)更符合你的需求赁酝。

理論上補(bǔ)償事務(wù)永不失敗,然而旭等,在分布式世界中酌呆,服務(wù)器可能會(huì)宕機(jī),網(wǎng)絡(luò)可能會(huì)失敗搔耕,甚至數(shù)據(jù)中心也可能會(huì)停電隙袁。在這種情況下我們能做些什么? 最后的手段是提供回退措施弃榨,比如人工干預(yù)菩收。

1.2 Saga的使用條件

Saga看起來很有希望滿足我們的需求。所有長(zhǎng)活事務(wù)都可以這樣做嗎鲸睛?這里有一些限制:

  1. Saga只允許兩個(gè)層次的嵌套娜饵,頂級(jí)的Saga和簡(jiǎn)單子事務(wù)
  2. 在外層,全原子性不能得到滿足官辈。也就是說箱舞,sagas可能會(huì)看到其他sagas的部分結(jié)果
  3. 每個(gè)子事務(wù)應(yīng)該是獨(dú)立的原子行為
  4. 在我們的業(yè)務(wù)場(chǎng)景下,各個(gè)業(yè)務(wù)環(huán)境(如:航班預(yù)訂拳亿、租車晴股、酒店預(yù)訂和付款)是自然獨(dú)立的行為,而且每個(gè)事務(wù)都可以用對(duì)應(yīng)服務(wù)的數(shù)據(jù)庫(kù)保證原子操作风瘦。

補(bǔ)償也有需考慮的事項(xiàng):

  • 補(bǔ)償事務(wù)從語義角度撤消了事務(wù)Ti的行為队魏,但未必能將數(shù)據(jù)庫(kù)返回到執(zhí)行Ti時(shí)的狀態(tài)公般。(例如万搔,如果事務(wù)觸發(fā)導(dǎo)彈發(fā)射, 則可能無法撤消此操作)

但這對(duì)我們的業(yè)務(wù)來說不是問題官帘。其實(shí)難以撤消的行為也有可能被補(bǔ)償瞬雹。例如,發(fā)送電郵的事務(wù)可以通過發(fā)送解釋問題的另一封電郵來補(bǔ)償刽虹。

對(duì)于ACID的保證:

Saga對(duì)于ACID的保證和TCC一樣:

  • 原子性(Atomicity):正常情況下保證酗捌。
  • 一致性(Consistency),在某個(gè)時(shí)間點(diǎn),會(huì)出現(xiàn)A庫(kù)和B庫(kù)的數(shù)據(jù)違反一致性要求的情況胖缤,但是最終是一致的尚镰。
  • 隔離性(Isolation),在某個(gè)時(shí)間點(diǎn)哪廓,A事務(wù)能夠讀到B事務(wù)部分提交的結(jié)果狗唉。
  • 持久性(Durability),和本地事務(wù)一樣涡真,只要commit則數(shù)據(jù)被持久分俯。

Saga不提供ACID保證,因?yàn)樵有院透綦x性不能得到滿足哆料。原論文描述如下:

full atomicity is not provided. That is, sagas may view the partial results of other sagas

通過saga log缸剪,saga可以保證一致性和持久性。

和TCC對(duì)比

Saga相比TCC的缺點(diǎn)是缺少預(yù)留動(dòng)作东亦,導(dǎo)致補(bǔ)償動(dòng)作的實(shí)現(xiàn)比較麻煩:Ti就是commit杏节,比如一個(gè)業(yè)務(wù)是發(fā)送郵件,在TCC模式下典阵,先保存草稿(Try)再發(fā)送(Confirm)拢锹,撤銷的話直接刪除草稿(Cancel)就行了。而Saga則就直接發(fā)送郵件了(Ti)萄喳,如果要撤銷則得再發(fā)送一份郵件說明撤銷(Ci)卒稳,實(shí)現(xiàn)起來有一些麻煩。

如果把上面的發(fā)郵件的例子換成:A服務(wù)在完成Ti后立即發(fā)送Event到ESB(企業(yè)服務(wù)總線他巨,可以認(rèn)為是一個(gè)消息中間件)充坑,下游服務(wù)監(jiān)聽到這個(gè)Event做自己的一些工作然后再發(fā)送Event到ESB,如果A服務(wù)執(zhí)行補(bǔ)償動(dòng)作Ci染突,那么整個(gè)補(bǔ)償動(dòng)作的層級(jí)就很深捻爷。

不過沒有預(yù)留動(dòng)作也可以認(rèn)為是優(yōu)點(diǎn):

  • 有些業(yè)務(wù)很簡(jiǎn)單,套用TCC需要修改原來的業(yè)務(wù)邏輯份企,而Saga只需要添加一個(gè)補(bǔ)償動(dòng)作就行了也榄。
  • TCC最少通信次數(shù)為2n,而Saga為n(n=sub-transaction的數(shù)量)司志。
  • 有些第三方服務(wù)沒有Try接口甜紫,TCC模式實(shí)現(xiàn)起來就比較tricky了,而Saga則很簡(jiǎn)單骂远。
  • 沒有預(yù)留動(dòng)作就意味著不必?fù)?dān)心資源釋放的問題囚霸,異常處理起來也更簡(jiǎn)單(請(qǐng)對(duì)比Saga的恢復(fù)策略和TCC的異常處理)。

2 Saga相關(guān)實(shí)現(xiàn)

Saga Log

Saga保證所有的子事務(wù)都得以完成或補(bǔ)償激才,但Saga系統(tǒng)本身也可能會(huì)崩潰拓型。Saga崩潰時(shí)可能處于以下幾個(gè)狀態(tài):

  • Saga收到事務(wù)請(qǐng)求额嘿,但尚未開始。因子事務(wù)對(duì)應(yīng)的微服務(wù)狀態(tài)未被Saga修改劣挫,我們什么也不需要做册养。
  • 一些子事務(wù)已經(jīng)完成。重啟后压固,Saga必須接著上次完成的事務(wù)恢復(fù)捕儒。
  • 子事務(wù)已開始,但尚未完成邓夕。由于遠(yuǎn)程服務(wù)可能已完成事務(wù)刘莹,也可能事務(wù)失敗,甚至服務(wù)請(qǐng)求超時(shí)焚刚,saga只能重新發(fā)起之前未確認(rèn)完成的子事務(wù)点弯。這意味著子事務(wù)必須冪等。
  • 子事務(wù)失敗矿咕,其補(bǔ)償事務(wù)尚未開始抢肛。Saga必須在重啟后執(zhí)行對(duì)應(yīng)補(bǔ)償事務(wù)。
  • 補(bǔ)償事務(wù)已開始但尚未完成碳柱。解決方案與上一個(gè)相同捡絮。這意味著補(bǔ)償事務(wù)也必須是冪等的。
  • 所有子事務(wù)或補(bǔ)償事務(wù)均已完成莲镣,與第一種情況相同福稳。

為了恢復(fù)到上述狀態(tài),我們必須追蹤子事務(wù)及補(bǔ)償事務(wù)的每一步瑞侮。我們決定通過事件的方式達(dá)到以上要求的圆,并將以下事件保存在名為saga log的持久存儲(chǔ)中:

  • Saga started event 保存整個(gè)saga請(qǐng)求,其中包括多個(gè)事務(wù)/補(bǔ)償請(qǐng)求
  • Transaction started event 保存對(duì)應(yīng)事務(wù)請(qǐng)求
  • Transaction ended event 保存對(duì)應(yīng)事務(wù)請(qǐng)求及其回復(fù)
  • Transaction aborted event 保存對(duì)應(yīng)事務(wù)請(qǐng)求和失敗的原因
  • Transaction compensated event 保存對(duì)應(yīng)補(bǔ)償請(qǐng)求及其回復(fù)
  • Saga ended event 標(biāo)志著saga事務(wù)請(qǐng)求的結(jié)束半火,不需要保存任何內(nèi)容
66ae7b320e502c13f4a21a08baa61ead

通過將這些事件持久化在saga log中越妈,我們可以將saga恢復(fù)到上述任何狀態(tài)。

由于Saga只需要做事件的持久化钮糖,而事件內(nèi)容以JSON的形式存儲(chǔ)梅掠,Saga log的實(shí)現(xiàn)非常靈活,數(shù)據(jù)庫(kù)(SQL或NoSQL)店归,持久消息隊(duì)列阎抒,甚至普通文件可以用作事件存儲(chǔ), 當(dāng)然有些能更快得幫saga恢復(fù)狀態(tài)娱节。

注意事項(xiàng)

對(duì)于服務(wù)來說挠蛉,實(shí)現(xiàn)Saga有以下這些要求:

  1. Ti和Ci是冪等的祭示。
  2. Ci必須是能夠成功的肄满,如果無法成功則需要人工介入谴古。
  3. Ti - Ci和Ci - Ti的執(zhí)行結(jié)果必須是一樣的:sub-transaction被撤銷了。

第一點(diǎn)要求Ti和Ci是冪等的稠歉,舉個(gè)例子掰担,假設(shè)在執(zhí)行Ti的時(shí)候超時(shí)了,此時(shí)我們是不知道執(zhí)行結(jié)果的怒炸,如果采用forward recovery策略就會(huì)再次發(fā)送Ti带饱,那么就有可能出現(xiàn)Ti被執(zhí)行了兩次,所以要求Ti冪等阅羹。如果采用backward recovery策略就會(huì)發(fā)送Ci勺疼,而如果Ci也超時(shí)了,就會(huì)嘗試再次發(fā)送Ci捏鱼,那么就有可能出現(xiàn)Ci被執(zhí)行兩次执庐,所以要求Ci冪等。

第二點(diǎn)要求Ci必須能夠成功导梆,這個(gè)很好理解轨淌,因?yàn)椋绻鸆i不能執(zhí)行成功就意味著整個(gè)Saga無法完全撤銷看尼,這個(gè)是不允許的递鹉。但總會(huì)出現(xiàn)一些特殊情況比如Ci的代碼有bug、服務(wù)長(zhǎng)時(shí)間崩潰等藏斩,這個(gè)時(shí)候就需要人工介入了躏结。

第三點(diǎn)乍看起來比較奇怪,舉例說明狰域,還是考慮Ti執(zhí)行超時(shí)的場(chǎng)景窜觉,我們采用了backward recovery,發(fā)送一個(gè)Ci北专,那么就會(huì)有三種情況:

  1. Ti的請(qǐng)求丟失了禀挫,服務(wù)之前沒有、之后也不會(huì)執(zhí)行Ti
  2. Ti在Ci之前執(zhí)行
  3. Ci在Ti之前執(zhí)行

對(duì)于第1種情況拓颓,容易處理语婴。對(duì)于第2、3種情況驶睦,則要求Ti和Ci是可交換的(commutative)砰左,并且其最終結(jié)果都是sub-transaction被撤銷。

3 Saga協(xié)調(diào)

協(xié)調(diào)saga:saga的實(shí)現(xiàn)包含協(xié)調(diào)saga步驟的邏輯场航。當(dāng)系統(tǒng)命令啟動(dòng)saga時(shí)缠导,協(xié)調(diào)邏輯必須選擇并告知第一個(gè)saga參與者執(zhí)行本地事務(wù)。一旦該事務(wù)完成溉痢,saga的排序協(xié)調(diào)選擇并調(diào)用下一個(gè)saga參與者僻造。這個(gè)過程一直持續(xù)到saga執(zhí)行了所有步驟憋他。如果任何本地事務(wù)失敗,則saga必須以相反的順序執(zhí)行補(bǔ)償事務(wù)髓削。構(gòu)建一個(gè)saga的協(xié)調(diào)邏輯有幾種不同的方法:

  • 編排(Choreography):在saga參與者中分配決策和排序竹挡。他們主要通過交換事件進(jìn)行溝通。
  • 控制(Orchestration):在saga控制類中集中saga的協(xié)調(diào)邏輯立膛。一個(gè)saga控制者向saga參與者發(fā)送命令消息揪罕,告訴他們要執(zhí)行哪些操作。

3.1 編排(Choreography)

基于編排的saga:實(shí)現(xiàn)sagas的一種方法是使用編排宝泵。當(dāng)使用編排時(shí)好啰,沒有中央?yún)f(xié)調(diào)員告訴saga參與者該做什么。相反儿奶,sagas參與者訂閱彼此的事件并做出相應(yīng)的響應(yīng)坎怪。

Screen Shot 2018-11-27 at 23.24.17

通過這個(gè)sagas的路徑如下:

  1. Order Service在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個(gè)Order并發(fā)布OrderCreated事件。
  2. Consumer Service消費(fèi)OrderCreated事件廓握,驗(yàn)證消費(fèi)者是否可以下訂單搅窿,并發(fā)布ConsumerVerified事件。
  3. Kitchen Service消費(fèi)OrderCreated事件隙券,驗(yàn)證訂單男应,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單,并發(fā)布TicketCreated事件娱仔。
  4. Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個(gè)處于PENDING狀態(tài)的Credit CardAuthorization沐飘。
  5. Accounting Service消費(fèi)TicketCreated和ConsumerVerified事件,收取消費(fèi)者的信用卡牲迫,并發(fā)布信用卡授權(quán)活動(dòng)耐朴。
  6. Kitchen Service使用CreditCardAuthorized事件并更改AWAITING_ACCEPTANCE票的狀態(tài)。
  7. Order Service收到CreditCardAuthorized事件盹憎,更改訂單狀態(tài)到APPROVED筛峭,并發(fā)布OrderApproved事件。

創(chuàng)建訂單saga還必須處理saga參與者拒絕訂單并發(fā)布某種失敗事件的場(chǎng)景陪每。例如影晓,消費(fèi)者信用卡的授權(quán)可能會(huì)失敗。saga必須執(zhí)行補(bǔ)償交易以撤消已經(jīng)完成的事情檩禾。圖中顯示了AccountingService無法授權(quán)消費(fèi)者信用卡時(shí)的事件流挂签。

Screen Shot 2018-11-27 at 23.54.12

事件順序如下:

  1. Order服務(wù)在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個(gè)Order并發(fā)布OrderCreated事件。
  2. Consumer服務(wù)消費(fèi)OrderCreated事件盼产,驗(yàn)證消費(fèi)者是否可以下訂單饵婆,并發(fā)布ConsumerVerified事件。
  3. Kitchen服務(wù)消費(fèi)OrderCreated事件戏售,驗(yàn)證訂單侨核,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單草穆,并發(fā)布TicketCreated事件。
  4. Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個(gè)處于PENDING狀態(tài)的Credit CardAuthorization芹关。
  5. Accounting服務(wù)消費(fèi)TicketCreated和ConsumerVerified事件续挟,向消費(fèi)者的信用卡收費(fèi)紧卒,并發(fā)布信用卡授權(quán)失敗事件侥衬。
  6. Kitchen服務(wù)使用信用卡授權(quán)失敗事件并將故障單的狀態(tài)更改為REJECTED。
  7. 訂單服務(wù)消費(fèi)信用卡授權(quán)失敗事件跑芳,并將訂單狀態(tài)更改為已拒絕轴总。

可靠的基于事件的通信

在實(shí)施基于編排的saga時(shí),您必須考慮一些與服務(wù)間通信相關(guān)的問題博个。第一個(gè)問題是確保saga參與者更新其數(shù)據(jù)庫(kù)并將事件作為數(shù)據(jù)庫(kù)事務(wù)的一部分發(fā)布怀樟。
您需要考慮的第二個(gè)問題是確保saga參與者必須能夠?qū)⑹盏降拿總€(gè)事件映射到自己的數(shù)據(jù)。

編組的saga的好處和缺點(diǎn)

基于編舞的saga有幾個(gè)好處

  • 簡(jiǎn)單:服務(wù)在創(chuàng)建盆佣,更新或刪除業(yè)務(wù)時(shí)發(fā)布事件對(duì)象
  • 松耦合:參與者訂閱事件并且彼此之間沒有直接的了解往堡。

并且有一些缺點(diǎn)

  • 更難理解:與業(yè)務(wù)流程不同,代碼中沒有一個(gè)地方可以定義saga共耍。相反虑灰,編排在服務(wù)中分配saga的實(shí)現(xiàn)。因此痹兜,開發(fā)人員有時(shí)很難理解給定的saga是如何工作的穆咐。
  • 服務(wù)之間的循環(huán)依賴關(guān)系:saga參與者訂閱彼此的事件,這通常會(huì)創(chuàng)建循環(huán)依賴關(guān)系字旭。例如对湃,如果仔細(xì)檢查圖示,您將看到存在循環(huán)依賴關(guān)系遗淳,例如訂單服務(wù)拍柒、會(huì)計(jì)服務(wù)、訂單服務(wù)屈暗。雖然這不一定是個(gè)問題斤儿,但循環(huán)依賴性被認(rèn)為是設(shè)計(jì)問題。
  • 緊密耦合的風(fēng)險(xiǎn):每個(gè)saga參與者都需要訂閱所有影響他們的事件恐锦。例如往果,會(huì)計(jì)服務(wù)必須訂閱導(dǎo)致消費(fèi)者信用卡被收費(fèi)或退款的所有事件。因此一铅,存在一種風(fēng)險(xiǎn)陕贮,即需要與Order Service實(shí)施的訂單生命周期保持同步更新。

3.2 控制(Orchestration)

控制是實(shí)現(xiàn)sagas的另一種方式潘飘。使用業(yè)務(wù)流程時(shí)肮之,您可以定義一個(gè)控制類掉缺,其唯一的職責(zé)是告訴saga參與者該做什么。 saga控制使用命令/異步回復(fù)樣式交互與參與者進(jìn)行通信戈擒。

Screen Shot 2018-11-28 at 00.08.51
  1. Order Service首先創(chuàng)建一個(gè)Order和一個(gè)創(chuàng)建訂單控制器眶明。之后,路徑的流程如下:
  2. saga orchestrator向Consumer Service發(fā)送Verify Consumer命令筐高。
  3. Consumer Service回復(fù)Consumer Verified消息搜囱。
  4. saga orchestrator向Kitchen Service發(fā)送Create Ticket命令。
  5. Kitchen Service回復(fù)Ticket Created消息柑土。
  6. saga協(xié)調(diào)器向Accounting Service發(fā)送授權(quán)卡消息蜀肘。
  7. Accounting服務(wù)部門使用卡片授權(quán)消息回復(fù)。
  8. saga orchestrator向Kitchen Service發(fā)送Approve Ticket命令稽屏。
  9. saga orchestrator向訂單服務(wù)發(fā)送批準(zhǔn)訂單命令扮宠。

使用狀態(tài)機(jī)建模SAGA ORCHESTRATORS

建模saga orchestrator的好方法是作為狀態(tài)機(jī)。狀態(tài)機(jī)由一組狀態(tài)和一組由事件觸發(fā)的狀態(tài)之間的轉(zhuǎn)換組成狐榔。每個(gè)transition都可以有一個(gè)action坛增,對(duì)于一個(gè)saga來說是一個(gè)saga參與者的調(diào)用。狀態(tài)之間的轉(zhuǎn)換由saga參與者執(zhí)行的本地事務(wù)的完成觸發(fā)薄腻。當(dāng)前狀態(tài)和本地事務(wù)的特定結(jié)果決定了狀態(tài)轉(zhuǎn)換以及執(zhí)行的操作(如果有的話)收捣。對(duì)狀態(tài)機(jī)也有有效的測(cè)試策略。因此被廓,使用狀態(tài)機(jī)模型可以更輕松地設(shè)計(jì)坏晦、實(shí)施和測(cè)試。

Screen Shot 2018-11-28 at 00.12.58

圖顯示了Create Order Saga的狀態(tài)機(jī)模型嫁乘。此狀態(tài)機(jī)由多個(gè)狀態(tài)組成昆婿,包括以下內(nèi)容:

  • Verifying Consumer:初始狀態(tài)。當(dāng)處于此狀態(tài)時(shí)蜓斧,該saga正在等待消費(fèi)者服務(wù)部門驗(yàn)證消費(fèi)者是否可以下訂單仓蛆。
  • Creating Ticket:該saga正在等待對(duì)創(chuàng)建票證命令的回復(fù)。
  • Authorizing Card:等待Accounting服務(wù)授權(quán)消費(fèi)者的信用卡挎春。
  • OrderApproved:表示saga成功完成的最終狀態(tài)看疙。
  • Order Rejected:最終狀態(tài)表明該訂單被其中一方參與者們拒絕。

SAGA ORCHESTRATION和TRANSACTIONAL MESSAGING

基于業(yè)務(wù)流程的saga的每個(gè)步驟都包括更新數(shù)據(jù)庫(kù)和發(fā)布消息的服務(wù)直奋。例如能庆,Order Service持久保存Order和Create Order Saga orchestrator,并向第一個(gè)saga參與者發(fā)送消息脚线。一個(gè)saga參與者搁胆,例如Kitchen Service,通過更新其數(shù)據(jù)庫(kù)并發(fā)送回復(fù)消息來處理命令消息。 Order Service通過更新saga協(xié)調(diào)器的狀態(tài)并向下一個(gè)saga參與者發(fā)送命令消息來處理參與者的回復(fù)消息渠旁。服務(wù)必須使用事務(wù)性消息傳遞攀例,以便自動(dòng)更新數(shù)據(jù)庫(kù)并發(fā)布消息。

讓我們來看看使用saga編排的好處和缺點(diǎn)顾腊。

基于ORCHESTRATION的SAGAS的好處和缺點(diǎn)

基于編排的saga有幾個(gè)好處:

  1. 更簡(jiǎn)單的依賴關(guān)系:編排的一個(gè)好處是它不會(huì)引入循環(huán)依賴關(guān)系粤铭。 saga orchestrator調(diào)用saga參與者,但參與者不會(huì)調(diào)用orchestrator杂靶。因此梆惯,協(xié)調(diào)器依賴于參與者,但反之亦然伪煤,因此沒有循環(huán)依賴性加袋。
  2. 較少的耦合:每個(gè)服務(wù)都實(shí)現(xiàn)了由orchestrator調(diào)用的API凛辣,因此它不需要知道saga參與者發(fā)布的事件抱既。
  3. 改善關(guān)注點(diǎn)分離并簡(jiǎn)化業(yè)務(wù)邏輯:saga協(xié)調(diào)邏輯本地化在saga協(xié)調(diào)器中。域?qū)ο蟾?jiǎn)單扁誓,并且不了解它們參與的saga防泵。例如,當(dāng)使用編排時(shí)蝗敢,Order類不知道任何saga捷泞,因此它具有更簡(jiǎn)單的狀態(tài)機(jī)模型。在執(zhí)行創(chuàng)建訂單saga期間寿谴,它直接從APPROVAL_PENDING狀態(tài)轉(zhuǎn)換到APPROVED狀態(tài)锁右。 Order類沒有與saga的步驟相對(duì)應(yīng)的任何中間狀態(tài)。因此讶泰,業(yè)務(wù)更加簡(jiǎn)單咏瑟。

業(yè)務(wù)流程也有一個(gè)缺點(diǎn)

  • 在協(xié)調(diào)器中集中過多業(yè)務(wù)邏輯的風(fēng)險(xiǎn)。這導(dǎo)致了一種設(shè)計(jì)痪署,其中智能協(xié)調(diào)器告訴啞巴服務(wù)要做什么操作码泞。幸運(yùn)的是,您可以通過設(shè)計(jì)獨(dú)立負(fù)責(zé)排序的協(xié)調(diào)器來避免此問題狼犯,并且不包含任何其他業(yè)務(wù)邏輯余寥。

除了最簡(jiǎn)單的saga,我建議使用編排悯森。為您的saga實(shí)施協(xié)調(diào)邏輯只是您需要解決的設(shè)計(jì)問題之一宋舷。

4 參考示例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瓢姻,隨后出現(xiàn)的幾起案子祝蝠,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件续膳,死亡現(xiàn)場(chǎng)離奇詭異改艇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坟岔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門谒兄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人社付,你說我怎么就攤上這事承疲。” “怎么了鸥咖?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵燕鸽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我啼辣,道長(zhǎng)啊研,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任鸥拧,我火速辦了婚禮党远,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘富弦。我一直安慰自己沟娱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布腕柜。 她就那樣靜靜地躺著济似,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盏缤。 梳的紋絲不亂的頭發(fā)上砰蠢,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音蛾找,去河邊找鬼娩脾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛打毛,可吹牛的內(nèi)容都是我干的柿赊。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼幻枉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碰声!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起熬甫,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤胰挑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瞻颂,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡豺谈,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了贡这。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茬末。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盖矫,靈堂內(nèi)的尸體忽然破棺而出丽惭,到底是詐尸還是另有隱情,我是刑警寧澤辈双,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布责掏,位于F島的核電站,受9級(jí)特大地震影響湃望,放射性物質(zhì)發(fā)生泄漏换衬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一喜爷、第九天 我趴在偏房一處隱蔽的房頂上張望冗疮。 院中可真熱鬧萄唇,春花似錦檩帐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至四敞,卻和暖如春泛源,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背忿危。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工达箍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铺厨。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓缎玫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親解滓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赃磨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容