LCN解決分散式事務原理解析+項目實戰(原創精華版)

来源:https://www.cnblogs.com/lmyupupblogs/archive/2020/03/19/12499815.html
-Advertisement-
Play Games

寫在前面: 由於工作需要,公司的微服務項目需解決分散式事務的問題,且由我進行分散式事務框架搭建和整合工作。 那麼藉此機會好好的將解決分散式事務的內容進行整理一下。這邊公司分散式事務框架選型是LCN框架(以後肯定會升級成seata)。 我整理的大綱如下: 1 CAP定律和BASE理論 有人問,為什麼需 ...


寫在前面:

由於工作需要,公司的微服務項目需解決分散式事務的問題,且由我進行分散式事務框架搭建和整合工作。

那麼藉此機會好好的將解決分散式事務的內容進行整理一下。這邊公司分散式事務框架選型是LCN框架(以後肯定會升級成seata)。

我整理的大綱如下:

1 CAP定律和BASE理論

  有人問,為什麼需要瞭解這個,這個其實是分散式事務基於的理論依據,所以需要瞭解一下。

1.1 CAP定律

  這個定理的內容是指的是在一個分散式系統中、Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。

(一)一致性(C

  在分散式系統中的所有數據備份,在同一時刻是否同樣的值。(等同於所有節點訪問同一份最新的數據副本)

(二)可用性(A

  在集群中一部分節點故障後,集群整體是否還能響應客戶端的讀寫請求。(對數據更新具備高可用性)

(三)分區容錯性(P

  以實際效果而言,分區相當於對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味著發生了分區的情況,必須就當前操作在CA之間做出選擇。

(四)總結一下

  以上可以知道分區容錯性(P)主要代表網路波動產生的錯誤,這是不可避免的,且這個三個模式不可兼得,所以目前就只有兩種模式:CPAP模式。

  其中CP表示遵循一致性原則,但不能保證高可用性,其中zookeeper作為註冊中心就是採用CP模式,因為zookeeper有過半節點不可以的話整個zookeeper將不可用。

  AP表示遵循於可用性原則,例如Eureka作為註冊中心用的是AP模式,因為其為去中心化,採用你中有我我中有你的相互註冊方式,只要集群中有一個節點可以使用,整個eureka服務就是可用的,但可能會出現短暫的數據不一致問題。

1.2 BASE理論

BASEBasically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent(最終一致性)三個短語的縮寫。BASE理論是對CAP中一致性和可用性權衡的結果,其來源於對大規模互聯網系統分散式實踐的總結, 是基於CAP定理逐步演化而來的。BASE理論的核心思想是:即使無法做到強一致性,但每個應用都可以根據自身業務特點,採用適當的方式來使系統達到最終一致性。

(一)基本可用

  基本可用是指分散式系統在出現不可預知故障的時候,允許損失部分可用性註意,這絕不等價於系統不可用。

  比如:響應時間上的損失。正常情況下,一個線上搜索引擎需要在0.5秒之內返回給用戶相應的查詢結果,但由於出現故障,查詢結果的響應時間增加了1~2

  系統功能上的損失:正常情況下,在一個電子商務網站上進行購物的時候,消費者幾乎能夠順利完成每一筆訂單,但是在一些節日大促購物高峰的時候,由於消費者的購物行為激增,為了保護購物系統的穩定性,部分消費者可能會被引導到一個降級頁面

(二)軟狀態

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

(三)最終一致性

  最終一致性強調的是所有的數據副本,在經過一段時間的同步之後,最終都能夠達到一個一致的狀態。因此,最終一致性的本質是需要系統保證最終數據能夠達到一致,而不需要實時保證系統數據的強一致性。

2 瞭解分散式事務

2.1 分散式事務產生的背景 

  在分散式產生之前,互聯網公司的項目都是傳統的單體項目,整個項目都共用了一個數據源,那麼進行業務執行對資料庫進行操作的時候,不會產生這種事務不一致問題,因為是同一個數據源用的一個本地事務。

  但隨著我們架構的演變,從單體架構到分散式架構到SOA架構項目再到如今公司採用的微服務架構,我們對服務進行了業務拆分,那麼數據源也被拆分,一般微服務項目是一個服務對應一個數據源。

  那麼在這種架構下,每個服務都有自己獨立的數據源有自己的本地事務,從而便會產生分散式事務,可能造成服務間數據不一致問題。

2.2 不同架構體系下解決事務的問題

(一)單體架構(單數據源)

  在單體的項目中,多個不同業務邏輯都是在同一個數據源中實現事務管理,是不存在分散式事務的問題,因為同一數據源的情況下都是採用事務管理器,相當於每個事務管理器對應一個數據源。

(一)單體架構(多數據源)

  在單體的項目中,有多個不同的數據源,每個數據源中都有自己獨立的事務管理器,互不影響,那麼這時候也會存在多數據源事務管理:解決方案jta+ Atomikos

(一)分散式/微服務架構

  在分散式/微服務架構,每個服務都有自己獨立的數據源和事務管理器,那麼在這種情況下如果有業務要進行RPC遠程調用的時候,那就必然可能產生分散式事務。目前主要解決方案有:MQLCNSeata等方案

LCN解決分散式事務

3.1 瞭解LCN

3.1.1 LCN背景

  LCN框架在20176月份發佈第一個版本,從開始的1.0,已經發展到了5.0版本。

  LCN名稱是由早期版本的LCN框架命名,在設計框架之初的1.0 ~ 2.0的版本時框架設計的步驟是如下,各取其首字母得來的LCN命名。

  5.0以後由於框架相容了LCNTCCTXC三種事務模式,為了避免區分LCN模式,特此將LCN分散式事務改名為TX-LCN分散式事務框架。

3.1.2 LCN定位

TX-LCN定位於一款事務協調性框架,框架其本身並不操作事務,而是基於對事務的協調從而達到事務一致性的效果。(LCN不生產事務,它只是事務的搬運工...woc這有點像農夫山泉的文案)

3.2 LCN分散式事務原理(自己理解的,白話文通俗易懂)

(上圖來源官網) 

  1) 首先我們的lcn協調者(TM)會和lcn客戶端(TC)通過引入的netty一直保持著長連接(持續監聽)。

  2) 當請求的發起方(調用方)進入介面業務之前,會通過AOP技術進到@LcnTransaction註解中LCN協調者那邊生成註冊一個全局的事務組IdgroupId)。

  3) 當發起方(調用方)通過rpc調用參與方(被調用方)的時候,lcn重寫了Feign客戶端,會從ThreadLocal中拿到該事務組IdgroupId),並將該事務組Id設置到請求頭中。

  4) 參與方(被調用方)在請求頭中獲取到了這個groupId的時候,lcn會標識該服務為參與方並加入到該事務組,並會被lcn代理數據源,當該服務業務邏輯執行完成後,進行數據源的假關閉,並不會真正的提交或回滾當前服務的事務。

  5) 當發起方執行完全部業務邏輯的時候,如果無異常會告知lcn協調者,lcn協調者再分別告訴該請求鏈上的所有參與方可以提交了,再進行真正的提交。若發起方調用完參與方後報錯了,也會告知lcn協調者,lcn協調者再告知所有的參與方進行真正的回滾操作,這樣就解決了分散式事務的問題。

