微服務(wù)架構(gòu)之事件驅(qū)動(dòng)架構(gòu)

前言

為了解決傳統(tǒng)的單體應(yīng)用(Monolithic Application)在可擴(kuò)展性麦向、可靠性螃宙、適應(yīng)性惶傻、高部署成本等方面的問(wèn)題嚼摩,許多公司(比如Amazon灶体、eBay和NetFlix等)開(kāi)始使用微服務(wù)架構(gòu)(Microservice Architecture)構(gòu)建自己的應(yīng)用。

微服務(wù)架構(gòu)(維基百科):
微服務(wù) (Microservices) 是一種軟件架構(gòu)風(fēng)格 (Software Architecture Style)掐暮,它是以專注于單一責(zé)任與功能的小型功能區(qū)塊 (Small Building Blocks) 為基礎(chǔ)蝎抽,利用模組化的方式組合出復(fù)雜的大型應(yīng)用程序,各功能區(qū)塊使用與語(yǔ)言無(wú)關(guān) (Language-Independent/Language agnostic) 的 API 集相互通訊路克。

但是樟结,微服務(wù)架構(gòu)在帶來(lái)一系列好處的同時(shí),也帶來(lái)了若干挑戰(zhàn)精算。除了分布式系統(tǒng)固有的復(fù)雜性以外瓢宦,微服務(wù)架構(gòu)也深刻影響了應(yīng)用和數(shù)據(jù)庫(kù)之間的關(guān)系,與傳統(tǒng)多個(gè)服務(wù)共享一個(gè)數(shù)據(jù)庫(kù)的方式不同灰羽,微服務(wù)架構(gòu)每個(gè)服務(wù)都有自己的數(shù)據(jù)庫(kù)驮履。對(duì)于開(kāi)發(fā)者來(lái)說(shuō),這就為微服務(wù)中的數(shù)據(jù)管理提出了更高的要求廉嚼。

微服務(wù)架構(gòu)中的數(shù)據(jù)管理

在傳統(tǒng)的單體應(yīng)用中玫镐,通常使用單個(gè)的關(guān)系型數(shù)據(jù)庫(kù)。這類數(shù)據(jù)庫(kù)所提供的事務(wù)語(yǔ)義怠噪,具備ACID特性恐似。

ACID:

  • Atomicity(原子性):一個(gè)事務(wù)中的操作是原子的,其中任何一步失敗傍念,系統(tǒng)都能夠完全回到事務(wù)前的狀態(tài)
  • Consistency(一致性):數(shù)據(jù)庫(kù)的狀態(tài)始終保持一致
  • Isolation(隔離性):多個(gè)并發(fā)執(zhí)行的事務(wù)不會(huì)互相影響
  • Durability(持久性):事務(wù)處理結(jié)束后矫夷,對(duì)數(shù)據(jù)的修改是永久的

應(yīng)用得益于數(shù)據(jù)庫(kù)的這些特性,能夠用簡(jiǎn)單的方式對(duì)數(shù)據(jù)進(jìn)行修改與讀取憋槐,而無(wú)需花費(fèi)太多精力考慮數(shù)據(jù)一致性問(wèn)題双藕。

但是,在微服務(wù)架構(gòu)下阳仔,為了在微服務(wù)之間建立松耦合的關(guān)系蔓彩,通常每一個(gè)微服務(wù)都會(huì)擁有自己獨(dú)立的數(shù)據(jù)庫(kù),僅僅通過(guò)對(duì)外暴露的API來(lái)進(jìn)行數(shù)據(jù)交換驳概。這種情況下赤嚼,我們就要面臨分布式數(shù)據(jù)管理帶來(lái)的挑戰(zhàn)。也就是說(shuō)顺又,在實(shí)現(xiàn)業(yè)務(wù)邏輯時(shí)更卒,如何保證服務(wù)之間的數(shù)據(jù)一致性

實(shí)時(shí)一致性

