亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java業(yè)務中臺確保數(shù)據(jù)一致性的解決方案

 更新時間:2021年10月11日 09:28:15   作者:慕楓技術筆記  
數(shù)據(jù)一致性通常指關聯(lián)數(shù)據(jù)之間的邏輯關系是否正確和完整。而數(shù)據(jù)存儲的一致性模型則可以認為是存儲系統(tǒng)和數(shù)據(jù)使用者之間的一種約定。如果使用者遵循這種約定,則可以得到系統(tǒng)所承諾的訪問結果

引言

隨著業(yè)務的發(fā)展,微服務架構逐漸成為當下業(yè)務中臺的主流架構形式,它不但解決了各個應用之間的解耦問題,同時也解決了單體應用的性能問題實現(xiàn)可擴展可動態(tài)伸縮的能力。如下圖所示,業(yè)務中臺就是將平臺的通用能力進行下沉,避免重復建設,形成底座平臺能力,上層的各個應用服務都是基于中臺能力進行快速構建。但是隨著應用規(guī)模的擴大,原本在單體應用中不是問題的問題,在微服務架構中可能就是比較嚴重的問題,本文所要探討的服務之間的數(shù)據(jù)一致性便是其中最具代表性的問題。本文將結合常見的電商下單場景來說明業(yè)務中臺數(shù)據(jù)一致性方案。

在這里插入圖片描述

數(shù)據(jù)一致性原理預備知識

在探討業(yè)務中臺數(shù)據(jù)一致性方案之前,我們先來一起回顧下數(shù)據(jù)庫事務的相關內容,通過對數(shù)據(jù)庫事務的分析,我們可以看出來在微服務架構中想要保證數(shù)據(jù)的一致性將會遇到什么樣的問題。

1、本地事務

事務的概念對于程序猿來說一定不陌生,這里的事務指的是數(shù)據(jù)庫事務。所謂數(shù)據(jù)庫事務,簡單來理解就是一套關于數(shù)據(jù)一致性維護的數(shù)據(jù)庫機制。 我們都知道,實際業(yè)務平臺大部分的業(yè)務數(shù)據(jù)還是保存在關系型數(shù)據(jù)庫中,在單體應用的時代,數(shù)據(jù)庫實例本身可以保證事務的有效性。
數(shù)據(jù)庫事務需要滿足四個基本特征:

(1)原子性(Atomicity):極端主義者,要么大家一起成功,有一個失敗都不行

(2)一致性(Consistency): 數(shù)據(jù)具有一致性,不存在狀態(tài)不確定的狀況

(3)隔離性(Isolation):事務之間互相不干擾,你走你的陽關道,我走我的獨木橋

(4)永久性(Durability):一旦事務提交后,數(shù)據(jù)就記錄就會被持久化

都說王守義 13 香,筆者最近也下單了一部 pro 準備換掉三年前的 iphone。那么我們以下單購買 iphone13 進行舉例說明,我們暫時將如下圖所示,如果在一個完整事務中,存在生成訂單、扣減庫存、增加積分以及發(fā)放優(yōu)惠券這四項業(yè)務,那么要么這四項都成功,下單夠購買 13 香這個業(yè)務才算是成功,中間有一項失敗就會造成業(yè)務數(shù)據(jù)的不一致,因此需要進行事務回滾,回滾到下單前的狀態(tài),以保證業(yè)務數(shù)據(jù)的一致性。

在這里插入圖片描述

2、分布式事務

隨著業(yè)務的不斷發(fā)展,業(yè)務復雜度也在不斷的增長,企業(yè)基于微服務架構向下沉淀出了通用的業(yè)務中臺,數(shù)據(jù)的訪問形式變得復雜了,服務節(jié)點間的數(shù)據(jù)訪問通過 API 接口進行。原本單數(shù)據(jù)庫實例只能保證數(shù)據(jù)庫實例內部的事務,但是在跨數(shù)據(jù)庫實例以及分布式業(yè)務調用過程中,單數(shù)據(jù)庫實例已經(jīng)無法保證全局事務的有效性。因此我們需要分布式的事務機制來保證各個服務節(jié)點之間的數(shù)據(jù)邏輯一致,否則就會出現(xiàn)如下的數(shù)據(jù)不一致的問題。

在這里插入圖片描述

針對分布式場景下的數(shù)據(jù)一致性問題,業(yè)界提出了 CAP 理論以及 BASE 理論,同時在這些理論的基礎之上產生了相應的分布式事務解決方案。我們先來看下什么是 CAP 理論以及 BASE 理論。

CAP 理論

Consistency:數(shù)據(jù)一致性

