主頁 > 軟體設計 > 分布式事務解決方案全決議

分布式事務解決方案全決議

2021-01-24 21:42:04 軟體設計

分布式事務解決方案

對于剛剛接觸分布式系統的伙伴來說,分布式看起來非常高大上、深不可測,目前已有Dubbo、SpringCloud等較好的分布式框架,但分布式事務仍是分布式系統一大痛點,本文結合一些經典博客文章,簡單決議一些常見的分布式事務解決方案,

基礎介紹

事務

事務可以看成是由多個小事件一起組成的一個大事件,這些小事件要么全部成功,則整個事件成功;如果有任意一個事件失敗,則所有事件均宣告失敗,并恢復成事件執行之前的樣子,

本地事務

在單應用開發場景中,較多的是通過關系型資料庫來控制事務,利用資料庫本身的事務特性來實作的,稱為資料庫事務,也可以稱為本地事務,資料庫事務在實作時會將一次事務的所有操作全部納入到一個不可分割的執行單元,該執行單元的所有操作要么全部成功,要么全部失敗,若其中任意操作執行失敗,都將導致整個事務的回滾,

ACID

嚴格意義上的事務實作應該是具備原子性一致性隔離性持久性,簡稱 ACID

  • A(Atomic)原子性:一個事務中所有操作,要么都執行完成,要么全部不執行,不可能出現部分成功部分失敗的情況,
  • C(Consistency)一致性:在事務執行前后,資料庫的一致性約束沒有被破壞,可以理解為資料是滿足完整性約束的,也就是不會存在中間狀態的資料,比如:張三給李四轉 100 元,轉賬前和轉賬后的資料是正確的狀態這叫一致性,如果出現張三轉出 100 元,李四賬戶沒有增加 100 元這就出現了中間狀態的錯誤資料,沒有達到一致性,
  • I(Isolation)隔離性:資料庫中的事務一般都是并發的,隔離性是指并發的兩個事務的執行互不干擾,一個事務不能看到其他事務的運行程序的中間狀態,通過配置事務隔離級別可以比避免臟讀、重復讀問題,
  • D(Durability)持久性:一個事務完成了之后資料就被被持久化到資料庫,之后的其他操作或故障都不會對事務的結果產生影響或者回滾操作,

分布式事務

隨著互聯網技術的發展與資料體量的擴增,軟體系統逐漸由單體應用演變為分布式系統/微服務應用,分布式系統把一個單體應用系統拆分成可獨立部署的多個微服務,很多場景下需要服務之間遠程協作才能完成事務操作,這種分布式系統環境下由不同的服務之間通過網路遠程協作完成事務稱之為分布式事務,分布式系統中實作事務,其實是由多個本地事務組合而成,對于分布式事務而言幾乎滿足不了 ACID,

場景介紹

  • 跨JVM行程產生分布式事務
    典型的場景就是微服務架構:微服務之間通過遠程呼叫完成事務操作,比如:訂單微服務和庫存微服務,下單的同時訂單微服務請求庫存微服務減少庫存,

    跨JVM行程產生分布式事務

  • 跨資料庫實體產生分布式事務
    當單體應用需要訪問多個資料庫(實體)時就會產生分布式事務,比如:用戶資訊和訂單資訊分別在兩個MySQL實體存盤,用戶管理系統洗掉用戶資訊,需要分別洗掉用戶資訊及用戶的訂單資訊,由于用戶資訊和訂單資料分布在不同的資料實體,需要通過不同的資料庫鏈接去操作資料,就會產生分布式事務,

    跨資料庫實體產生分布式事務

  • 多服務訪問同一個資料庫實體
    訂單微服務和庫存微服務即使訪問同一個資料庫也會產生分布式事務,原因就是跨JVM行程,兩個微服務持有了不同的資料庫鏈接進行資料庫操作,此時產生分布式事務,

    多服務訪問同一個資料庫實體

CAP理論

CAP 是 ConsistencyAvailabilityPartition tolerance 三個單詞的縮寫,分別表示一致性可用性磁區容忍性,一個分布式系統最多只能同時滿足一致性、可用性和磁區容錯性這三項中的兩項,

CAP簡介
  • C(Consistency)一致性

一致性是指寫操作后的讀操作可以讀取到最新的資料狀態,當資料分布在多個節點上,從任意結點讀取到的資料都是最新的狀態,即所有節點在同一時間的資料完全一致

A. 從客戶端和服務端來看一致性:

? 1.從客戶端來看,一致性主要指的是多并發訪問時更新過的資料如何獲取的問題,

? 2.從服務端來看,則是更新如何分布到整個系統,以保證資料最終一致,

B. 從一致性的程度來看一致性:

? 1.強一致性:對于關系型資料庫,要求更新過的資料能被后續的訪問都能看到,

? 2.弱一致性:能容忍后續的部分或者全部訪問不到,

? 3.最終一致性:經過一段時間后要求能訪問到更新后的資料,

C. 分布式系統一致性的特點:

? 1.由于存在資料同步的程序,寫操作的回應會有一定的延遲,

? 2.為了保證資料一致性會對資源暫時鎖定,待資料同步完成釋放鎖定資源,

? 3.如果請求資料同步失敗的結點則會回傳錯誤資訊,一定不會回傳舊資料,

  • A(Availability)可用性

可用性指服務一直可用,任何事務操作都可以得到回應結果,且不會出現回應超時或回應錯誤,

  • P(Partition tolerance)磁區容錯性