我們首先考慮在系統(tǒng)中實(shí)現(xiàn)實(shí)時(shí)一致性的情況稚照。比如以一個(gè)銀行系統(tǒng)為例蹂空,客戶通常會(huì)有一個(gè)儲(chǔ)蓄賬戶和一個(gè)理財(cái)賬戶「┟龋現(xiàn)在,考慮客戶從自己的儲(chǔ)蓄賬戶向理財(cái)賬戶轉(zhuǎn)賬10000元的場(chǎng)景上枕。

假設(shè)現(xiàn)在有兩張表 deposit_account 和 finance_account咐熙,分別用于存儲(chǔ)儲(chǔ)蓄賬戶和理財(cái)賬戶的信息,用戶的ID是201辨萍。那么棋恼,在單一數(shù)據(jù)庫(kù)場(chǎng)景下,通過(guò)數(shù)據(jù)庫(kù)事務(wù)可以很容易完成這個(gè)操作:

Begin transaction
    update deposit_account_table set amount=amount-10000 where userId=201;
    update finance_account amount=amount+10000 where userId=1;
End transaction
commit;

這樣在單體應(yīng)用中锈玉,由于所有數(shù)據(jù)都是保存在同一個(gè)數(shù)據(jù)庫(kù)中爪飘,通過(guò)數(shù)據(jù)庫(kù)提供的ACID特性,就可以輕松實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)一致性拉背。

但是师崎,在微服務(wù)架構(gòu)中,可能的設(shè)計(jì)是存在兩個(gè)服務(wù):儲(chǔ)蓄服務(wù)(Deposit Service)和理財(cái)服務(wù)(Finance Service)椅棺,假設(shè)由儲(chǔ)蓄服務(wù)負(fù)責(zé)處理客戶的轉(zhuǎn)賬請(qǐng)求犁罩。而如下圖所示,這兩個(gè)服務(wù)都分別維護(hù)自己的數(shù)據(jù)两疚,因此儲(chǔ)蓄服務(wù)無(wú)法直接訪問(wèn)理財(cái)服務(wù)的數(shù)據(jù)昼汗,而只能通過(guò)API去修改客戶的余額。

微服務(wù)下的數(shù)據(jù)訪問(wèn)

此時(shí)鬼雀,為了滿足訂單服務(wù)與客戶服務(wù)之間的實(shí)時(shí)一致性要求顷窒,可以采用分布式事務(wù),比如基于兩階段提交協(xié)議(Two-phase commit, 2PC)的實(shí)現(xiàn)來(lái)做到這一點(diǎn)源哩。(關(guān)于2PC鞋吉,已經(jīng)有大量的研究成果和成功實(shí)踐經(jīng)驗(yàn),本文將不再做太多闡述励烦,具體可自行參見(jiàn)相關(guān)文獻(xiàn)和資料)

根據(jù)CAP定理谓着,我們追求實(shí)時(shí)一致性時(shí),通常需要犧牲掉部分可用性坛掠。比如以上場(chǎng)景中赊锚,當(dāng) Finance Service 由于軟硬件故障或網(wǎng)絡(luò)問(wèn)題而不可用的時(shí)候,系統(tǒng)將無(wú)法為用戶提供內(nèi)部轉(zhuǎn)賬服務(wù)屉栓。

此外舷蒲,作為典型的同步操作,2PC也存在著比較比較嚴(yán)重的性能問(wèn)題友多,并不適合高并發(fā)場(chǎng)景牲平。因此,在數(shù)據(jù)一致性上我們需要尋求其他的解決方案域滥。

最終一致性

如果我們考慮只保證系統(tǒng)的最終一致性纵柿,那么就可以避免使用2PC蜈抓,從而提高系統(tǒng)可用性和性能。