Avalibility:數(shù)據(jù)可用性

Partition tolerance:分區(qū)容錯性

在這里插入圖片描述

任何一個分布式系統(tǒng)是沒法同時滿足 CAP 中的三項的,為什么這么說呢?我們來舉個簡單的例子來進行說明。如下圖所示,訂單服務將生成的訂服務寫入訂單數(shù)據(jù)主庫,同時將數(shù)據(jù)同步到訂單數(shù)據(jù)從庫中,訂單服務從從庫中進行訂單數(shù)據(jù)查詢,從人實現(xiàn)訂單數(shù)據(jù)的讀寫分離。那么我們繼續(xù)來看,當系統(tǒng)滿足分區(qū)容錯性之后,數(shù)據(jù)一致性和數(shù)據(jù)可用性之間存在怎樣的矛盾。

如果必須實現(xiàn)數(shù)據(jù)的一致性,那么當訂單數(shù)據(jù)寫入主庫的時候,由于此時主庫還未將最新的訂單數(shù)據(jù)同步到從庫當中,因此主庫和從庫出現(xiàn)了數(shù)據(jù)不一致的情況,但是一致性又要求必須實現(xiàn)數(shù)據(jù)的強一致,那么此時的只好將從庫鎖住不對外提供服務,直到主庫數(shù)據(jù)同步到從庫后再開放訂單數(shù)據(jù)查詢。因此在 這個過程中無法同時滿足數(shù)據(jù)一致性以及可用性。

在這里插入圖片描述

對應的 BASE 理論,其實就是一種 CAP 理論的實際權衡結果,既然無法做到強一致性,那么各個服務節(jié)點可以根據(jù)自身的業(yè)務特點實現(xiàn)數(shù)據(jù)的最終一致。所謂 BASE 理論指的就是:

a、Basically Available — 基本可用,畢竟對于分布式系統(tǒng)來說,可用性比數(shù)據(jù)一致性性要重要的多

b、Soft state — 軟狀態(tài) 指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認為該中間狀態(tài)的存在不會影響系統(tǒng)的整體可用性,即允許系統(tǒng)在不同節(jié)點的數(shù)據(jù)副本之間進行數(shù)據(jù)同步的過程中存在延時

c、Eventually consistent — 最終一致性,強調的是系統(tǒng)中所有的數(shù)據(jù)副本,在進過一段時間的同步后,最終能夠達到一個一致的狀態(tài)。最終一致性需要保證數(shù)據(jù)最終能夠一致而不需要保證數(shù)據(jù)實時的一致性。

看吧,實際上我們也不需要太為難我們自己,既然很難實現(xiàn)強一致性,那么實現(xiàn)最終一致性相對來說是一個非常劃算以及可行性較高的數(shù)據(jù)一致性解決方案。
有了前人大佬們總結的分布式理論,我們一起來看下幾種常見的分布式事務場景吧。

(1)一個事務中包含了多數(shù)據(jù)庫操作

我們還是以上面購買 13 香來舉個栗子,由于業(yè)務量的不斷攀升,之前的單數(shù)據(jù)庫實例已經(jīng)無法滿足當前業(yè)務要求。因此我們將數(shù)據(jù)庫按照業(yè)務域進行了拆分。我們簡化下購物的業(yè)務流程,簡化后包括生成訂單、扣減庫存以及增加積分,因此一個購物事務中包括了三個數(shù)據(jù)庫的操作,但是數(shù)據(jù)庫實例只能保證自身的事務特性,不能保證全局的事務特性。如果訂單生成,但是庫存沒有扣減,積分沒有增加,將數(shù)顯數(shù)據(jù)不一致問題,因此出現(xiàn)了分布式事務問題。

在這里插入圖片描述

(2)一個事務中包含了多服務訪問同一數(shù)據(jù)庫

隨著業(yè)務的發(fā)展,原先單體項目的模塊越來越多,維護起來成本較高,比如訂單模塊修改了但是庫存模塊沒有修改,但是發(fā)布的時候還是需要發(fā)布整個應用,萬一有個 Bug 啥的還要回滾,不能做到功能和維護上面的隔離。因此我們需要對應用不同的模塊進行拆分,那么原本的內部調用變成了兩個服務之間的遠程調用,原本的本地事務就演變成了分布式事務。

在這里插入圖片描述

(3)一個事務包含了多個微服務調用數(shù)據(jù)不一致引發(fā)的問題

在微服務架構體系下面,原有的服務中的各個業(yè)務模塊經(jīng)過縱向拆分后,成為一個個獨立的服務,如前面的購物業(yè)務流程,整個過程涉及到多個微服務,因此數(shù)據(jù)庫提供的事務機制,只能保證一個微服務節(jié)點的事務,同樣不能保證全局的事務。因此當一個微服務需要調用多個其他微服務完成對應的業(yè)務時,分布式事務的問題就會出現(xiàn)。

