動態

詳情 返回 返回

【Spring開發】SpringCloud服務端高級框架第7篇:分佈式事務,0.學習目標【附代碼文檔】 - 動態 詳情

🏆🏆🏆教程全知識點簡介:微服務保護、服務異步通信、消息中間件部署、分佈式事務、搜索引擎、緩存、數據同步以及相關組件的安裝配置等技術要點。在微服務保護方面,介紹了 Sentinel 的基礎知識,包括雪崩問題、超時處理、艙壁模式、斷路器機制,以及不同服務保護技術的對比;講解了流量控制(簇點鏈路、流控模式、熱點參數限流)、隔離與降級(FeignClient 整合 Sentinel、線程隔離)、授權規則(自定義異常結果)及規則持久化(規則管理模式與 pull 模式),並演示了基於 Nacos 的規則持久化改造。服務異步通信部分探討了消息可靠性(生產者消息確認、Return 回調、ConfirmCallback)、死信交換機、TTL 隊列等高級應用。RabbitMQ 部署指南涵蓋了單機部署、DelayExchange 插件安裝、集羣部署、鏡像模式等內容。分佈式事務部分介紹了 CAP 定理、BASE 理論、常見解決方案,Seata 的基礎與部署(TC 服務部署、Nacos 配置、數據庫表創建)、多種事務模式(XA 模式及優缺點、四種模式對比)和高可用架構。分佈式搜索引擎章節講解了 Elasticsearch 的原理(ELK 技術棧、倒排索引)、索引庫與文檔操作、RestAPI 與 RestClient 的使用、排序與高亮、酒店搜索案例(分頁、競價排名、ad標記、算分函數)、自動補全、數據同步(同步調用、監聽 binlog)、集羣搭建與腦裂問題、分片存儲測試,以及單點 ES、Kibana、IK 分詞器安裝。緩存部分介紹了 Redis 持久化(RDB 與 AOF 對比)、單機安裝 Redis、Redis 集羣、多級緩存(JVM 進程緩存、Caffeine)、請求參數處理、Tomcat 查詢、HTTP 工具與 CJSON 工具類、Redis 緩存查詢。數據同步與網關部分包括 Canal 安裝(開啓 MySQL 主從、設置權限)、OpenResty 安裝(開發庫、目錄結構、環境變量配置)及運行流程。

<!-- start:bj1 -->

📚📚👉👉👉本站這篇博客:   https://segmentfault.com/a/1190000047239876    中查看

📚📚👉👉👉本站這篇博客:   https://segmentfault.com/a/1190000047239876    中查看

<!-- end:bj1 -->

✨ 本教程項目亮點

🧠 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
💻 全技術鏈覆蓋:完整前後端技術棧,涵蓋開發必備技能
🚀 從零到實戰:適合 0 基礎入門到提升,循序漸進掌握核心能力
📚 豐富文檔與代碼示例:涵蓋多種場景,可運行、可複用
🛠 工作與學習雙參考:不僅適合系統化學習,更可作為日常開發中的查閲手冊
🧩 模塊化知識結構:按知識點分章節,便於快速定位和複習
📈 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考

🎯🎯🎯全教程總章節


🚀🚀🚀本篇主要內容

分佈式事務

0.學習目標

1.分佈式事務問題

1.1.本地事務

本地事務,也就是傳統的單機事務。在傳統數據庫事務中,必須要滿足四個原則:

1.2.分佈式事務

分佈式事務,就是指不是在單個服務或單個數據庫架構下,產生的事務,例如:

  • 跨數據源的分佈式事務
  • 跨服務的分佈式事務
  • 綜合情況

在數據庫水平拆分、服務垂直拆分之後,一個業務操作通常要跨多個數據庫、服務才能完成。例如電商行業中比較常見的下單付款案例,包括下面幾個行為:

  • 創建新訂order單
  • 扣減產品庫存
  • 從用户賬户餘額扣除金額

完成上面的操作需要訪問三個不同的微服務和三個不同的數據庫。

訂order單的創建、庫存的扣減、賬户扣款在每一個服務和數據庫內是一個本地事務,可以保證ACID原則。

但是當 把三件事情看做一個"業務",要滿足保證“業務”的原子性,要麼所有操作全部成功,要麼全部失敗,不允許出現部分成功部分失敗的現象,這就是分佈式系統下的事務了。

此時ACID難以滿足,這是分佈式事務要解決的問題

1.3.演示分佈式事務問題

通過一個案例來演示分佈式事務的問題:

1)創建數據庫,名為seata_demo,然後導入課前資料提供的SQL文件:

2)導入課前資料提供的微服務:

微服務結構如下:

其中:

seata-demo:父工程,負責管理項目依賴

  • account-service:賬户服務,負責管理用户的資金賬户。提供扣減餘額的接口
  • storage-service:庫存服務,負責管理產品庫存。提供扣減庫存的接口
  • order-service:訂order單服務,負責管理訂order單。創建訂order單時,需要調用account-service和storage-service

3)啓動nacos、所有微服務

4)測試下單功能,發出Post請求:

請求如下:

curl --location --request POST 'http://localhost:8082/order?userId=user202103032042012&commodityCode=100202003032041&count=20&money=200'

如圖:

測試發現,當庫存不足時,如果餘額已經扣減,並不會回滾,出現了分佈式事務問題。

2.理論基礎

解決分佈式事務問題,需要一些分佈式系統的基礎知識作為理論指導。

2.1.CAP定理

1998年,加州大學的計算機科學家 Eric Brewer 提出,分佈式系統有三個指標。

  • Consistency(一致性)
  • Availability(可用性)
  • Partition tolerance (分區容錯性)

它們的第一個字母分別是 C、A、P。

Eric Brewer 説,這三個指標不可能同時做到。這個結論就叫做 CAP 定理。

2.1.1.一致性

Consistency(一致性):用户訪問分佈式系統中的任意節點,得到的數據必須一致。

比如現在包含兩個節點,其中的初始數據是一致的:

當 修改其中一個節點的數據時,兩者的數據產生了差異:

要想保住一致性,就必須實現node01 到 node02的數據 同步:

2.1.2.可用性

Availability (可用性):用户訪問集羣中的任意健康節點,必須能得到響應,而不是超時或拒絕。

如圖,有三個節點的集羣,訪問任何一個都可以及時得到響應:

當有部分節點因為網絡故障或其它原因無法訪問時,代表節點不可用:

2.1.3.分區容錯

Partition(分區):因為網絡故障或其它原因導致分佈式系統中的部分節點與其它節點失去連接,形成獨立分區。

Tolerance(容錯):在集羣出現分區時,整個系統也要持續對外提供服務

2.1.4.矛盾

在分佈式系統中,系統間的網絡不能100%保證健康,一定會有故障的時候,而服務有必須對外保證服務。因此Partition Tolerance不可避免。

Spring AMQP 文檔

當節點接收到新的數據變更時,就會出現問題了:

如果此時要保證一致性,就必須等待網絡恢復,完成數據同步後,整個集羣才對外提供服務,服務處於阻塞狀態,不可用。

如果此時要保證可用性,就不能等待網絡恢復,那node01、node02與node03之間就會出現數據不一致。

也就是説,在P一定會出現的情況下,A和C之間只能實現一個。

2.2.BASE理論

BASE理論是對CAP的一種解決思路,包含三個思想:

  • Basically Available (基本可用):分佈式系統在出現故障時,允許損失部分可用性,即保證核心可用。
  • Soft State(軟狀態):在一定時間內,允許出現中間狀態,比如臨時的不一致狀態。
  • Eventually Consistent(最終一致性):雖然無法保證強一致性,但是在軟狀態結束後,最終達到數據一致。

2.3.解決分佈式事務的思路

分佈式事務最大的問題是各個子事務的一致性問題,因此可以借鑑CAP定理和BASE理論,有兩種解決思路:

  • AP模式:各子事務分別執行和提交,允許出現結果不一致,然後採用彌補措施恢復數據即可,實現最終一致。
  • CP模式:各個子事務執行後互相等待,同時提交,同時回滾,達成強一致。但事務等待過程中,處於弱可用狀態。

但不管是哪一種模式,都需要在子系統事務之間互相通訊,協調事務狀態,也就是需要一個事務協調者(TC)

這裏的子系統事務,稱為分支事務;有關聯的各個分支事務在一起稱為全局事務

3.初識Seata

Programiz Java

Seata是 2019 年 1 月份螞蟻金服和阿里巴巴共同開源的分佈式事務解決方案。致力於提供高性能和簡單易用的分佈式事務服務,為用户打造一站式的分佈式解決方案。

官網地址:http://seata.io/,其中的文檔、播客中提供了大量的使用説明、源碼分析。

3.1.Seata的架構

Seata事務管理中有三個重要的角色:

  • TC (Transaction Coordinator) - 事務協調者:維護全局和分支事務的狀態,協調全局事務提交或回滾。
  • TM (Transaction Manager) - 事務管理器:定義全局事務的範圍、開始全局事務、提交或回滾全局事務。
  • RM (Resource Manager) - 資源管理器:管理分支事務處理的資源,與TC交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。