仍然以以上的用戶內(nèi)部賬戶之間的轉(zhuǎn)賬服務(wù)為例昂儒。當(dāng)用戶從儲(chǔ)蓄賬戶向理財(cái)賬戶轉(zhuǎn)賬時(shí)沟使,減少儲(chǔ)蓄賬戶的金額與增加理財(cái)賬戶的金額這兩個(gè)動(dòng)作,可以無(wú)需在一個(gè)事務(wù)里面完成渊跋,而是分成兩步:

  1. 儲(chǔ)蓄服務(wù)減去儲(chǔ)蓄賬戶中的金額腊嗡,并生成一個(gè)憑證(消息)發(fā)送給理財(cái)服務(wù);
  2. 理財(cái)服務(wù)收到憑證后刹枉,在理財(cái)賬戶中增加相應(yīng)的金額。

我們會(huì)發(fā)現(xiàn)以上過(guò)程在第1步完成之后屈呕,第2步完成之前微宝,儲(chǔ)蓄賬戶與理財(cái)賬戶之間實(shí)際上是存在短時(shí)間的數(shù)據(jù)不一致的。但是虎眨,只要最終第2步能夠完成蟋软,系統(tǒng)的數(shù)據(jù)就仍然能夠保持一致性,這就是我們所說(shuō)的最終一致性嗽桩。

在最終一致性這個(gè)前提下岳守,即使理財(cái)服務(wù)在某段時(shí)間內(nèi)不可用,系統(tǒng)仍然能夠能為用戶提供內(nèi)部轉(zhuǎn)賬服務(wù)碌冶,從而提高了系統(tǒng)的可用性湿痢。

而這樣一種基于最終一致性的解決方案,就是本文將要介紹的事件驅(qū)動(dòng)的架構(gòu)(Event-driven Architecture)扑庞。

事件驅(qū)動(dòng)的架構(gòu)

所謂事件驅(qū)動(dòng)的架構(gòu)譬重,也就是使用事件來(lái)實(shí)現(xiàn)跨多個(gè)服務(wù)的業(yè)務(wù)邏輯

在這一架構(gòu)里罐氨,當(dāng)有重要事件發(fā)生時(shí)臀规,比如更新業(yè)務(wù)數(shù)據(jù),某個(gè)微服務(wù)會(huì)發(fā)布事件栅隐,其它微服務(wù)則訂閱這些事件塔嬉;當(dāng)某一微服務(wù)接收到事件就可以更新自己的業(yè)務(wù)數(shù)據(jù),同時(shí)發(fā)布新的事件觸發(fā)下一步更新租悄。而事件的發(fā)布與訂閱谨究,則依賴于一個(gè)可靠的消息代理(Message Broker)。

以上文的場(chǎng)景為例泣棋,在事件驅(qū)動(dòng)的架構(gòu)中记盒,從儲(chǔ)蓄賬戶轉(zhuǎn)賬到理財(cái)賬戶的過(guò)程如下:

  1. 儲(chǔ)蓄服務(wù)將用戶的儲(chǔ)蓄賬戶中的金額減少10000,并發(fā)布“向理財(cái)賬戶轉(zhuǎn)賬”事件外傅;
  2. 理財(cái)服務(wù)獲取“轉(zhuǎn)賬到理財(cái)賬戶”事件纪吮, 更新理財(cái)賬戶俩檬,將理財(cái)賬戶的金額增加10000,并發(fā)布“理財(cái)賬戶轉(zhuǎn)入”事件碾盟;
  3. 儲(chǔ)蓄服務(wù)獲取“理財(cái)賬戶轉(zhuǎn)入”事件棚辽,結(jié)束本次轉(zhuǎn)賬交易。
事件驅(qū)動(dòng)的業(yè)務(wù)流程

在這里需要考慮的一個(gè)問(wèn)題冰肴,就是轉(zhuǎn)賬失敗處理屈藐。比如以上第2步如果因?yàn)椤袄碡?cái)賬戶被凍結(jié)無(wú)法轉(zhuǎn)入資金”之類的原因失敗了,理財(cái)服務(wù)就應(yīng)該發(fā)布“理財(cái)賬戶轉(zhuǎn)入失敗”事件熙尉,儲(chǔ)蓄服務(wù)獲取到該事件后联逻,需要對(duì)儲(chǔ)蓄賬戶進(jìn)行回滾,將減少的金額重新增加回去检痰。