在這里插入圖片描述

數(shù)據(jù)一致性解決方案

正是因為分布式微服務的復雜結構,因此給維護數(shù)據(jù)一致性帶來了一定的挑戰(zhàn),但是由于分布式理論的發(fā)展與實踐,為我們解決分布式系統(tǒng)提供了理論依據(jù)。

分布式系統(tǒng)數(shù)據(jù)一致性的保證的關鍵點就在于如何實現(xiàn)和單系統(tǒng)一樣的事務控制,在單點系統(tǒng)階段,數(shù)據(jù)的一致性通過數(shù)據(jù)庫本身的機制進行保證。但是在分布式中臺系統(tǒng)中,數(shù)據(jù)一致性需要借助于外部的力量進行保證。

當下已經(jīng)有較為成熟的數(shù)據(jù)一致性解決方案了,下面我們來具體分析下各個解決方案,我們按照分布式系統(tǒng)是否強調數(shù)據(jù)的強一致性,我們可以將分布式事務分為剛性事務以及柔性事務。

1、剛性事務

所謂的剛性事務就是追求數(shù)據(jù)的強一致性,必須滿足數(shù)據(jù)庫事務的 ACID 特性。典型的剛性事務解決方案就是 XA 模型。它通過引入一個事務協(xié)調者的角色,站在全局的角度來看分布式事務,將各個子域合并為一個大的分布式事務來實現(xiàn)數(shù)據(jù)的一致性。

但是在實際的高并發(fā)場景下基本不會使用這樣的分布式解決方案,主要原因有以下幾點,我們以 XA 模型中最常見的兩階段提交的方案來說明其存在的不足之處。

(1)單點故障問題:由于引入了分布式事務的全局協(xié)調者的角色,那么如果一旦全局協(xié)調者產生故障,那么各個子事務參與者并不能獲取事務執(zhí)行結果狀態(tài),導致子事務阻塞,因此我們需要花費很大精力去保證事務協(xié)調者的高可用。

(2)性能問題:在大型分布式系統(tǒng)高并發(fā)場景下,由于參與分布式事務的 RM 過多,因此網(wǎng)絡通信次數(shù)、重試以及通信時間都會增加,導致可能的阻塞時間也會變長,從而降低了整個系統(tǒng)的吞吐狀況。

2、柔性事務

既然剛性事務在高并發(fā)場景下存在上述的問題,那么有沒有更好的數(shù)據(jù)一致性解決方案呢?這時候柔性分布式事務就派上用場了。柔性事務尊屬分布式事務的 BASE 理論,它允許一段時間內的系統(tǒng)之間數(shù)據(jù)的不一致,但是在最終狀態(tài)下需要保證事務的一致性。

(1)TCC 模式

所謂 TCC 模式即為 Try-Confirm-Cancel,它是二階段提交的一種實現(xiàn)方式。它包含的主要操作如下所示:

**Try:**嘗試執(zhí)行業(yè)務,但是實際并沒有真正執(zhí)行,只是進行數(shù)據(jù)檢查,鎖定業(yè)務資源,便于后續(xù)業(yè)務執(zhí)行需要

**Confirm:**執(zhí)行具體的業(yè)務操作,使用之前階段預留的業(yè)務資源數(shù)據(jù)

**Cancel:**如果在 try 階段某個事務執(zhí)行失敗,則取消之前的業(yè)務操作

Try 階段:

這個階段主要實現(xiàn)嘗試執(zhí)行對應的業(yè)務,可以理解為一種預備執(zhí)行的狀態(tài)。因為在完成業(yè)務流程之前,并不知道各個業(yè)務節(jié)點或者可以理解為子事務是否可以正常執(zhí)行,因此嘗試在各個子事務去預先執(zhí)行,看看能不能正常處理。

回到我們這個購買 13 香的例子當中,訂單中心首先將訂單狀態(tài)修改為 UPDATING 狀態(tài),而不是 COMPLETED 狀態(tài)。庫存中心可以將 13 香的庫存鎖住,積分中心同樣可以進行預增加積分。

在這里插入圖片描述

Confirm 階段:

如果有幸進入這個階段,說明前期的 try 階段都已經(jīng)處理成功了,即為訂單的狀態(tài)成功變更為 UPDATING 狀態(tài),庫存中的訂單數(shù)據(jù)量已經(jīng)被鎖定,用戶對應的購物積分已經(jīng)預先增加了,這三個步驟都已經(jīng)完美實現(xiàn)了。對應的 TCC 框架已經(jīng)感知到各個 Try 階段的執(zhí)行結果,因此在執(zhí)行 Confirm 時候需要執(zhí)行對應服務提供的 Confirm 接口去完成實際的數(shù)據(jù)提交。

TCC 框架需要分別調用各個服務的確認提交接口完成對應的本地事務提交。訂單服務需要將訂單狀態(tài)修改為訂單完成狀態(tài)、 庫存服務需要將將庫存進行真實的扣減,用戶積分服務為用戶增加相應的用戶積分。

在這里插入圖片描述

Cancel 階段:

如果不幸走到這個階段,無論在哪個階段都需要對之前執(zhí)行的所有擦偶作執(zhí)行回滾,恢復原有數(shù)據(jù)。如在執(zhí)行到積分添加的過程中出現(xiàn)異常,那么代表這個分支事務在執(zhí)行中出現(xiàn)了問題,無法完成正常的事務提交。因此為了保證數(shù)據(jù)的一致性,需要將之前的數(shù)據(jù)進行回滾操作。

在這里插入圖片描述

在整個 TCC 處理過程之中,還有一件事情需要特別注意,那就是為了保證業(yè)務的成功率,各個業(yè)務服務向 TCC 框架進行 confirm 以及 TCC 向各個業(yè)務服務進行 confirm 以及 cancel 的時候都需要進行異常重試,以保證執(zhí)行的成功率,因此對應的業(yè)務服務需要進行冪等處理,防止重試導致的重復操作。

可以看得出來,TCC 模式下的微服務需要業(yè)務代碼重度耦合,實際編碼的體感很不好,需要借助于外部的 TCC 框架,同時需要在業(yè)務代碼中增加 Try、Cancel 處理流程需要的接口。上述的 TCC 解決方案,需要在用戶執(zhí)行完下單操作之后依次執(zhí)行訂單生成接口、庫存扣減接口以及用戶積分接口來完成整體的業(yè)務操作,但是在實際的業(yè)務場景中,我們大概率不會這么同步調用多個接口來完成具體業(yè)務,下面我們看看另外一種分布式數(shù)據(jù)一致性解決方案。

(2)可靠消息最終一致性

在實際的平臺中,我們通常使用消息事件來解決各個微服務之間的耦合問題。我們結合之前的購買 13 香的實際案例來進行說明,可靠消息的事務模型實際上就是基于事件驅動架構,當用戶在購買 13 香之后,創(chuàng)建了 13 香的訂單并完成支付,向消息中間件發(fā)送訂單已支付事件消息,訂閱了訂單支付支付之間消息的庫存服務、積分服務等,接收到對應的訂單支付消息之后,執(zhí)行其對應的業(yè)務流程,如扣減庫存以及增加用戶積分等。

從上述描述中我們可以看出來,可靠消息最終一致性的方案中,消息的可靠投遞是一切后續(xù)業(yè)務的重要前提,同時需要避免消息的重復消費,因此對應監(jiān)聽消息的服務的業(yè)務接口需要實現(xiàn)冪等性。我們來看如下的偽代碼。

public void generateOrder() {

	try{
    boolean result = orderRepo.saveOrder(orderMpdel);
    
    if(result) {
      mqSender.sendMessage(orderModel);
    }
      
    
  } catch(Exception e) {
    rollback();
  }


}

在上述代碼中,無論是本地訂單數(shù)據(jù)保存(本地事務)處理失敗還是異步消息發(fā)送異常,我們都會進行訂單數(shù)據(jù)回滾,這代碼看上去沒有什么毛病,但是我們再仔細分析下是不是真的沒有什么問題嗎?

在這里插入圖片描述

由于引入了消息中間件,服務之間的調用不再是依次的同步調用,各自服務通過消費對應的訂單消息來實現(xiàn)各自的業(yè)務。當用戶進行下單操作后,訂單服務會生成對應的訂單信息,而后發(fā)送訂單生成消息。但是由于是分布式系統(tǒng),受網(wǎng)絡等因素的影響,有可能出現(xiàn)消息發(fā)送完成后訂單服務未接收到消息中間件返回的響應信息,因此訂單服務將之前的訂單數(shù)據(jù)進行了回滾,但是積分服務已經(jīng)將 MQ 中的訂單信息進行了消費,增加了用戶積分。這就造成了訂單與積分數(shù)據(jù)不一致的情況。 另外如果在訂單生成之后,訂單服務掛掉了無法正常投遞消息也會造成數(shù)據(jù)不一致的情況。

a、本地消息表