磁區容錯性指在遇到某節點或網路磁區故障的時候,仍然能夠對外提供滿足一致性和可用性的服務,通常分布式系統的各各結點部署在不同的子網,不可避免的會出現由于網路問題而導致結點之間通信失敗,此時仍可對外提供服務,即為磁區容錯性,磁區容錯性分是布式系統具備的基本能力,

CAP組合

在所有分布式事務場景中不會同時具備 CAP 三個特性,因為在具備了P的前提下C和A是不能共存的,在生產中對分布式事務處理時要根據需求來確定滿足 CAP 的哪兩個方面,

  • AP:滿足可用性和容錯性,舍棄一致性,這也就是意味著你的系統在并發訪問的時候可能會出現資料不一致的情況,這是很多分布式系統設計時的選擇,大多數都是犧牲了一致性,但通常實作 AP 都會保證最終一致性,比如現在的12306搶票,本來你看到的是還有一張票,其實在這個時刻已經被買走了,你填好了資訊準備提交訂單的時候發現系統提示你已售罄,這就是犧牲了一致性,但過一段時間再重新查詢,就會發現無票,這是實作了最終一致性,只要用戶可以接受在一定的時間查到正確的資料即可,
  • CP:滿足一致性和容錯性,舍棄可用性,如果你的系統允許有段時間的訪問失效等問題,這個是可以滿足的,比如多個人并發買票,后臺網路出現故障,你買的時候系統就崩潰了,zookeeper 其實就是追求的強一致,又比如跨行轉賬,一次轉賬請求要等待雙方銀行系統都完成整個事務才算完成,
  • CA:滿足一致性和可用性,舍棄容錯性,不考慮由于網路不通或結點掛掉的問題,那么系統將不是一個標準的分布式系統,涉及分布式的想法就是把功能分開,部署到不同的機器上,最常用的關系型資料就滿足了 CA,
小結

CAP 是一個已經被證實的理論,一個分布式系統最多只能同時滿足:一致性(Consistency)、可用性(Availability)和磁區容忍性(Partition tolerance)這三項中的兩項,它可以作為我們進行架構設計、技術選型的考量標準,對于多數大型互聯網應用的場景,節點多、部署分散,而且現在的集群規模越來越大,所以節點故障、網路故障是常態,而且要保證服務可用性達到 N 個 9(99.99…%),并要達到良好的回應性能來提高用戶體驗,因此一般都會做出如下選擇:保證 P 和 A ,舍棄 C 的強一致性,但保證最終一致性,

BASE理論

BASE理論簡介

BASE 是 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent (最終一致性)三個短語的縮寫,BASE 理論是對 CAP 中 AP 的一個擴展,通過犧牲強一致性來獲得可用性,當出現故障允許部分不可用但要保證核心功能可用,允許資料在一段時間內是不一致的,但最終達到一致狀態,滿足BASE理論的事務,我們稱之為“柔性事務”,

  • 基本可用:分布式系統在出現故障時,允許損失部分可用功能,保證核心功能可用,如電商網站交易付款出現問題了,商品依然可以正常瀏覽,
  • 軟狀態:由于不要求強一致性,所以BASE允許系統中存在中間狀態(也叫軟狀態),這個狀態不影響系統可用性,如訂單的"支付中"、“資料同步中”等狀態,待資料最終一致后狀態改為“成功”狀態,
  • 最終一致:最終一致是指經過一段時間后,所有節點資料都將會達到一致,如訂單的"支付中"狀態,最侄訓變 為“支付成功”或者"支付失敗",使訂單狀態與實際交易結果達成一致,但需要一定時間的延遲、等待,
強一致性和最終一致性

CAP 理論告訴我們一個分布式系統最多只能同時滿足一致性(Consistency)、可用性(Availability)和磁區容忍性(Partition tolerance)這三項中的兩項,其中AP在實際應用中較多,AP 即舍棄一致性,保證可用性和磁區容忍性,但是在實際生產中很多場景都要實作一致性,比如主資料庫向從資料庫同步資料,即使不要一致性,但是最終也要將資料同步成功來保證資料一致,這種一致性和 CAP 中的一致性不同,CAP 中的一致性要求在任何時間查詢每個結點資料都必須一致,它強調的是強一致性,但是最終一致性是允許可以在一段時間內每個結點的資料不一致,但是經過一段時間每個結點的資料必須一致,它強調的是最終資料的一致性,

ACID與BASE
ACID (剛性事務)BASE (柔性事務)
原子性(Atomicity)基本可用(Basically Available)
一致性(Consistency)柔性狀態(Soft state)
隔離性(Isolation)最終一致性(Eventually Consistent)
持久性(Durability)

二階段提交(2PC)

方案簡介

2PC(Two-phase commit protocol),中文叫二階段提交, 2PC 是一種強一致性設計,有事務協調者事務參與者兩個主要角色,事務的發起者為事務協調者,事務的其他執行者為事務參與者,事務協調者協調管理各事務參與者的提交和回滾,,我們可以把事務協調者想象為帶頭大哥,而事務參與者則理解為跟班小弟,由帶頭大哥協調所有跟班小弟的任務執行,

流程分析

準備階段

  1. 事務協調者,給所有事務參與者發送事務內容,并詢問能否提交事務,然后等待參與者回復,
  2. 事務參與者,收到事務內容,開始執行事務,同時將 undoredo 資訊記入事務日志中,但此時事務參與者并不提交事務,
  3. 如果參與者執行事務成功,則給協調者回應 yes ,回答可以進行事務提交;若果參與者事務執行失敗,則給協調者回復 no ,表示不可進行事務提交,