以上的過(guò)程與傳統(tǒng)的數(shù)據(jù)管理基于ACID模型不一樣的是包归,它是基于BASE模型的。

BASE:

  • Basically Available(基本可用):系統(tǒng)在出現(xiàn)不可預(yù)知的故障的時(shí)候铅歼,允許損失部分可用性公壤,但不等于系統(tǒng)不可用
  • Soft State(軟狀態(tài)):允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認(rèn)為該中間狀態(tài)的存在不會(huì)影響系統(tǒng)的整體可用性
  • Eventually Consistent(最終一致性):系統(tǒng)保證最終數(shù)據(jù)能夠達(dá)到一致

事件發(fā)布

在事件驅(qū)動(dòng)的架構(gòu)中椎椰,跨服務(wù)完成業(yè)務(wù)邏輯的一個(gè)關(guān)鍵點(diǎn)是每個(gè)服務(wù)自動(dòng)更新數(shù)據(jù)庫(kù)和發(fā)布事件厦幅,也就是要以原子粒度更新數(shù)據(jù)庫(kù)和發(fā)布事件。例如慨飘,儲(chǔ)蓄服務(wù)必須在對(duì)儲(chǔ)蓄賬戶表進(jìn)行更新确憨,然后發(fā)布“向理財(cái)賬戶轉(zhuǎn)賬”事件,這兩個(gè)操作需要原子化實(shí)現(xiàn)瓤的。如果服務(wù)在更新數(shù)據(jù)庫(kù)之后缚态、發(fā)布事件之前崩潰,系統(tǒng)會(huì)變得不一致堤瘤。

保證數(shù)據(jù)更新與事件發(fā)布原子化的方法玫芦,有以下幾種:

  • 使用本地事務(wù)發(fā)布事件
  • 挖掘數(shù)據(jù)庫(kù)事務(wù)日志
  • 使用事件源

使用本地事務(wù)發(fā)布事件

一個(gè)實(shí)現(xiàn)原子化的方法是使用本地事務(wù)來(lái)更新業(yè)務(wù)實(shí)體和事件列表,由一個(gè)獨(dú)立進(jìn)程來(lái)發(fā)布事件本辐。具體來(lái)說(shuō)桥帆,就是在存儲(chǔ)業(yè)務(wù)實(shí)體狀態(tài)的數(shù)據(jù)庫(kù)中,使用一個(gè)事件表來(lái)充當(dāng)消息隊(duì)列慎皱。應(yīng)用啟動(dòng)一個(gè)(本地)數(shù)據(jù)庫(kù)事務(wù)老虫,更新業(yè)務(wù)實(shí)體的狀態(tài),在事件表中插入一個(gè)事件茫多,并提交該事務(wù)祈匙。一個(gè)獨(dú)立的消息發(fā)布線程或進(jìn)程查詢?cè)撌录恚瑢⑹录l(fā)布到消息代理,并標(biāo)注該事件為已發(fā)布夺欲。下圖展示了這一設(shè)計(jì)跪帝。

363875b0-f8b9-45a4-a28c-eeed128b1fa0.png

儲(chǔ)蓄服務(wù)更新儲(chǔ)蓄賬戶的余額,然后在事件表中插入“轉(zhuǎn)賬到理財(cái)賬戶”的事件些阅。事件發(fā)布線程或進(jìn)程在事件表中查詢未發(fā)布的事件并發(fā)布伞剑,然后更新事件表,將該事件標(biāo)記為已發(fā)布市埋。

這種方法的優(yōu)點(diǎn)是:

  • 使用本地事務(wù)黎泣,保證了數(shù)據(jù)被更新時(shí)事件一定能夠被發(fā)布
  • 實(shí)現(xiàn)簡(jiǎn)單,只需要系統(tǒng)具備本地事務(wù)的能力即可實(shí)現(xiàn)