3.3 LCN本地環境部署

3.3.1 本地部署註冊中心

  註冊中心是微服務中最為重要的一個組件,提供了服務間在調用時需要的一些ip和埠等列表信息。

  我這邊採用nacos作為註冊中心,具體如何一分鐘快速搭建本地nacos可參見:https://nacos.io/zh-cn/docs/quick-start.html 註冊中心的部署略過不做詳細的說明。搭建好nacos後,訪問127.0.0.1:8848/nacos進行訪問(賬號密碼預設為nacos),出現如下界面即完成了nacos本地的搭建。

 

3.3.2 本地部署協調者TM環境 

  在部署TX-LCN中有遇到問題或想查看部署詳細的操作可以訪問如下地址:http://www.txlcn.org/zh-cn/docs/start.html 

  1) 我們要去github中先將tx-lcn的源碼下載下來,這邊我們選擇的是5.0.2的版本,github下載源碼地址:https://github.com/codingapi/tx-lcn/releases

  

  2) 創建相應的資料庫表,先創建MySQL資料庫, 名稱為: tx-manager,再創建資料庫表t_tx_exception

 

CREATE TABLE `t_tx_exception`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `group_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `unit_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `mod_id` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `transaction_state` tinyint(4) NULL DEFAULT NULL,
  `registrar` tinyint(4) NULL DEFAULT NULL,
  `remark` varchar(4096) NULL DEFAULT  NULL,
  `ex_state` tinyint(4) NULL DEFAULT NULL COMMENT '0 未解決 1已解決',
  `create_time` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; 

  3) 打開我們下好的源碼,找到txlcn-tm模塊,修改其配置文件application.properties具體修改的內容根據自己業務而定,官方也有相應配置內容,但需要註意首次運行要將配置文件的這段設置為createspring.jpa.hibernate.ddl-auto=create

 

  4) 準備將txlcn-tm模塊打包成jar,先執行打包命令: mvn clean package -Dmaven.test.skip=true 打包完成後可以在模塊中看到出現了jar包。

  5) 開始對jar包進行運行,進入到target目錄,執行命令啟動jar包:java -jar txlcn-tm-5.0.2.RELEASE.jar

  6) 運行成功後可以看到tomcat啟動成功。

 

  7) 訪問控制台的埠為7919,預設密碼codingapi

 

 

 

  至此,TM部署並啟動完成。