提交階段

事務協調者會等待收到所有事務參與者回應后才會進行下一步操作,且事務協調者在該階段中有超時機制,如果事務協調者收到事務參與者回應資訊為 yes,則向所有事務參與者發送提交(commit)資訊;如果事務協調者收到事務參與者的失敗資訊或超時資訊,則會給所有事務參與者發送回滾(rollback)資訊進行事務回滾,

事務參與者根據來自事務協調者的指令執行提交事務或者回滾事務的操作,并釋放所有事務處理程序中占用的鎖資源(必須在最后階段釋放鎖資源) ,以下是兩種情況具體步驟決議:

  • 當所有事務參與者均回應 yes,則提交事務,如下圖,
  1. 事務協調者向所有事務參與者發出正式提交事務(commit)的請求,
  2. 事務參與者執行事務提交操作,若提交失敗,則會不斷重試,直到提交成功,然后釋放整個事務期間占用的資源,
  3. 所有事務參與者向事務協調者回應提交事務完成的 ack 訊息,
  4. 事務協調者收到所有事務參與者回應的 ack 訊息后,完成提交事務操作,

2PC-正常事務

  • 當準備階段任意一個事務參與者回應 no,則中斷事務,如下圖:
  1. 事務協調者向所有參與者發出回滾(rollback)請求,
  2. 事務參與者使用準備階段中的 undo 資訊執行事務回滾操作,若回滾失敗則會不斷重試,直到所有事務參與者都回滾成功,然后釋放整個事務期間占用的資源,
  3. 各事務參與者向事務協調者回應回滾事務完成的 ack 訊息,
  4. 事務協調者收到所有參與者回應的 ack 訊息后,完成事務中斷操作,

2PC-事務中斷

方案小結

2PC 方案實作起來相對簡單,但實際專案中用的比較少,主要因為以下問題:

  1. 性能較低:所有事務參與者在事務提交階段處于同步阻塞狀態,占用系統資源,效率低,有性能瓶頸,
  2. 可靠性問題:協調者存在單點故障問題,如果事務協調者出現故障,事務參與者將一直處于鎖死狀態,
  3. 資料一致性問題:在提交階段中,如果發生網路波動,部分事務參與者收到了提交訊息,另一些事務參與者沒收到提交訊息,導致了節點之間資料不一致的問題,

三階段提交(3PC)

方案簡介

3PC 也是強一致性,該方案是 2PC 上的改進版本,主要是在事務協調者和事務參與者中都引入超時機制,并 將 2PC 方案的準備階段拆分為2個階段,插入了一個預提交階段(PreCommit),以此來處理2PC的提交階段中事務參與者發生崩潰或錯誤,或者網路波動,導致事務參與者無法知曉是否提交或回滾的不確定狀態所引起的延時問題,

流程分析

準備階段(CanCommit)

事務協調者向事務參與者發送 commit 請求,參與者如果可以提交就 yes 并進入預提交狀態(與2PC中的準備階段不同,參與者不執行事務操作),否則回傳 no 回應,

  1. 事務協調者向所有參與者發出包含事務內容的 canCommit 請求,詢問是否可以提交事務,并等待所有事務參與者的回應,
  2. 事務參與者收到 canCommit 請求后,如果認為可以執行事務操作,則回應 yes 并進入預備狀態,否則反饋 no (與2PC中的準備階段不同,參與者不執行事務操作),

預提交階段(PreCommit)

3PC中的預提交階段和2PC中的準備階段一樣,執行事務但不提交,事務協調者根據準備階段中事務參與者的回應決定是否可以進行事務的預提交操作,

  • 準備階段中所有事務參與者均回應 yes,事務參與者進入預提交狀態,
  1. 事務協調者向所有事務參與者發出 preCommit 請求,進入預提交階段,
  2. 事務參與者收到 preCommit 請求后,執行事務操作,將 undo 和 redo 資訊記入事務日志中(但不提交事務),
  3. 所有事務參與者向事務協調者回應執行事務成功的 ack 訊息或失敗的 no訊息 ,并等待事務協調者發出最終指令,

3PC-預提交回應yes

  • 當準備階段任意一個事務參與者回應 no,或者等待超時后事務協調者尚無法收到所有參與者的回應,則中斷事務
  1. 事務協調者向所有事務參與者發出 abort 請求,
  2. 事務參與者收到事務協調者發出的 abort 請求,或在等待事務協調者的指令程序中出現超時,均會中斷事務,

3PC-預提交回應no

提交階段(DoCommit)

該階段與2PC的提交階段一樣,進行真正的事務提交,進入提交階段后,無論是事務協調者出現問題,或者事務協調者與事務參與者網路出現問題,都會導致事務參與者無法接收到事務協調者發出的 do Commit 請求或 abort 請求,事務參與者都會在等待超時之后,繼續執行事務提交,因為預提交階段的引入起到了一個統一狀態的作用,進入到提交階段則事務參與者默認認為事務應該被提交,

  • 預提交階段中所有事務參與者均回應 ack 訊息,執行真正的事務提交
  1. 如果事務協調者處于作業狀態,則向所有事務參與者發出 do Commit 請求,
  2. 事務參與者收到 do Commit 請求后,會正式執行事務提交操作,并釋放整個事務期間占用的資源,
  3. 所有事務參與者向協調者回應提交事務完成的 ack 訊息,
  4. 事務協調者收到所有事務參與者回應的 ack 訊息后,完成事務提交,

