日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试必备的分布式事物方案

發布時間:2025/3/11 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试必备的分布式事物方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

四月初,去面試了本市的一家之前在做辦公室無人貨架的公司,雖然他們現在在面臨著轉型,但是對于我這種想從傳統企業往互聯網行業走的孩子來說,還是比較有吸引力的。

在面試過程中就提到了分布式事物問題。我又一次在沒有好好整理的問題上吃了虧,記錄一下,還是長記性 !

先看面試過程

面試官先是在紙上先畫了這樣一張圖:

讓我看這張圖按照上面的流程走,有沒有什么問題?面試官并沒有直接說出來這里面會有分布式事物的問題,而是讓我來告訴他,這就是面試套路呀。

我回答了這中間可能存在分布式事物的問題,當步驟2在調用 B 系統時,可能存在B 系統處理完成后,在響應的時候超時,導致 A 系統誤認為 B 處理失敗了,從而導致A 系統回滾,跟 B 系統存在數據不一致的情況。

ok ,我回答到這里,應該回答了面試官的第一層意思,至少我有這種意識,他點了點頭。

接著,他繼續問:“那你有什么好的解決方式嗎?

此時我腦子里面只有兩階段提交的大概流程圖的印象,然后巴卡巴拉的跟他說了一番,什么中間來個協調者呀,先預提交什么的,如果有失敗,就?rollback,如果 ok,再真正的提交事物,就是網上這些大神們說的這些理論。

然后面試官就繼續問:那A 在調用 B 的這條線斷了,你們代碼具體是怎么處理的呢 ?怎么來做到 rollback 的呢 ?說說你代碼怎么寫的。

此時,我懵了。

最后結果,大家肯定也能猜到,涼涼。

什么是事務

這里我們說的事務一般是指?數據庫事務,簡稱?事務,是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。維基百科中這么說的。

用轉賬的例子來說,A 賬戶要給 B 賬戶轉 100塊,這中間至少包含了兩個操作:

1.A 賬戶 減 100 塊

2.B 賬戶 加 100 塊

在支持事務的數據庫管理系統來說,就是得確保上面兩個操作(整個“事務”)都能完成,不能存在,A 的100塊扣了,然后B的賬戶又沒加上去的情況。

數據庫事務包含了四個特性,分別是:

?原子性(Atomicity):事務作為一個整體被執行,包含在其中的對數據庫的操作要么全部被執行,要么都不執行。對于轉賬來說,A賬戶扣錢,B 賬戶加錢,要么同時成功,要么同時失敗。

?一致性(Consistency):事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態的含義是數據庫中的數據應滿足完整性約束

?隔離性(Isolation):多個事務并發執行時,一個事務的執行不應影響其他事務的執行。其他賬戶在轉賬的時候,不能影響到上面的 A 跟 B 之前的交易。

?持久性(Durability):已被提交的事務對數據庫的修改應該永久保存在數據庫中。

什么是分布式事物

我們知道,上面的轉賬 我們是在一個數據庫中的事務操作。我們可以使用一些框架 比如 Spring 的事務管理器來給我們統一搞定。

但是如果我們系統中出現垮庫操作,比如一個操作中,我需要操作多個庫,或者說這個操作會垮應用之前的調用,那么Spring 的事務管理機制就對這種場景沒有辦法了。

就像上面面試題中出現的問題一樣,在系統 A 的步驟 2 在遠程調用 B 的時候,由于網絡超時,導致B 沒有正常響應,但是A 這邊調用失敗,進行了回滾,而 B 又提交了事物。此時就可能會導致數據不一致的情況,參生分布式事物的問題。

分布式事物的存在,就是解決數據不一致的情況。

為什么我們要保證一致性

CAP 理論

分布式系統中有這么一個廣為流傳的理論:CAP 定理

這個定理呀,起源于加州大學柏克萊分校(University of California, Berkeley)的計算機科學家埃里克·布魯爾在 2000年的分布式計算原理研討會(PODC)上提出的一個猜想。后來在2002年,麻省理工學院(MIT)的賽斯·吉爾伯特和南希·林奇發表了布魯爾猜想的證明,使之成為一個定理。【摘自維基百科】

他說呀,對于一個分布式計算系統來說,不可能同時滿足以下三點:

?一致性(Consistency)

?可用性(Availability)

?分區容錯性(Partition tolerance)

而一個分布式系統最多只能滿足其中的兩項。

那么,上面的三點分別是什么玩意兒?為什么又只能同時滿足兩項呢?