3.3.3 本地配置客戶端TC環境

  TC就是我們的客戶端,也就是我們的微服務,配置相對簡單如下: 

  1) 引入相關依賴,其中一個是lcn核心包,一個是建立長連接的netty包。

<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-tc</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.codingapi.txlcn</groupId>
    <artifactId>txlcn-txmsg-netty</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

  2) 配置yml文件,設置服務連接到lcn服務。(註意下lcn控制台是7970,這個8070lcn通訊埠號

tx-lcn:
  client:
    manager-address: 127.0.0.1:8070
  logger:
    enabled: true

  3) 引入依賴並配置好yml文件後,在服務的啟動類上添加@EnableDistributedTransaction註解,開啟分散式事務。

  4) 在業務的方法上面添加註解@LcnTransaction@Transactional,如下圖

  5) 做好這些配置後,開始啟動項目,啟動成功項目後可以在lcn控制台看到相應的服務列表,能夠看到則說明服務已經實現了對lcn事務協調者管理器的註冊。

 

  看到服務都能夠成功註冊進TM後,便全部完成TX-LCN本地環境的搭建,後續可以開始測試自己的業務代碼是否解決了分散式事務的問題。 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 學習 Spring Boot "Spring tutorials" | Java Web Development, Spring Cloud Programming tutorials Spring Boot為您提供了Spring Framework的所有功能,而沒有所有的複雜性。立即開始編寫應用。 ...
  • 1. this指針的用處: 一個對象的this指針並不是對象本身的一部分,不會影響sizeof(對象)的結果。 請細品以下概念 this作用域是在類內部,當在類的非靜態成員函數中訪問類的非靜態成員的時候,編譯器會自動將對象本身的地址作為一個隱含參數傳遞給函數。也就是說,即使你沒有寫上this指針,編 ...
  • SpringBoot配置文件 YML YAML (YAML Ain't a Markup Language)YAML不是一種標記語言,通常以.yml為尾碼的文件,是一種直觀的能夠被電腦識別的數據序列化格式,並且容易被人類閱讀,容易和腳本語言交互的,可以被支持YAML庫的不同的編程語言程式導入,一種專 ...
  • 認識Spring boot 什麼是Spring boot Spring Boot makes it easy to create stand alone, production grade Spring based Applications that you can "just run". We t ...
  • https://blog.csdn.net/CeliaTodd/article/details/104977577 spring boot整合redis的過程中,遇到Unable to connect to localhost:6379的異常問題.(redis是在Linux中啟動的)註解:IP地址最 ...
  • C++基礎 學習筆記一:源代碼的格式化 1. 源代碼中的標記與空白 C++中的語句是以分號表示語句的結束。在C++中空格和回車以及製表符均為相同作用,即三者通常可以互相替代。 例如可以將一個簡單的main函數這樣寫: cpp int main(){cout(僅供參考) 上面的兩個例子均可通過編譯但是 ...
  • 首先,我們先通過字面意思來理解... 成員:成員變數、成員函數。 static 修飾成員變數,還有修飾成員函數。 static 聲明為靜態的,稱為靜態成員。不管這個類創建了多少個對象,靜態成員只有一個拷貝,這個拷貝被所有屬於這個類的對象共用。 靜態成員,屬於類 而不是對象。 1.static 修飾成 ...
  • ​當我第一次在項目代碼中看到Stream流的時候,心裡不由得罵了一句“傻X”炫什麼技。當我開始嘗試在代碼中使用Stream時,不由得感嘆真香。 記得以前有朋友聊天說,他在代碼中用了Lambda表達式結果CodeReview的時候老大讓它改了。我在“第三章 Stream流”寫了,“ 簡潔的後果就是,代 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...