3PC-提交事務

  • 當預提交階段中任意一個事務參與者回應 no,或者在預提交階段中事務協調者無法收到所有參與者的回應,則中斷事務
  1. 如果事務協調者處于作業狀態,向所有事務參與者發出 abort 請求,
  2. 事務參與者使用預提交階段中的 undo 資訊執行回滾操作,并釋放整個事務期間占用的資源,
  3. 所有事務參與者向事務協調者回應回滾事務完成的 ack 訊息,
  4. 事務協調者收到所有事務參與者回應的 ack 訊息后,完成事務中斷,

3PC-事務中斷

方案小結

優點:3PC相比2PC,會先詢問事務參與者是否有條件接事務,不會直接鎖資源,降低了阻塞范圍,在等待超時后事務協調者或事務參與者會中斷事務,避免了事務協調者單點故障問題,3PC的提交階段中即使事務協調者出現問題時,事務參與者會繼續提交事務,

缺點:引入一個階段,多一次互動,性能比2PC更低,且絕大部分情況事務參與者都由能執行事務的條件,仍要先詢問一次,而且資料不一致問題依然存在,當在參與者收到 preCommit 請求后等待 do commite 指令時,此時如果協調者請求中斷事務,而協調者無法與參與者正常通信,會導致參與者繼續提交事務,造成資料不一致,

TCC

方案簡介

2PC 和3PC 都是資料庫層面的,而 TCC 是基于業務層的分布式事務,TCC 的概念,最早是由 Pat Helland 于 2007 年發表的一篇名為《Life beyond Distributed Transactions:an Apostate’s Opinion》的論文提出的,其核心思想是:針對每個操作,都要注冊一個與其對應的確認和補償(撤銷)操作,

TCC 是 Try、Con?rm、Cancel 三個詞語的縮寫,TCC 要求每個分支事務實作三個操作:預處理 Try、確認 Con?rm、撤銷,Try、Confirm、Cancel 可以理解為 SQL 事務中的 Lock、Commit、Rollback,可以將TCC 簡單理解為服務化的 2PC 編程模型,都是先試探性的執行,如果都可以那就真正的執行,如果不行就回滾,

TCC中還可以有一個事務管理者的角色 - TM 事務管理器:TM事務管理器可以實作為獨立的服務,也可以讓全域事務發起方充當 TM 的角色,TM 獨立出來是為了成為公用組件,是為了考慮系統結構和軟體復用,TM 在發起全域事務時生成全域事務記錄,全域事務 ID 貫穿整個分布式事務呼叫鏈條,用來記錄事務背景關系, 追蹤和記錄狀態,由于 Con?rm 和 Cancel 失敗需進行重試,因此需要實作為冪等,冪等性是指同一個操作無論請求多少次,其結果都相同,

TCC 的 Try、Confirm、Cancel 3 個方法均由業務編碼實作:

  • Try 操作作為一階段,負責資源的檢查、預留和鎖定,
  • Confirm 操作相當于2PC的提交階段,執行真正的業務,
  • Cancel 是預留資源的取消,可以理解為撤銷預留階段的動作,

流程分析

為了方便理解,下面以電商下單為例進行方案決議,這里把整個程序簡單分為扣減庫存,訂單創建 2 個步驟,庫存服務和訂單服務分別在不同的服務器節點上,

Try 階段

從執行階段來看,與傳統事務機制中業務邏輯相同,但從業務角度來看,卻不一樣,

TCC 機制中的 Try 僅是一個初步操作,它和后續的確認一起才能真正構成一個完整的業務邏輯,這個階段主要完成:

  • 完成所有業務檢查作業( 一致性 ) ,
  • 預留鎖定必須業務資源( 準隔離性 ) ,
  • Try 嘗試執行業務,

TCC 事務機制是以初步操作(Try)為中心的,確認操作(Confirm)和取消操作(Cancel)都是圍繞初步操作(Try)而展開,因此,Try 階段中的操作,其保障性是最好的,即使失敗,仍然有取消操作(Cancel)可以將其執行結果撤銷,

假設商品庫存為 100,購買數量為 2,這里檢查和更新庫存的同時,凍結用戶購買數量的庫存,同時創建訂單,訂單狀態為待確認,

TCC-Try

Confirm階段

Confirm:當 Try 階段服務全部正常執行, 執行確認業務邏輯操作,Try 階段所有分支事務執行成功后開始執行 Con?rm,通常情況下,采用 TCC 則認為 Con?rm 階段是不會出錯的,即:只要 Try 成功,Con?rm 一定成功,若 Con?rm 階段真的出錯了,需引入重試機制或人工處理,所以 Confirm 操作需要滿足冪等性,

Confirm 階段也可以看成是對 Try 階段的一個補充,Try + Confirm 一起組成了一個完整的業務邏輯,Confirm 階段使用的資源一定是 Try 階段預留的業務資源,

TCC-Confirm

Cancel 階段

Cancel:當 Try 階段存在服務執行失敗需要回滾, 進入 Cancel 階段,執行分支事務的業務取消,釋放Try階段中的預留業務員資源,通常情況下,采用 TCC 則認為 Cancel 階段也是一定成功的,若 Cancel 階段真的出錯了,需引入重試機制或人工處理,所以 Cancel 操作需要滿足冪等性,

TCC-CANCEL

方案小結