我們先看這樣一個場景,現在我們系統部署了兩份(兩個節點,web1 和 web2 ),同樣的業務代碼,但是維護的是自己這個節點生成的數據。但是用戶訪問進來,可能會訪問到不同的節點。

但是不管是訪問web1 還是web2 ,在用戶參數數據 過后,這個數據都必須得同步到另外的節點,讓用戶不管訪問哪個節點,都是響應他需要的數據。如下圖:

分區容錯性

我們先說?分區容錯性也就是說呀,就算上面這兩個節點之間發生了網絡故障,無法發生同步的問題,但是用戶訪問進來,不管到哪個節點,這個節點都得單獨提供服務,這一點對于互聯網公司來說,是必須要滿足的。

當 web1 和 web2 之間的網絡發生故障,導致數據無法進行同步。用戶在web1 上寫了數據,馬上又訪問進來讀取數據,請求到了 web2,但是此時 web2 是沒有數據的。那么我們是 給用戶返回 null ?還是說給一些提示,說系統不可用,稍后重試呢?

都不妥吧,兄弟。

一致性

如果要保證可用性,那么有數據的節點返回數據,沒數據的節點返回 null ,就會出現用戶那里看到的是一會兒有數據,一會兒沒有數據,此時就存在?一致性 的問題。

可用性

如果保證一致性,那么在用戶訪問的時候,不管 web1 還是web2 ,我們可能會返回一些提示信息,說系統不可用,稍后再試等等,保證每次都是一致的。明明我們有數據在,但是我們系統卻響應的是提示信息,此時就是 可用性 的問題。

由于分區容錯性(P)是必須保證的,那么我們分布式系統就更多是在一致性(CP) 和可用性(AP)上做平衡了,只能同時滿足兩個條件。

其實,大家想想,ZK 是不是就是嚴格實現了 CP ,而 Eureka 則是保證了 AP。

其實分布式事物強調的就是一致性。

幾種分布式事物解決方案

2PC

在說 2PC 之前,我們先了解一下?XA規范 是個什么東西?

XA規范 描述了全局的事務管理器與局部的資源管理器之間的接口。XA規范的目的是允許多個資源(如數據庫,應用服務器,消息隊列,等等)在同一事務中訪問,這樣可以使ACID屬性跨越應用程序而保持有效。

XA 使用 兩階段提交(2PC) 來保證所有資源同時提交或回滾任何特定的事務。

大家想一個場景,在做單應用的時候,有的同學連過兩個庫吧?在一個事物中會同時向兩個系統插入數據。但是對于普通事物來講,是管不了的。

看下圖(只是舉例這種操作的套路,不局限于下面的業務):

一個服務里面要去操作兩個庫,如何保證事物成功呢。

這里我們介紹一個框架?Atomikos ,他就是實現了這種 XA 的套路。看代碼:

具體代碼移步 Github?AtomikosJTATest[1]:?https://github.com/heyxyw/learn/blob/master/distributed-transaction/src/main/java/com/zhouq/jta/AtomikosJTATest.java[2]

看到上面的圖了哇,Atomikos 自己實現了一個事物管理器。我們獲取的連接都從它哪里拿。

?第一步先開啟事務,然后進行預提交,db1 和 db2 都先進行預先執行,注意:這里沒有提交事物。?第二步才是真正的提交事物,由 Atomikos 來發起提交的,如果出現異常則發起回滾操作。

這個過程是不是就有兩個角色了,一個 事務管理器,一個資源管理器(我們這里是 數據庫,也可以是其他的組件,消息隊列什么的)。

整個執行過程是這樣:

上圖是正常情況,下圖是一方出現故障的情況。

圖片來自:XA 事務處理[3]:https://www.infoq.cn/article/xa-transactions-handle[4] ,具體關于XA 的詳細講解,可以好好看看。整個2PC 的流程:

第一階段(提交請求階段)

  • 協調者節點向所有參與者節點詢問是否可以執行提交操作,并開始等待各參與者節點的響應。

  • 參與者節點執行詢問發起為止的所有事務操作,并將Undo信息和Redo信息寫入日志。

  • 各參與者節點響應協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它返回一個"同意"消息;如果參與者節點的事務操作實際執行失敗,則它返回一個"中止"消息。

  • 第二階段 (提交執行階段)

    成功當協調者節點從所有參與者節點獲得的相應消息都為"同意"時:

    1.協調者節點向所有參與者節點發出"正式提交"的請求。

    2.參與者節點正式完成操作,并釋放在整個事務期間內占用的資源。

    3.參與者節點向協調者節點發送"完成"消息。

    4.協調者節點收到所有參與者節點反饋的"完成"消息后,完成事務。

    失敗如果任一參與者節點在第一階段返回的響應消息為"終止",或者 協調者節點在第一階段的詢問超時之前無法獲取所有參與者節點的響應消息時:

    1.協調者節點向所有參與者節點發出"回滾操作"的請求。

    2.參與者節點利用之前寫入的Undo信息執行回滾,并釋放在整個事務期間內占用的資源。

    3.參與者節點向協調者節點發送"回滾完成"消息。

    4.協調者節點收到所有參與者節點反饋的"回滾完成"消息后,取消事務。

    有時候,第二階段也被稱作完成階段,因為無論結果怎樣,協調者都必須在此階段結束當前事務。

    可靠消息最終一致性方案基于普通的消息隊列中間件上面我們說了兩階段提交的方案,接下來我們講講怎么基于可靠消息最終一致性方案來解決分布式事物的問題。

    這個方案,就有消息服務中間件角色參與進來了。我們先看一個大提的流程圖:

    我們以創建訂單下單過程和 后面出庫 的流程為例來講述上面的圖。

    在下單邏輯里面(Producer 端),我們先生成一個訂單的數據,比如訂單號,數量等關鍵的信息,先包裝成一條消息,并把消息的狀態置為 init ,然后發送到 獨立消息服務中,并且入庫。

    接下來繼續處理 下單的其他本地的邏輯。

    處理完成后,走到確認發送消息這一步,說明我的訂單是能夠下成功的。那么我們再向消息服務里面發送一條confirm 的消息,消息服務里面就可以把這個訂單的消息狀態修改為 send 并且,發送到消息隊列里面。

    接下來,消費者端去消費這條消息。處理自己這邊的邏輯,處理完成以后,然后反饋消息處理結果到獨立消息服務,獨立消息服務把消息狀態置為 end 狀態 ,表示結束。但是得注意保證接口的冪等性,避免重復消費帶來的問題。

    這里面可能出現的問題,以及各個步驟怎么解決的:

    1.比如在?prepare 階段就發生異常,那么這里訂單這塊都不會下成功。但是我們說,我們這里是基于可靠消息,得保證我們的消息服務是正常的。

    2.在?comfirm 出現異常,此時發送確認失敗,但是我們的單已經下成功了。這種情況,我們就可以在獨立消息服務中起一個定時任務,定時去查詢 消息狀態為 init?的數據,去反向查詢 訂單系統中的單號是否存在,如果存在,那么我們就把消息置為?send 狀態,然后發送到 消息隊列里面,如果查詢到不存在的訂單,那么就直接拋棄掉這條消息。所以這里我們的訂單系統得提供批量查詢訂單的接口,還有下游的消費系統得保證冪等。保證重復消費的一致性。

    3.消息隊列丟消息或者下游系統一直處理失敗,導致沒有消息反饋過來,出現一直是?send 狀態的消息。此時獨立消息我們還需要一個定時任務,就是處理這種 send 狀態的消息,我們可以進行重發,直到后面系統消費成功為止。

    4.最后消費者這端,我們在消費的時候,如果出現消費異常,或者是系統bug 導致異常的情況。那么這里我們還可以去記錄日志,如果不是系統代碼問題,是網絡抖動導致的,那么在上面第三種情況,消息系統會重新發送消息,我們再處理就是。如果是一直失敗,你就要考慮是不是你的代碼真的有問題,有bug 了吧。

    5.最后的保底方案,記錄日志,出現問題人肉處理數據。現在我們系統出現錯誤,以目前的技術手段是沒辦法做到都靠機器去解決的,都得靠我們人。據我了解,現在很多大廠都會有這樣的人,專門處理這種類型的問題,手動去修改數據庫的方式。我們之前待的小廠,基本上都是靠我們自己去寫 sql 去修改數據的,想想,是不是?

    貼一下關鍵的獨立消息服務核心邏輯代碼框架

    定時任務

    基于 RocketMQ實現

    這種方案,跟上面的獨立消息服務一致,這里直接去掉獨立服務,只利用消息隊列來實現,也就是阿里的?RocketMQ

    流程圖如下:

    這里的整個流程跟上面基于消息服務是一致的。這里就不過多闡述,具體代碼實現請參考 :https://www.jianshu.com/p/453c6e7ff81c[5] ,寫得非常好。

    針對這里的 可靠消息最終一致性方案 來說,我們說的 可靠 是指保證消息一定能發送到消息中間件里面去,保證這里可靠。

    對于下游的系統來說,消費不成功,一般來說就是采取失敗重試,重試多次不成功,那么就記錄日志,后續人工介入來進行處理。所以這里得強調一下,后面的系統,一定要處理 冪等,重試,日志 這幾個東西。

    如果是對于資金類的業務,后續系統回滾了以后,得想辦法去通知前面的系統也進行回滾,或者是發送報警由人工來手工回滾和補償。

    TCC 方案

    TCC 的全程分為三個階段,分別是 Try、Confirm、Cancel:

    1.Try階段這個階段說的是對各個服務的資源做檢測以及對資源進行鎖定或者預留

    2.Confirm階段這個階段說的是在各個服務中執行實際的操作

    3.Cancel階段如果任何一個服務的業務方法執行出錯,那么這里就需要進行補償,就是執行已經執行成功的業務邏輯的回滾操作

    還是以轉賬的例子為例,在跨銀行進行轉賬的時候,需要涉及到兩個銀行的分布式事物,從A 銀行向 B 銀行轉 1 塊,如果用TCC 方案來實現:

    大概思路就是這樣的:

    1.Try 階段先把A 銀行賬戶先凍結 1 塊,B銀行賬戶中的資金給預加 1 塊。

    2.Confirm 階段執行實際的轉賬操作,A銀行賬戶的資金扣減 1塊,B 銀行賬戶的資金增加 1 塊。

    3.Cancel 階段如果任何一個銀行的操作執行失敗,那么就需要回滾進行補償,就是比如A銀行賬戶如果已經扣減了,但是B銀行賬戶資金增加失敗了,那么就得把A銀行賬戶資金給加回去。

    這種方案就比較復雜了,一步操作要做多個接口來配合完成。

    以 ByteTCC 框架的實現例子來大概描述一下上面的流程,示例地址?https://gitee.com/bytesoft/ByteTCC-sample/tree/master/dubbo-sample[6]

    最開始 A 銀行賬戶 與 B 銀行賬戶都分別為:amount(數量)=1000,frozen(凍結金額)= 0

    從A銀行賬戶發起轉賬到 B 銀行賬戶 1 塊:

    try 階段A 銀行賬戶金額減 1,凍結金額 加 1,B 銀行 賬戶 凍結金額加 1 。

    此時:

    ?A 銀行賬戶:amount(數量)= 1000 - 1 = 999,frozen(凍結金額)= 0 + 1 = 1

    ?B 銀行賬戶:amount(數量)= 1000,frozen(凍結金額)= 0 + 1 = 1

    confirm 階段A銀行賬戶凍結金額 減 1,B 銀行賬戶金額 加 1,凍結金額 減 1

    此時:

    ?A 銀行賬戶:amount(數量)= 999,frozen(凍結金額)= 1 - 1 = 0

    ?B 銀行賬戶:amount(數量)= 1000 + 1 = 1001,frozen(凍結金額)= 1 - 1 = 0

    cancel 階段A 銀行賬戶金額 + 1,凍結金額 -1 ,B 銀行 凍結金額 -1

    此時:

    ?A 銀行賬戶:amount(數量)= 999 + 1 = 1000,frozen(凍結金額)= 1 - 1 = 0

    ?B 銀行賬戶:amount(數量)= 1000,frozen(凍結金額)= 1 - 1 = 0

    至此,整個過程就演示完畢,大家記得跑一遍代碼。其實還是蠻復雜的,有許多接口一起來配合完成整個業務,試想一下,如果我們項目中大量用到 TCC 來寫,你受得了?

    再提一下 BASE理論

    BASE 理論是 Basically Available(基本可用),Soft State(軟狀態)和Eventually Consistent(最終一致性)三個短語的縮寫。

    1.基本可用(Basically Available)指分布式系統在出現不可預知故障的時候,允許損失部分可用性。

    2.軟狀態( Soft State)指允許系統中的數據存在中間狀態,并認為該中間狀態的存在不會影響系統的整體可用性,即允許系統在不同節點的數據副本之間進行數據同步的過程存在延時。

    3.最終一致( Eventual Consistency)強調的是所有的數據更新操作,在經過一段時間的同步之后,最終都能夠達到一個一致的狀態。因此,最終一致性的本質是需要系統保證最終數據能夠達到一致,而不需要實時保證系統數據的強一致性。

    其核心思想是:

    即使無法做到強一致性(Strong consistency),但每個應用都可以根據自身的業務特點,采用適當的方式來使系統達到最終一致性(Eventual consistency)

    到這里大家再想想, 上面 TCC 方案中的賬戶設計了一個凍結字段?frozen?,這里是不是就是?BASE理論 中間的 軟狀態 呢 ?

    最后

    對存在非常多的微服務的公司來說,服務之間的調用異常的復雜,那么在引入分布式事物的過程中,你需要考慮加入分布式事物后,系統實現起來的復雜性和開發成本,或者說哪些地方根本就不需要搞分布式事物。

    其實沒必要到處都搞分布式事物,對于大多數的業務來說,其實我們并不需要做分布式事物,直接做日志,做監控就好了。然后出現問題,手工去處理,一個月也不會有那么多的問題的。如果你天天都出現這些問題,你是不是要好好去排查排查你的代碼Bug了。

    對于資金類的場景,那么基本上會采用分布式事物方案來保證,像其他的服務,會員,積分,商品信息呀這些,可能就不需要這么去搞了。


    作者介紹:喬二爺,在成都喬二爺這個名字是之前身邊的同事給取的,也不知道為啥。也習慣了他們這樣叫我。

    一直待在相對傳統一點的企業,有四年半的 Java 開發經驗,會點大數據的內容,也跟客戶打過一年的交道,還帶過 10個月 10人+的技術團隊,有一定的協調組織能力,能夠理解 boss 的工作內容,也能很好的配合別人做事。

    【End】

    重磅消息:為了回饋讀者朋友,老王準備了500元的微信紅包,點擊參與領取

    關注下方二維碼,訂閱更多精彩內容。

    轉發朋友圈,是對我最大的支持。

    總結

    以上是生活随笔為你收集整理的面试必备的分布式事物方案的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲福利社 | 奶水旺盛的少妇在线播放 | 亚洲视频在线免费看 | av三级在线观看 | 在线观看av不卡 | 一区二区高清在线 | 性xx紧缚网站| 91香蕉在线视频 | www.热久久| 亚洲第一免费 | 91麻豆免费视频 | 色播99| 青青青在线视频 | xxxx国产 | 136fldh导航福利微拍 | 3d毛片 | 欧美性受黑人性爽 | 2021中文字幕 | 久久精品网址 | 干一夜综合 | 波多野吉衣伦理片 | 自拍偷拍国产 | 日韩精品一区二区在线视频 | 深夜福利国产 | xxxx国产精品 | 99在线视频免费观看 | 久久综合色视频 | 风间由美一区二区 | 欧美日本免费 | 91久久精品在线 | 国产成人精品亚洲男人的天堂 | 国产特级黄色片 | 欧美日韩操 | 久久精品人人爽 | 羞辱狗奴的句子有哪些 | 日韩综合在线观看 | 91蝌蚪少妇偷拍 | 亚洲国产片 | 99国产精品久久久久99打野战 | 超碰资源在线 | 清纯唯美亚洲综合 | 99成人 | 意大利少妇愉情理伦片 | 欧美xxxx吸乳| 国产精品99久久久久久人 | 亚洲小说在线 | 色婷婷视频 | 国产精品一二三区视频 | 女人久久 | 国产ts在线| 在线免费a视频 | 精品少妇人妻一区二区黑料社区 | 国产黄a三级 | 手机在线看片你懂的 | 精品中文一区二区三区 | 狠狠久| 伊人网址| 欧美一级免费黄色片 | 国产三级伦理片 | 国产99视频在线观看 | 国产精彩视频 | 波多野结衣在线观看一区 | 国产精品久久久久久久一区探花 | 亚洲午夜久久久久 | 91视频在线观看免费 | 日韩精品无 | 日本性xxxxx 免费毛片视频网站 | 日韩av在线免费观看 | 亚洲成色在线 | 丁香婷婷九月 | 国产亚洲一区二区三区在线观看 | 亚洲激情小视频 | 夜夜cao | 欧美xxxxxhd| 国产精品无码一区二区三区三 | 久操操 | 香蕉啪啪网 | 国产免费一区二区三区在线播放 | 岛国片免费在线观看 | 欧美日韩综合一区二区三区 | 国产大奶在线 | 久久久人妻无码一区二区 | 欧美视频一区二区三区 | 日日爽夜夜操 | 日韩中文字幕亚洲精品欧美 | 脱女学生小内内摸了高潮 | av在线一 | 亚洲精品7777 | 草草视频在线播放 | 欧美伦理一区 | 新疆毛片| 免费一级做a爰片久久毛片潮 | 探花国产在线 | 暖暖日本在线视频 | 亚洲性xxxx| 黄色喷水视频 | 亚洲国产网址 | 国产无码精品视频 | 宅男在线视频 |