這種方法的一個(gè)缺點(diǎn)是缤谎,數(shù)據(jù)更新操作與所要發(fā)布的事件之間的對(duì)應(yīng)關(guān)系抒倚,是由應(yīng)用的開(kāi)發(fā)者實(shí)現(xiàn)的,因此有很大可能出錯(cuò)坷澡。

挖掘數(shù)據(jù)庫(kù)事務(wù)日志

實(shí)現(xiàn)原子化的另一種方式是由線程或者進(jìn)程通過(guò)挖掘數(shù)據(jù)庫(kù)事務(wù)或提交日志來(lái)發(fā)布事件托呕。應(yīng)用更新數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)的事務(wù)日志會(huì)記錄這些變更洋访。事務(wù)日志挖掘線程或進(jìn)程讀取這些日志镣陕,并把事件發(fā)布到消息代理谴餐。

比如一個(gè)B2C的電商網(wǎng)站姻政,就可以通過(guò)挖掘訂單數(shù)據(jù)的更新日志,來(lái)進(jìn)行事件發(fā)布岂嗓。如下圖所示:

挖掘數(shù)據(jù)庫(kù)事務(wù)日志

這一方法的范例是開(kāi)源的 LinkedIn Databus 項(xiàng)目汁展。Databus 挖掘 Oracle 事務(wù)日志并發(fā)布與之對(duì)應(yīng)的事件,LinkedIn 則使用 Databus 維持各種來(lái)源的數(shù)據(jù)存儲(chǔ)與記錄系統(tǒng)一致厌殉。

另一個(gè)范例則是 AWS DynamoDB 采用的流機(jī)制食绿。AWS DynamoDB 是一個(gè)可管理的 NoSQL 數(shù)據(jù)庫(kù),其中每個(gè) DynamoDB 流包括 DynamoDB 表在過(guò)去 24 小時(shí)之內(nèi)的時(shí)序變化公罕,包括創(chuàng)建器紧、更新和刪除操作。應(yīng)用能夠讀取這些變更楼眷,將其作為事件發(fā)布铲汪。

這種方法的優(yōu)點(diǎn)是:

  • 要發(fā)布的事件直接來(lái)源于數(shù)據(jù)庫(kù)的事務(wù)日志,因此不會(huì)出錯(cuò)
  • 應(yīng)用無(wú)需關(guān)注事件的發(fā)布罐柳,簡(jiǎn)化了應(yīng)用開(kāi)發(fā)者的工作

但是這種方法也有一些缺點(diǎn):

  • 事務(wù)日志的格式與所使用的數(shù)據(jù)庫(kù)相關(guān)掌腰,因此事件挖掘 的實(shí)現(xiàn)會(huì)由于數(shù)據(jù)庫(kù)的種類或版本的變化而隨之需要修改
  • 由于是直接從數(shù)據(jù)庫(kù)的更新記錄生成事件,因此可能會(huì)無(wú)法逆向推斷出業(yè)務(wù)邏輯张吉,因此并不適合于所有場(chǎng)景(比如前文所述的轉(zhuǎn)賬場(chǎng)景)

使用事件源

事件源采用一種截然不同的齿梁、以事件為中心的方法來(lái)保存業(yè)務(wù)實(shí)體——不同于存儲(chǔ)實(shí)體的當(dāng)前狀態(tài),應(yīng)用存儲(chǔ)的是狀態(tài)改變的事件序列。每當(dāng)業(yè)務(wù)實(shí)體的狀態(tài)改變勺择,新事件就被附加到事件列表创南,并且應(yīng)用可以通過(guò)事件回放來(lái)重構(gòu)實(shí)體的當(dāng)前狀態(tài)。鑒于保存事件是一個(gè)單一的操作酵幕,因此本質(zhì)上也是原子化的扰藕。