TCC 事務機制相對于傳統事務機制(X/Open XA),有以下優點:

  • 性能提升:讓應用自己定義資料操作的粒度,使得降低鎖沖突、不會鎖定整個資源,提高吞吐量,
  • 適用范圍廣:基于業務實作,TCC 可以跨資料庫,跨不同業務系統實作事務,
  • 最終一致性:基于 Confirm 和 Cancel 的冪等性,保證事務最終完成確認或者取消,保證資料的最終一致性,
  • 可靠性:解決了 XA 協議的協調者單點故障問題,由主業務方發起并控制整個業務活動,業務活動管理器也變成多點,引入集群,

缺點:

  • TCC 的 Try、Confirm 和 Cancel 操作功能要按具體業務來實作,業務耦合度較高,提高了開發成本,
  • 這三個操作方法的實作有一定難度,需要按照網路狀態、系統故障等不同的失敗原因實作不同的回滾策略,

本地訊息表

方案簡介

本地訊息表的方案最初是由 eBay 提出,該方案基于可靠訊息最終一致性方案,可靠訊息最終一致性方案是指當事務發起方執行完成本地事務后并發出一條訊息,事務參與方(訊息消費者)一定能夠接收訊息并處理事務成功,此方案強調的是只要訊息發給事務參與方最終事務要達到一致,

本地訊息表核心思路是利用各系統本地的事務來實作分布式事務,通過在事務主動發起方額外新建事務訊息表,事務發起方處理業務和記錄事務訊息在本地事務中完成,輪詢事務訊息表的資料發送事務訊息,事務被動方基于訊息中間件消費事務訊息表中的事務,

事務訊息表與業務資料表處于同一個資料庫中,然后在執行業務的時候 將業務的執行和將訊息放入訊息表中的操作放在同一個事務中,保證訊息放入本地表中業務肯定是執行成功的,這樣就能利用本地事務來保證在對這兩個表的操作滿足事務特性,并且使用了訊息佇列來保證最終一致性,這樣設計可以避免”業務處理成功 + 事務訊息發送失敗",或"業務處理失敗 + 事務訊息發送成功"的棘手情況出現,保證 2 個系統事務的資料一致性,

流程分析

把分布式事務最先開始處理的事務方稱為事務主動方,在事務主動方之后處理的業務內的其他事務稱為事務被動方,為了方便理解,以電商下單為例進行方案決議,這里把整個程序簡單分為扣減庫存,訂單創建 2 個步驟,

庫存服務和訂單服務分別在不同的服務器節點上,其中庫存服務是事務主動方,訂單服務是事務被動方,事務的主動方需要額外新建事務訊息表,用于記錄分布式事務的訊息的發生、處理狀態,

整個業務處理流程如下圖:

本地訊息表-流程

  1. 事務主動方處理本地事務,

    事務主動方在本地事務中處理業務更新操作和寫訊息表操作,上面例子中庫存服務階段在本地事務中完成扣減庫存和寫訊息表(圖中 1、2),

  2. 事務主動方通過訊息中間件,通知事務被動方處理事務通知事務待訊息,

    訊息中間件可以基于 Kafka、RocketMQ 等訊息佇列,事務主動方主動寫訊息到訊息佇列,事務消費方消費并處理訊息佇列中的訊息,

    庫存服務把事務待處理訊息寫到訊息中間件,訂單服務消費訊息中間件的訊息,完成新增訂單(圖中 3 - 5),

  3. 事務被動方通過訊息中間件,通知事務主動方事務已處理的訊息,

    訂單服務把事務已處理訊息寫到訊息中間件,庫存服務消費中間件的訊息,并將事務訊息的狀態更新為已完成(圖中 6 - 8),

為了資料的一致性,當處理錯誤需要重試,事務發送方和事務接收方相關業務處理需要支持冪等,而且一般重試會有最大次數,超過最大次數可以記錄下報警讓人工處理,可以看到本地訊息表其實實作的是最終一致性,容忍了資料暫時不一致的情況,具體保存一致性的容錯處理如下:

  • 當步驟 1 處理出錯,事務回滾,相當于什么都沒發生,
  • 當步驟 2、步驟 3 處理出錯,由于未處理的事務訊息還是保存在事務發送方,事務發送方可以定時輪詢讀取本地訊息表中的超時訊息資料,再次發送到訊息中間件進行處理,事務被動方消費事務訊息重試處理,
  • 如果是業務上的失敗,事務被動方可以發訊息給事務主動方進行回滾,
  • 如果多個事務被動方已經消費訊息,事務主動方需要回滾事務時需要通知事務被動方回滾,

方案小結

本地訊息表的優點如下:

  • 從應用設計開發的角度實作了事務參與方接收訊息資料的可靠性,訊息資料的可靠性不依賴于訊息中間件,榷訓了對 MQ 中間件特性的依賴,
  • 引入訊息機制后,同步的事務操作變為基于訊息執行的異步操作, 避免了分布式事務中的同步阻塞操作的影響,并實作了兩個服務的解耦(非業務解耦),
  • 方案輕量,容易實作,

缺點如下:

  • 與具體的業務場景系結,耦合性強,不可公用,
  • 訊息資料與業務資料同庫,占用業務系統資源,
  • 業務系統在使用關系型資料庫的情況下,訊息服務性能會受到關系型資料庫并發性能的局限,

MQ 事務訊息

方案簡介

