-
1 # 冬至152131624
-
2 # 營養快報
謝謝邀請:分散式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分散式系統的不同節點之上。簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的伺服器上,且屬於不同的應用,分散式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分散式事務就是為了保證不同資料庫的資料一致性。
分散式事務,本質上是對多個數據庫的事務進行統一控制,按照控制力度可以分為:不控制、部分控制和完全控制。不控制就是不引入分散式事務,部分控制就是各種變種的兩階段提交,包括上面提到的訊息事務+最終一致性、TCC模式,而完全控制就是完全實現兩階段提交。部分控制的好處是併發量和效能很好,缺點是資料一致性減弱了,完全控制則是犧牲了效能,保障了一致性,具體用哪種方式,最終還是取決於業務場景。
-
3 # 半夏時光在路上
事務的管理不應該屬於Dubbo框架, Dubbo只需實現可被事務管理即可, 像JDBC和JMS都是可被事務管理的分散式資源, Dubbo只要實現相同的可被事務管理的行為,比如可以回滾, 其它事務的排程,都應該由專門的事務管理器實現。 在Java中,分散式事務主要的規範是JTA/XA, 其中:JTA是Java的事務管理器規範, XA是工業標準的X/Open CAE規範,可被兩階段提交及回滾的事務資源定義, 比如某資料庫實現了XA規範,則不管是JTA,還是MSDTC,都可以基於同樣的行為對該資料庫進行事務處理。
首先是不建議採用XA兩階段提交方式去處理分散式事務,要知道要能夠支援XA分散式事務,必須是要實現XA規範才可以,而Service本身是無狀態的,如果這樣去做了等於是把Service內部的東西暴露了出去。對於分散式事務最好的方式還是事務補償或者BASE基於訊息的最終一致性。
可以設想一個最簡單的分散式事務場景,對於跨銀行的轉賬操作,該操作涉及到呼叫兩個異地的Service服務,一個是本地提供的取款服務,一個是目標銀行提供的存款服務,該兩個服務本身無狀態且獨立,構成一個完整的事務。對於事務的處理初步分析: 事務補償機制 事務補償即在事務鏈中的任何一個正向事務操作,都必須存在一個完全符合回滾規則的可逆事務。如果是一個完整的事務鏈,則必須事務鏈中的每一個業務服務或操作都有對應的可逆服務。對於Service服務本身無狀態,也不容易實現前面討論過的透過DTC或XA機制實現的跨應用和資源的事務管理,建立跨資源的事務上下文。因此也較難以實現真正的預提交和正式提交的分離。
在這種情況下以上面例子來說,首先呼叫取款服務,完全呼叫成功並返回,資料已經持久化。然後呼叫異地的存款服務,如果也呼叫成功,則本身無任何問題。如果呼叫失敗,則需要呼叫本地註冊的逆向服務(本地存款服務),如果本地存款服務呼叫失敗,則必須考慮重試,如果約定重試次數仍然不成功,則必須log到完整的不一致資訊。也可以是將本地存款服務作為訊息傳送到訊息中介軟體,由訊息中介軟體接管後續操作。 在上面方式中可以看到需要手工編寫大量的程式碼來處理以保證事務的完整性,我們可以考慮實現一個通用的事務管理器,實現事務鏈和事務上下文的管理。對於事務鏈上的任何一個服務正向和逆向操作均在事務管理和協同器上註冊,由事務管理器接管所有的事務補償和回滾操作。
基於訊息的最終一致性 在這裡首先要回答的是我們需要時實時一致性還是最終一致性的問題,如果需要的是最終一致性,那麼BASE策略中的基於訊息的最終一致性是比較好的解決方案。這種方案真正實現了兩個服務的真正解耦,解耦的關鍵就是非同步訊息和訊息持久化機制。 還是以上面的例子來看。對於轉賬操作,原有的兩個服務呼叫變化為第一步呼叫本地的取款服務,第二步傳送異地取款的非同步訊息到訊息中介軟體。如果第二步在本地,則保證事務的完整性基本無任何問題,即本身就是本地事務的管理機制。只要兩個操作都成功即可以返回客戶成功。
由於解耦,我們看到客戶得到成功返回的時候,如果是上面一種情況則異地卡馬上就能查詢賬戶存款增加。而第二種情況則不一定,因為本身是一種非同步處理機制。訊息中介軟體得到訊息後會去對訊息解析,然後呼叫異地銀行提供的存款服務進行存款,如果服務呼叫失敗則進行重試。
異地銀行存款操作不應該長久地出現異常而無法使用,因此一旦發現異常我們可以迅速的解決,訊息中介軟體中異常服務自然會進行重試以保證事務的最終一致性。這種方式假設問題一定可以解決,在不到萬不得已的情況下本地的取款服務一般不進行可逆操作。 在本地取款到異地存款兩個服務呼叫之間,會存在一個真空期,這段時間相關現金不在任何一個賬戶,而只是在一個事務的中間狀態,但是客戶並不關心這個,只要在約定的時間保證事務最終的一致性即可。
關於冪等操作的問題 重複呼叫多次產生的業務結果與呼叫一次產生的業務結果相同,簡單點講所有提供的業務服務,不管是正向還是逆向的業務服務,都必須要支援重試。因為服務呼叫失敗這種異常必須考慮到,不能因為服務的多次呼叫而導致業務資料的累計增加或減少。 關於是否可以補償的問題 在這裡我們談的是多個跨系統的業務服務組合成一個分散式事務,因此在對事務進行補償的時候必須要考慮客戶需要的是否一定是最終一致性。客戶對中間階段出現的不一致的承受度是如何的。 3
在上面的例子來看,如果採用事務補償機制,基本可以是做到準實時的補償,不會有太大的影響。而如果採用基於訊息的最終一致性方式,則可能整個週期比較長,需要較長的時間才能給得到最終的一致性。比如週六轉款,客戶可能下週一才得到通知轉賬不成功而進行了回退,那麼就必須要考慮客戶是否能給忍受。
其次對於前面討論,如果真正需要的是實時的一致性,那麼即使採用事務補償機制,也無法達到實時的一致性。即很可能在兩個業務服務呼叫中間,客戶前臺業務操作對持久化的資料進行了其它額外的操作。在這種模式下,我們不得不考慮需要在資料庫表增加業務狀態鎖的問題,即整個事務沒有完整提交併成功前,第一個業務服務呼叫雖然持久化在資料庫,但是仍然是一箇中間狀態,需要透過業務鎖來標記,控制相關的業務操作和行為。但是在這種模式下無疑增加了整個分散式業務系統的複雜度。
-
4 # right10
各個服務處理好自身回滾,將自己出錯的資訊通知給其他服務進行處理。記錄好各個服務的日誌資訊,出現斷電情況透過日誌恢復。或者第三方服務統一控制事物。看要做到什麼程度。說得簡單,做起來挺複雜的
-
5 # 解道Jdon
分散式事物其實是個偽概念,因為傳統的JTA或2PC在分散式環境下無法抵抗網路的不穩定性,分散式的特點就是預設網路不穩定,這與在同一臺伺服器中概念是不同的,而CAP定理才是分散式網路的根本依據,傳統JTA或者基於RPC的所謂事務都是不適合分散式的,因為網路容錯性差 很脆弱。所以最終一致性的柔性事務才是根據CAP下的選擇,比如Saga等都是成熟方案。
-
6 # 修雲財經號
說不了如何,那個說來話長,小篇幅講不清楚。我要說的是,事務一致性並不少見,只要是有複雜金融交易場景的都需要事務一致性,這個不難。真正難的是在互金場景大規模交易下如何低成本地實現事務一致性。普通的Dubbo根本做不了,現在唯一在大量金融核心交易實踐中實現分步式事務一致性並且能對外輸出的只有螞蟻金服的SOFA及其中介軟體。
-
7 # ksfzhaohui
分散式事務:是指會涉及到操作多個數據庫的事務。其實就是將對同一庫事務的概念擴大到了對多個庫的事務。目的是為了保證分散式系統中的資料一致性。分散式事務處理的關鍵是必須有一種方法可以知道事務在任何地方所做的所有動作,提交或回滾事務的決定必須產生統一的結果(全部提交或全部回滾)。
X/Open 組織(即現在的 Open Group )定義了分散式事務處理模型。 X/Open DTP 模型( 1994 )包括應用程式( AP )、事務管理器( TM )、資源管理器( RM )、通訊資源管理器( CRM )四部分。一般,常見的事務管理器( TM )是交易中介軟體,常見的資源管理器( RM )是資料庫,常見的通訊資源管理器( CRM )是訊息中介軟體。 XA 就是 X/Open DTP 定義的交易中介軟體與資料庫之間的介面規範(即介面函式),交易中介軟體用它來通知資料庫事務的開始、結束以及提交、回滾等。 XA 介面函式由資料庫廠商提供。 二階提交協議和三階提交協議就是根據這一思想衍生出來的。可以說二階段提交其實就是實現XA分散式事務的關鍵(確切地說:兩階段提交主要保證了分散式事務的原子性:即所有結點要麼全做要麼全不做)。
所以大部分的關係型資料庫透過兩階段提交(2 Phase Commit 2PC)演算法來完成分散式事務就不足為奇了。
1.兩階段/三階段提交
2PC/3PC全稱:Two/Three Phase Commit,中文名叫叫兩階段/三階段提交;為了使基於分散式系統架構下的所有節點在進行事務處理的過程中能夠ACID特性而設計的一種演算法,需要引入一個作為協調者的元件來統一掌控所有節點(稱作參與者)的操作結果並最終指示這些節點是否要把操作結果進行真正的提交兩階段提交的演算法如下:
第一階段:提交事務階段(投票階段)
第二階段:執行事務提交(執行階段)
這種方式缺點比較多,通常在複雜場景下是不推薦使用的,除非是非常簡單的場景,非常容易提供回滾,而且依賴的服務也非常少的情況。
2.本地方法表
這種實現方式的思路,其實是源於ebay;其基本的設計思想是將遠端分散式事務拆分成一系列的本地事務。如果不考慮效能及設計優雅,藉助關係型資料庫中的表即可實現。舉個經典的跨行轉賬的例子來描述。
第一步虛擬碼如下,扣款1W,透過本地事務保證了憑證訊息插入到訊息表中。
第二步,通知對方銀行賬戶上加1W了,如何通知對方:可以透過輪詢或者MQ的方式
3.MQ
方式大致虛擬碼如下,跨行轉賬為例
try{1.本地更新資料庫,如果更新成功,執行第二部2.透過MQ傳送訊息}catch{rollback();}如果第一步失敗,那不會將訊息傳送到MQ,如果第一步成功,第二步失敗,那捕獲異常回滾資料,保證資料一致性;
4.事務MQ
有MQ是直接支援分散式事務的,比如阿里的RocketMQ;RocketMQ處理事務訊息的大致流程如下:
1.生產者傳送"待確認"訊息;
2.RocketMQ接收到訊息進行相關儲存操作,成功以後返回狀態給生產者;
3.生產者接收到的返回如果為SEND_OK狀態,將執行本地事務操作;
4.根據本地事務執行的結果,生產者執行commit還是rollback;
5.如果第四步生產者執行操作失敗,伺服器會在經過固定時間段對狀態為"待確認"的訊息發起回查請求;
6.生產者接收到回查請求後根據本地事務的結果返回commit還是rollback;
7.伺服器收到結果後執行相關操作。
總結
可以看到第一種方式是保證絕對的一致性,這種在網際網路行業很少使用,主要是效能太差了;後面四種情況都是保證了“最終一致性”,這種方式用的比較廣泛;另外分散式事務本質上其實是資料一致性問題,所以可以關注一下CAP理論和Base理論;更多的可以關注本人的相關文章。
不管是soa,還是微服務,我們做一個大的專案,會拆分成多個模組,也就是多個小專案。那我們這些小專案呼叫得時候,這個分散式事物是怎麼控制的,可以把dubbo和feignclient的都詳細講下嗎?
回覆列表
對於這種分散式的亊務挖制,我認為總設計師應該實際的工作情況,時刻監控各個方面有關聯的系紡,統一調配,隨時監督,我認為這樣才能控荊整體亊態的發展,對這方面我是個外行,只是發表自已的一點看法。