要了解事件源如何運(yùn)行,可以以儲(chǔ)蓄服務(wù)為例芳撒。在傳統(tǒng)的方法中邓深,每次轉(zhuǎn)賬交易都會(huì)更新儲(chǔ)蓄賬戶表的記錄。而使用事件源的時(shí)候笔刹,儲(chǔ)蓄服務(wù)以狀態(tài)更改事件的方式存儲(chǔ)用戶的儲(chǔ)蓄賬戶芥备,每個(gè)事件都包含足夠的數(shù)據(jù)去重建儲(chǔ)蓄賬戶狀態(tài)。

事件表

事件長(zhǎng)期保存在事件倉(cāng)庫(kù)(Event Store)舌菜,使用 API 添加和檢索實(shí)體的事件萌壳。同時(shí),事件倉(cāng)庫(kù)起到類似上文提及的消息代理的作用日月,通過(guò) API 讓服務(wù)訂閱事件袱瓮,將所有事件傳達(dá)到所有感興趣的訂閱者。所以爱咬,事件倉(cāng)庫(kù)可以認(rèn)為是數(shù)據(jù)庫(kù)與消息代理的綜合體尺借,是事件源方法的支柱。

事件源方法

事件源方法有如下的優(yōu)點(diǎn):

  • 事件即狀態(tài)精拟,發(fā)布事件就是在更新?tīng)顟B(tài)燎斩,因此天然具有原子性,并且不會(huì)出錯(cuò)
  • 由于存儲(chǔ)的是事件蜂绎,而不是域?qū)ο笳け恚虼吮苊饬?a target="_blank" rel="nofollow">對(duì)象關(guān)系抗阻不匹配的問(wèn)題(object?relational impedance mismatch problem)
  • 由于存儲(chǔ)了所有的業(yè)務(wù)狀態(tài)更新事件,因此可以通過(guò)事件回放推斷出任一時(shí)間點(diǎn)的業(yè)務(wù)實(shí)體狀態(tài)

事件源方法也有以下這些缺點(diǎn):

  • 要實(shí)現(xiàn)一個(gè)可靠和高性能的事件倉(cāng)庫(kù)并不是一件容易的事情
  • 應(yīng)用代碼需要根據(jù)事件倉(cāng)庫(kù)的 API 進(jìn)行重寫(xiě)
  • 事件倉(cāng)庫(kù)只直接支持通過(guò)主鍵查詢業(yè)務(wù)實(shí)體师枣,因此對(duì)于復(fù)雜視圖的查詢比較困難(可以通過(guò)CQRS方法解決怪瓶,具體參見(jiàn)下文)

命令查詢分離(CQRS)

在事件源方法中,不再直接存儲(chǔ)任何業(yè)務(wù)實(shí)體的狀態(tài)践美,而是代之以狀態(tài)變更事件洗贰。在進(jìn)行復(fù)雜視圖的查詢時(shí),如果還按照與命令操作同樣的方式拨脉,將會(huì)遇到一些困難哆姻。比如要發(fā)起如下的一個(gè)同時(shí)涉及儲(chǔ)蓄賬戶和理財(cái)賬戶的查詢操作:

SELECT *
FROM DEPOSIT_ACCOUNT deposit, FINANCE_ACCOUNT finance
WHERE
    deposit.user_id = finance.user_id
    AND finance.state = 'active'
    AND deposit.amount > 100000
    AND finance.amount > 5000

在非事件源的方式下,可以很容易的從儲(chǔ)蓄賬戶表和理財(cái)賬戶表查詢到相應(yīng)數(shù)據(jù)玫膀。但是在事件源方式下矛缨,事件倉(cāng)庫(kù)中存儲(chǔ)的是一系列事件,并且只能通過(guò)主鍵(比如 deposit_account.id 或 finance_account.id)去查詢相應(yīng)的業(yè)務(wù)實(shí)體,此時(shí)要處理類似 deposit.amount > 100000 這樣的查詢條件以及條件組合時(shí)箕昭,是非常復(fù)雜和低效的灵妨。

為了解決這一問(wèn)題,可以采用CQRS方法落竹,將命令與查詢分離泌霍。命令操作仍然通過(guò)各服務(wù)的 API 以更新事件列表的方式進(jìn)行,而查詢操作則通過(guò)一個(gè)統(tǒng)一的視圖查詢服務(wù)(View Query Service)完成述召。