MQ事務訊息方案可以算是最大努力通知方案,最大努力通知方案的目標:發起通知方通過一定的機制最大努力將業務處理結果通知到接收方,具體包括:

  1. 有一定的訊息重復通知機制,因為接收通知方可能沒有接收到通知,此時要有一定的機制對訊息重復通知,
  2. 訊息校對機制,如果盡最大努力也沒有通知到接收方,或者接收方消費訊息后要再次消費,此時可由接收方主動向通知方查詢訊息資訊來滿足需求,

所以最大努力通知其實只是表明了一種柔性事務的思想:我已經盡力我最大的努力想達成事務的最終一致了,

基于 MQ 的分布式事務方案其實是對本地訊息表的封裝,將本地訊息表基于 MQ 內部,其他方面的協議基本與本地訊息表一致,有一些第三方的MQ是支持事務訊息的,比如RocketMQ,他們支持事務訊息的方式也是類似于采用的二階段提交,但是市面上一些主流的MQ都是不支持事務訊息的,比如 RabbitMQ 和 Kafka 都不支持,

流程分析

下面主要基于 RocketMQ 介紹 MQ 的分布式事務方案,

在本地訊息表方案中,保證事務主動方發寫業務表資料和寫訊息表資料的一致性是基于資料庫事務,RocketMQ 的事務訊息相對于普通 MQ,相當于提供了 2PC 的提交介面,第一階段Prepared訊息,會拿到訊息的地址, 第二階段執行本地事務,第三階段通過第一階段拿到的地址去訪問訊息,并修改狀態,方案如下:

  • 正常情況:事務主動方發訊息

MQ事務-事務主動方發訊息

這種情況下,事務主動方服務正常,沒有發生故障,發訊息流程如下:

  1. 發送方向 MQ 服務端(MQ Server)發送事務訊息即半訊息(half),半訊息不是說一半訊息,而是這個訊息對消費者來說不可見(圖中 1),
  2. MQ Server 將訊息持久化成功之后,向發送方 ack 確認訊息已經發送成功(圖中 2),
  3. 發送方開始執行本地事務邏輯(圖中 3),
  4. 發送方根據本地事務執行結果向 MQ Server 提交二次確認(commit 或是 rollback)(圖中 4),
  5. MQ Server 收到 commit 狀態則將半訊息標記為可投遞,訂閱方最終將收到該訊息;MQ Server 收到 rollback 狀態則洗掉半訊息,訂閱方將不會接受該訊息(圖中 5),
  • 例外情況:事務主動方訊息恢復

MQ事務-事務主動方訊息恢復

有斷網或者應用重啟等例外情況,流程如下:

  1. 提交的二次確認超時未到達 MQ Server(圖中 4),
  2. MQ Server 對該訊息發起訊息回查(圖中 5),
  3. 發送方收到訊息回查后,需要檢查對應訊息的本地事務執行的最終結果(圖中 6),
  4. 發送方根據檢查得到的本地事務的最終狀態再次提交二次確認(圖中 7),
  5. MQ Server基于 commit/rollback 對訊息進行投遞或者洗掉(圖中 8),

介紹完 RocketMQ 的事務訊息方案后,由于前面已經介紹過本地訊息表方案,這里就簡單介紹 RocketMQ 分布式事務:

MQ分布式事務

方案小結

最大努力通知與可靠訊息一致性有什么不同?

  1. 解決方案思想不同

    可靠訊息一致性,發起通知方需要保證將訊息發出去,并且將訊息發到接收通知方,訊息的可靠性關鍵由發起通知方來保證,最大努力通知,發起通知方盡最大的努力將業務處理結果通知為接收通知方,但是可能訊息接收不到,此時需要接 收通知方主動呼叫發起通知方的介面查詢業務處理結果,通知的可靠性關鍵在接收通知方,

  2. 兩者的業務應用場景不同

    可靠訊息一致性關注的是交易程序的事務一致,以異步的方式完成交易,最大努力通知關注的是交易后的通知事務,即將交易結果可靠的通知出去,

  3. 技術解決方向不同

    可靠訊息一致性要解決訊息從發出到接收的一致性,即訊息發出并且被接收到,最大努力通知無法保證訊息從發出到接收的一致性,只提供訊息接收的可靠性機制,可靠機制是,最大努力的將訊息通知給接收方,當訊息無法被接收方接收時,由接收方主動查詢訊息(業務處理結果)

MQ事務訊息方案相比本地訊息表方案,其優點是:

  • 訊息資料獨立存盤 ,降低業務系統與訊息系統之間的耦合,
  • 系統吞吐量高于本地訊息表方案,

缺點是:

  • 一次訊息發送需要兩次網路請求(half 訊息 + commit/rollback 訊息),
  • 業務處理服務需要實作訊息狀態回查介面,

Saga 事務

方案簡介

Saga 事務源于 1987 年普林斯頓大學的 Hecto 和 Kenneth 發表的如何處理 long lived transaction(長活事務)論文,

Saga 事務核心思想是將長事務拆分為多個本地短事務組成,由 Saga 事務協調器協調,每個本地事務有相應的執行模塊和補償模塊,如果正常結束那就正常完成,當 Saga 事務中的任意一個本地事務出錯了, 可以根據相反順序呼叫相關事務對應的補償方法恢復,達到事務的最終一致性,在服務請求的程序中,可能會出現超時重試的情況,需要通過冪等來避免多次請求所帶來的問題,

ACID與Saga