通過本地消息表的方式將分布式事務拆解為本地事務的實現(xiàn),如下圖所示,將訂單生成以及消息記錄表包裹在一個本地事務中,生成訂單信息后同時在本地消息表中插入一條訂單消息發(fā)送記錄用以記錄消息發(fā)送的狀態(tài)。如果消息發(fā)送失敗則記錄狀態(tài),訂單服務進行重試發(fā)送,超過重試次數(shù)后可以由定時服務進行定時掃描本地未完成狀態(tài)的消息進行重新發(fā)行消息,以保證消息的正常投遞。

當消息到達 MQ 之后,如果 MQ 進行了正常的響應則業(yè)務可以繼續(xù)。但是如果 MQ 未正常響應,則訂單服務認為 MQ 未能正常接收消息需要不斷進行重試。

MQ 接收到消息并進行持久化后,則響應訂單服務說我這里已經(jīng)接收到你的訂單消息了,接下來的事情就交給我我吧,此時訂單服務不再進行消息發(fā)送重試,本地消息表中的消息狀態(tài)為已發(fā)送。

消息發(fā)送成功后,積分服務將會消費對應的訂單消息,但是如果積分服務在執(zhí)行本地積分服務失敗后需要通知訂單服務將原來的訂單信息進行回滾。

在這里插入圖片描述

b、事務消息

關于事務消息,將在另外一篇文章詳細介紹,主要的思想是借助于 RocketMQ 的事務消息機制,將分布式事務轉換為兩階段提交的解決方案,從而實現(xiàn)依托于消息中間件的事務一致性解決方案。

總結

本文以最常見的電商購物案例為實際背景,圍繞如何實現(xiàn)業(yè)務中臺的數(shù)據(jù)一致性進行了詳細的說明,分別從分布式系統(tǒng)數(shù)據(jù)一致性問題產生的背景、相關的分布式事務理論以及基于理論之上產生的相應的解決方案總結了業(yè)務中臺的數(shù)據(jù)一致性的解決方案。重點闡述了柔分布式事務解決方案在業(yè)務中臺數(shù)據(jù)一致性實踐中的應用。

到此這篇關于Java業(yè)務中臺確保數(shù)據(jù)一致性的解決方案的文章就介紹到這了,更多相關Java 數(shù)據(jù)一致性內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring中使用自定義ThreadLocal存儲導致的坑及解決

    Spring中使用自定義ThreadLocal存儲導致的坑及解決

    這篇文章主要介紹了Spring中使用自定義ThreadLocal存儲導致的坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • IDEA高效使用設置指南

    IDEA高效使用設置指南

    本文主要為大家介紹了關于IDEA高效的設置指南,其中包含必備的一些插件推薦以及主題優(yōu)化還有IDEA源碼的閱讀技巧,干貨滿滿,有需要的朋友可以借鑒參考下
    2022-01-01
  • Java中map遍歷方式的選擇問題詳解

    Java中map遍歷方式的選擇問題詳解

    這篇文章主要介紹了Java中map遍歷方式的選擇問題的相關內容,小編覺得挺不錯的,在則里分享給大家,需要的朋友可以參考下。
    2017-10-10
  • Spring Boot構建框架詳解

    Spring Boot構建框架詳解

    這篇文章主要為大家詳細介紹了Spring Boot構建框架的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Java通過try釋放資源的方法

    Java通過try釋放資源的方法

    這篇文章主要介紹了Java通過try釋放資源的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • Java實現(xiàn)上傳文件圖片到指定服務器目錄

    Java實現(xiàn)上傳文件圖片到指定服務器目錄

    本文通過實例代碼給大家介紹了java上傳文件圖片到指定服務器目錄的相關知識,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-06-06
  • MyBatis-plus報錯Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的解決方法

    MyBatis-plus報錯Property ‘sqlSessionFactory‘ or 

    這篇文章主要給大家介紹了MyBatis-plus 報錯 Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的兩種解決方法,如果遇到相同問題的朋友可以參考借鑒一下
    2023-12-12
  • spring初始化方法的執(zhí)行順序及其原理分析

    spring初始化方法的執(zhí)行順序及其原理分析

    這篇文章主要介紹了spring初始化方法的執(zhí)行順序及其原理分析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java??常見位邏輯運算符梳理

    java??常見位邏輯運算符梳理

    這篇文章主要介紹了java常見位邏輯運算符梳理,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參一下下面文章詳細內容
    2022-08-08
  • Jenkins一鍵打包部署SpringBoot應用

    Jenkins一鍵打包部署SpringBoot應用

    本文主要介紹了Jenkins一鍵打包部署SpringBoot應用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-01-01

最新評論