整體的架構如圖:

EclipseLink 文檔

Seata基於上述架構提供了四種不同的分佈式事務解決方案:

  • XA模式:強一致性分階段事務模式,犧牲了一定的可用性,無業務侵入
  • TCC模式:最終一致的分階段事務模式,有業務侵入
  • AT模式:最終一致的分階段事務模式,無業務侵入,也是Seata的默認模式
  • SAGA模式:長事務模式,有業務侵入

無論哪種方案,都離不開TC,也就是事務的協調者。

3.2.部署TC服務

參考課前資料提供的文檔《 seata的部署和集成.md 》:

3.3.微服務集成Seata

以order-service為例來演示。

3.3.1.引入依賴

首先,在order-service中引入依賴:

Vavr 函數式庫

Java Code Geeks

Spring Security 文檔

<!--seata-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <exclusions>
        <!--版本較低,1.3.0,因此排除--> 
        <exclusion>
            <artifactId>seata-spring-boot-starter</artifactId>
            <groupId>io.seata</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <!--seata starter 採用1.4.2版本-->
    <version>${seata.version}</version>
</dependency>

3.3.2.配置TC地址

在order-service中的application.yml中,配置TC服務信息,通過註冊中心nacos,結合服務名稱獲取TC地址:

WireMock 文檔

seata:
  registry: # TC服務註冊中心的配置,微服務根據這些信息去註冊中心獲取tc服務地址
    type: nacos # 註冊中心類型 nacos
    nacos:
      server-addr: 127.0.0.1:8848 # nacos地址
      namespace: "" # namespace,默認為空
      group: DEFAULT_GROUP # 分組,默認是DEFAULT_GROUP
      application: seata-tc-server # seata服務名稱
      username: nacos
      password: nacos
  tx-service-group: seata-demo # 事務組名稱
  service:
    vgroup-mapping: # 事務組與cluster的映射關係
      seata-demo: SH

微服務如何根據這些配置尋找TC的地址呢?

知道註冊到Nacos中的微服務,確定一個具體實例需要四個信息:

  • namespace:命名空間
  • group:分組
  • application:服務名
  • cluster:集羣名

以上四個信息,在剛才的yaml文件中都能找到:

namespace為空,就是默認的public

結合起來,TC服務的信息就是:public@DEFAULT_GROUP@seata-tc-server@SH,這樣就能確定TC服務集羣了。然後就可以去Nacos拉取對應的實例信息了。

3.3.3.其它服務

其它兩個微服務也都參考order-service的步驟來做,完全一樣。

4.動手實踐

下面 就一起學習下Seata中的四種不同的事務模式。

4.1.XA模式

XA 規範 是 X/Open 組織定義的分佈式事務處理(DTP,Distributed Transaction Processing)標準,XA 規範 描述了全局的TM與局部的RM之間的接口,幾乎所有主流的數據庫都對 XA 規範 提供了支持。

4.1.1.兩階段提交

XA是規範,目前主流數據庫都實現了這種規範,實現的原理都是基於兩階段提交。

正常情況:

Javadoc 工具

異常情況:

Javatpoint 教程

一階段:

  • 事務協調者通知每個事物參與者執行本地事務
  • 本地事務執行完成後報告事務執行狀態給事務協調者,此時事務不提交,繼續持有數據庫鎖

二階段:

  • 事務協調者基於一階段的報告來判斷下一步操作

    • 如果一階段都成功,則通知所有事務參與者,提交事務
    • 如果一階段任意一個參與者失敗,則通知所有事務參與者回滾事務

4.1.2.Seata的XA模型

Seata對原始的XA模式做了簡單的封裝和改造,以適應自己的事務模型,基本架構如圖:

RM一階段的工作:

​ ① 註冊分支事務到TC

​ ② 執行分支業務sql但不提交

​ ③ 報告執行狀態到TC

TC二階段的工作:

  • TC檢測各分支事務執行狀態

    a.如果都成功,通知所有RM提交事務

    b.如果有失敗,通知所有RM回滾事務

RM二階段的工作:

  • 接收TC指令,提交或回滾事務

4.1.3.優缺點

XA模式的優點是什麼?

Maven 生命週期

  • 事務的強一致性,滿足ACID原則。
  • 常用數據庫都支持,實現簡單,並且沒有代碼侵入

XA模式的缺點是什麼?

  • 因為一階段

Add a new 評論

Some HTML is okay.