ACID (剛性事務)Saga 只提供ACD保證
原子性(Atomicity)原子性(通過Saga協調器實作)
一致性(Consistency)一致性(本地事務 + Saga Log)
隔離性(Isolation)隔離性(Saga 不保證)
持久性(Durability)持久性(Saga Log)

流程分析

Saga 事務基本協議如下:

  • 每個 Saga 事務由一系列冪等的有序子事務(sub-transaction) Ti 組成,
  • 每個 Ti 都有對應的冪等補償動作 Ci,補償動作用于撤銷 Ti 造成的結果,

可以看到,和 TCC 相比,Saga 沒有“預留”動作,它的 Ti 就是直接提交到庫,

Saga 的執行順序有兩種,如下圖,下面以下單流程為例,整個操作包括:創建訂單、扣減庫存、支付、增加積分,

Saga-執行順序

  • 事務正常執行完成:T1, T2, T3, …, Tn,例如:扣減庫存(T1),創建訂單(T2),支付(T3),依次有序完成整個事務,
  • 事務回滾:T1, T2, …, Tj, Cj,…, C2, C1,其中 0 < j < n,例如:扣減庫存(T1),創建訂單(T2),支付(T3,支付失敗),支付回滾(C3),訂單回滾(C2),恢復庫存(C1),

Saga 定義了兩種恢復策略:

  • 向前恢復(forward recovery):對應于上面第一種執行順序,適用于必須要成功的場景,發生失敗進行重試,執行順序是類似于這樣的:T1, T2, …, Tj(失敗), Tj(重試),…, Tn,其中j是發生錯誤的子事務(sub-transaction),該情況下不需要Ci,如下圖:

Saga-向前恢復

  • 向后恢復(backward recovery):對應于上面提到的第二種執行順序,其中 j 是發生錯誤的子事務(sub-transaction),這種做法的效果是撤銷掉之前所有成功的子事務,使得整個 Saga 的執行結果撤銷,

Saga-向后恢復

Saga 事務常見的有兩種不同的實作方式:

  • 集中式的實作方式 - 命令協調(Order Orchestrator):中央協調器負責集中處理事件的決策和業務邏輯排序,

中央協調器(Orchestrator,簡稱 OSO)以命令/回復的方式與每項服務進行通信,全權負責告訴每個參與者該做什么以及什么時候該做什么,

以電商訂單的例子為例:

  1. 事務發起方的主業務邏輯請求 OSO 服務開啟訂單事務
  2. OSO 向庫存服務請求扣減庫存,庫存服務回復處理結果,
  3. OSO 向訂單服務請求創建訂單,訂單服務回復創建結果,
  4. OSO 向支付服務請求支付,支付服務回復處理結果,
  5. 主業務邏輯接收并處理 OSO 事務處理結果回復,

Saga-命令協調

中央協調器必須事先知道執行整個訂單事務所需的流程(例如通過讀取配置),如果有任何失敗,它還負責通過向每個參與者發送命令來撤銷之前的操作來協調分布式的回滾,

基于中央協調器協調一切時,回滾要容易得多,因為協調器默認是執行正向流程,回滾時只要執行反向流程即可,

  • 分布式的實作方式 - 事件編排(Event Choreography0):沒有中央協調器(沒有單點風險)時,每個服務產生并觀察其他服務的事件,并決定是否應采取行動,

在事件編排方法中,第一個服務執行一個事務,然后發布一個事件,該事件被一個或多個服務進行監聽,這些服務再執行本地事務并發布(或不發布)新的事件,

當最后一個服務執行本地事務并且不發布任何事件時,意味著分布式事務結束,或者它發布的事件沒有被任何 Saga 參與者聽到都意味著事務結束,

以電商訂單的例子為例:

  1. 事務發起方的主業務邏輯發布開始訂單事件,
  2. 庫存服務監聽開始訂單事件,扣減庫存,并發布庫存已扣減事件,
  3. 訂單服務監聽庫存已扣減事件,創建訂單,并發布訂單已創建事件,
  4. 支付服務監聽訂單已創建事件,進行支付,并發布訂單已支付事件,
  5. 主業務邏輯監聽訂單已支付事件并處理,

Saga-事件編排

事件編排是實作 Saga 模式的自然方式,它很簡單,容易理解,不需要太多的代碼來構建,如果事務涉及 2 至 4 個步驟,則可能是非常合適的,

隔離性

由于 Saga 模型中只支持ACD,沒有 Prepare 階段,因此事務間不能保證隔離性,

當多個 Saga 事務操作同一資源時,就會產生資料語意不一致、更新丟失、臟資料讀取等問題,需要在業務層控制并發,解決方案如下:

  • 在應用層面加入邏輯鎖,
  • Session層面隔離保證串行化操作,
  • 業務層面預先凍結資源資料,
  • 業務操作程序中通過及時讀取當前狀態的方式獲取更新,

方案小結

命令協調設計的優點如下:

  • 服務之間關系簡單,避免服務之間的回圈依賴關系,因為 Saga 協調器會呼叫 Saga 參與者,但參與者不會呼叫協調器,
  • 程式開發簡單,只需要執行命令/回復(其實回復訊息也是一種事件訊息),降低參與者的復雜性,
  • 易維護擴展,在添加新步驟時,事務復雜性保持線性,回滾更容易管理,更容易實施和測驗,易于監控和協調,

命令協調設計缺點如下:

  • 中央協調器容易處理邏輯容易過于復雜,導致難以維護,
  • 存在協調器單點故障風險,