CQRS方法

根據(jù)存儲(chǔ)在事件倉(cāng)庫(kù)中的事件集合朱转,可以計(jì)算得到每個(gè)業(yè)務(wù)實(shí)體的狀態(tài),這些狀態(tài)以物化視圖(Materialized View)的方式存儲(chǔ)在一個(gè)數(shù)據(jù)庫(kù)中积暖。當(dāng)有新的事件產(chǎn)生時(shí)藤为,也同樣會(huì)自動(dòng)更新視圖。這樣夺刑,視圖查詢服務(wù)就可以像查詢普通的數(shù)據(jù)庫(kù)數(shù)據(jù)一樣實(shí)現(xiàn)各種查詢場(chǎng)景缅疟。具體的設(shè)計(jì)可參考下圖所示:

CQRS服務(wù)架構(gòu)

結(jié)論

在微服務(wù)架構(gòu)中,每個(gè)微服務(wù)都有其私有數(shù)據(jù)存儲(chǔ)遍愿,不同的微服務(wù)可能使用不同的數(shù)據(jù)庫(kù)存淫。這種架構(gòu)帶來(lái)便利的同時(shí),也給分布式數(shù)據(jù)管理帶來(lái)挑戰(zhàn)沼填,其中最大的挑戰(zhàn)就是在實(shí)現(xiàn)跨服務(wù)的業(yè)務(wù)邏輯時(shí)桅咆,如何保持服務(wù)之間的數(shù)據(jù)一致性

對(duì)于許多應(yīng)用倾哺,解決方案就是使用事件驅(qū)動(dòng)的架構(gòu)轧邪。事件驅(qū)動(dòng)的架構(gòu)帶來(lái)的挑戰(zhàn)是如何原子化地更新?tīng)顟B(tài)和發(fā)布事件刽脖。有幾個(gè)方法可以做到這一點(diǎn)羞海,包括把數(shù)據(jù)庫(kù)用作消息隊(duì)列、事務(wù)日志挖掘和事件源曲管。

參考文獻(xiàn)

  1. Event-Driven Data Management for Microservices
  2. Base: An Acid Alternative
  3. Pattern: Event-driven architecture
  4. 如何用消息系統(tǒng)避免分布式事務(wù)却邓?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市院水,隨后出現(xiàn)的幾起案子腊徙,更是在濱河造成了極大的恐慌,老刑警劉巖檬某,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撬腾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡恢恼,警方通過(guò)查閱死者的電腦和手機(jī)民傻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人漓踢,你說(shuō)我怎么就攤上這事牵署。” “怎么了喧半?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵奴迅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我挺据,道長(zhǎng)取具,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任扁耐,我火速辦了婚禮者填,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘做葵。我一直安慰自己占哟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布酿矢。 她就那樣靜靜地躺著榨乎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瘫筐。 梳的紋絲不亂的頭發(fā)上蜜暑,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音策肝,去河邊找鬼肛捍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛之众,可吹牛的內(nèi)容都是我干的拙毫。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼棺禾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缀蹄!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起膘婶,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缺前,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后悬襟,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體衅码,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年脊岳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逝段。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筛璧。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惹恃,靈堂內(nèi)的尸體忽然破棺而出夭谤,到底是詐尸還是另有隱情,我是刑警寧澤巫糙,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布朗儒,位于F島的核電站,受9級(jí)特大地震影響参淹,放射性物質(zhì)發(fā)生泄漏醉锄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一浙值、第九天 我趴在偏房一處隱蔽的房頂上張望恳不。 院中可真熱鬧,春花似錦开呐、人聲如沸烟勋。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)卵惦。三九已至,卻和暖如春瓦戚,著一層夾襖步出監(jiān)牢的瞬間沮尿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工较解, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畜疾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓印衔,卻偏偏與公主長(zhǎng)得像啡捶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子当编,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

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