您好,登錄后才能下訂單哦!
本篇內容介紹了“web分布式事務舉例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
在分布式時代,分庫分表是很常見的,微服務系統中,各個系統通常使用獨立的數據庫,所以,事務很難靠數據庫本身保證,只能靠業務系統來解決。
例如支付寶中的余額寶、花唄,具體不清楚,但猜測應該就是2個服務,不是同一個數據庫,我們還花唄的時候通常都是從余額寶中扣除的,這就是分布式事務,一個系統中扣減錢,一個系統中增加錢。
下面我們分析下最終一致性的實現方案,最終一致性通常都是使用消息中間件來實現的,系統結構如下:
用戶向系統A發起轉賬請求,A先在自己的數據庫中扣錢,然后通過消息中間件告訴B應該加錢,B收到后在自己的數據庫中加錢。
這里有個關鍵問題,A更新數據庫和給消息中間件發消息是2個操作,如下兩個場景怎么處理:
先更新數據庫,成功了,但發送消息失敗了,重發多次還是失敗
先發消息,成功了,但數據庫更新失敗,消息撤不回來了
都是因為這2個操作不是原子的,發做誰都有問題。
那看下這樣做是否可以,就是把更新數據庫和給消息中間件發消息放到一個事務中,這樣不就原子了嗎?
有問題,例如:
如果消息發送失敗,具體問題出在哪兒?是消息中間件根本就沒收到消息,還是收到消息后response時出錯了?如果是根本沒收到還好一點,如果是收到了但響應失敗就麻煩了,導致A數據庫回滾,沒有扣錢,但B收到消息了,加錢了。
如果發消息時網絡延遲很高怎么辦,數據庫事務一直被拖著,性能差,風險高。
所以,放入一個事務中這種方法是不可取的。
為了保證原子性,可以變通一下,添加一個消息表,A不直接往消息中間件中發消息,而是把消息寫入消息表,然后通過一個后臺程序不斷的把消息寫入消息中間件。
這個后臺程序源源不斷的把消息表中的消息發到消息中間件,如果失敗就重試,可以保證:
消息不會丟失
順序不亂
但會有消息重復的情況,因為消息發送失敗可能是寫入失敗,也可能是寫入成功但響應失敗,所以消息可能會重復,這個問題需要系統B來處理。
系統B需要考慮2個問題:
消息丟失
B從消息中間件中拿到消息,還沒處理完就宕機了,這條消息怎么辦?
需要通過ACK機制處理,消費成功的發送ACK,對于沒有ACK的消息,消息中間件會再次推送。
消息重復
ACK機制也存在消息重復的情況,比如B已經處理完一條消息,發ACK時失敗了,那么這條消息就還會被推過來。
還有就是上面說的后臺程序發消息時可能重復。
對于重復消息問題,可以加一個判重表,記錄處理成功的消息,每次收到消息時,先通過判重表判斷一下,如果重復了就不處理,實現冪等性。
這樣,整體結構就變為:
“web分布式事務舉例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。