事件編排設計優點如下:

  • 避免中央協調器單點故障風險,
  • 當涉及的步驟較少服務開發簡單,容易實作,

事件/編排設計缺點如下:

  • 服務之間存在回圈依賴的風險,
  • 當涉及的步驟較多,服務間關系混亂,難以追蹤調測,

Seata 方案

方案簡介

Seata 是由阿里中間件團隊發起的開源專案 Fescar,后更名為 Seata,它是一個是開源的分布式事務框架,

傳統 2PC 的問題在 Seata 中得到了解決,它通過對本地關系資料庫的分支事務的協調來驅動完成全域事務,是作業在應用層的中間件,主要優點是性能較好,且不長時間占用連接資源,它以高效并且對業務 0 侵入的方式解決微服務場景下面臨的分布式事務問題,它目前提供 AT 模式(即 2PC)及 TCC 模式的分布式事務解決方案,

設計思想

Seata 的設計目標其一是對業務無侵入,因此從業務無侵入的 2PC 方案著手,在傳統 2PC的基礎上演進,并解決 2PC 方案面臨的問題,

Seata 把一個分布式事務理解成一個包含了若干分支事務全域事務,全域事務的職責是協調其下管轄的分支事務達成一致,要么一起成功提交,要么一起失敗回滾,此外,通常分支事務本身就是一個關系資料庫的本地事務,下圖是全域事務與分支事務的關系圖:

seata1

與傳統 2PC 的模型類似,Seata 定義了 3 個組件來協議分布式事務的處理程序:

seata2

  • Transaction Coordinator(TC):事務協調器,它是獨立的中間件,需要獨立部署運行,它維護全域事務的運行狀態,接收 TM 指令發起全域事務的提交與回滾,負責與 RM 通信協調各各分支事務的提交或回滾,
  • Transaction Manager(TM): 事務管理器,TM 需要嵌入應用程式中作業,它負責開啟一個全域事務,并最終向 TC 發起全域提交或全域回滾的指令,
  • Resource Manager(RM):控制分支事務,負責分支注冊、狀態匯報,并接收事務協調器 TC 的指令,驅動分支(本地)事務的提交和回滾,

流程分析

拿新用戶注冊送積分舉例,簡單分析Seata的分布式事務程序:

seata3

  1. 用戶服務的 TM 向 TC 申請開啟一個全域事務,全域事務創建成功并生成一個全域唯一的 XID,
  2. 用戶服務的 RM 向 TC 注冊分支事務,該分支事務在用戶服務執行新增用戶邏輯,并將其納入 XID 對應全域事務的管轄,
  3. 用戶服務執行分支事務,向用戶表插入一條記錄,
  4. 邏輯執行到遠程呼叫積分服務時(XID 在微服務呼叫鏈路的背景關系中傳播),積分服務的 RM 向 TC 注冊分支事務,該分支事務執行增加積分的邏輯,并將其納入 XID 對應全域事務的管轄,
  5. 積分服務執行分支事務,向積分記錄表插入一條記錄,執行完畢后,回傳用戶服務,
  6. 用戶服務分支事務執行完畢,
  7. TM 向 TC 發起針對 XID 的全域提交或回滾決議,
  8. TC 調度 XID 下管轄的全部分支事務完成提交或回滾請求,

方案小結

Seata方案與傳統 2PC 方案對比,有以下優點:

  • 架構層次方面:傳統 2PC 方案的 RM 實際上是在資料庫層,RM 本質上就是資料庫自身,通過 XA 協議實作,而 Seata 的 RM 是以 jar 包的形式作為中間件層部署在應用程式這一側的,
  • 二階段提交方面:傳統 2PC無論提交階段的決議是 commit 還是 rollback ,事務性資源的鎖都要保持到 Phase2 完成才釋放,而 Seata 的做法是在 Phase1 就將本地事務提交,這樣就可以省去 Phase2 持鎖的時間,整體提高效率,

由于 Seata 的 0 侵入性并且解決了傳統 2PC 長期鎖資源的問題,推薦采用 Seata 實作 2PC,

總結

方案對比

19

各方案使用場景

介紹完分布式事務相關理論和常見解決方案后,最終的目的在實際專案中運用,因此,總結一下各個方案的常見的使用場景:

  • 2PC/3PC:依賴于資料庫,能夠很好的提供強一致性和強事務性,但相對來說延遲比較高,比較適合傳統的單體應用,在同一個方法中存在跨庫操作的情況,不適合高并發和高性能要求的場景,
  • TCC:適用于執行時間確定且較短,實時性要求高,對資料一致性要求高,比如互聯網金融企業最核心的三個服務:交易、支付、賬務,
  • 本地訊息表/MQ 事務:都適用于事務中參與方支持操作冪等,對一致性要求不高,業務上能容忍資料不一致到一個人工檢查周期,事務涉及的參與方、參與環節較少,業務上有對賬/校驗系統兜底,
  • Saga 事務:由于 Saga 事務不能保證隔離性,需要在業務層控制并發,適合于業務場景事務并發操作同一資源較少的情況, Saga 相比缺少預提交動作,導致補償動作的實作比較麻煩,例如業務是發送短信,補償動作則得再發送一次短信說明撤銷,用戶體驗比較差,Saga 事務較適用于補償動作容易處理的場景,

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/251739.html

標籤:其他

上一篇:SpingBoot + Dubbo + Zookeeper實作簡單分布式開發的應用

下一篇:負載均衡之Haproxy搭建Web群集實戰部署

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more