基於GO開發的自動聊機程式
分散式事務
-
分散式事務是指事務的參與者,支援事務的伺服器,資源伺服器分別位於分散式系統的不同節點之上,通常一個分散式
事物中會涉及到對多個數據源或業務系統的操作。 -
典型的分散式事務場景:跨銀行轉操作就涉及呼叫兩個異地銀行服務
CAP理論
-
CAP理論:一個分散式系統不可能同時滿足一致性,可用性和分割槽容錯性這個三個基本需求,最多隻能同時滿足其中兩
項 -
一致性(C):資料在多個副本之間是否能夠保持一致的特性。
-
可用性(A):是指系統提供的服務必須一致處於可用狀態,對於每一個使用者的請求總是在有限的時間內返回結果,超過時
間就認為系統是不可用的 -
分割槽容錯性(P):分散式系統在遇到任何網路分割槽故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務,
除非整個網路環境都發生故障。
CAP定理的應用
-
放棄P(CA):如果希望能夠避免系統出現分割槽容錯性問題,一種較為簡單的做法就是將所有的資料(或者是與事物先相關
的資料)都放在一個分散式節點上,這樣雖然無法保證100%系統不會出錯,但至少不會碰到由於網路分割槽帶來的負面影
響 -
放棄A(CP):其做法是一旦系統遇到網路分割槽或其他故障時,那受到影響的服務需要等待一定的時間,應用等待期間系統
無法對外提供正常的服務,即不可用 -
放棄C(AP):這裡說的放棄一致性,並不是完全不需要資料一致性,是指放棄資料的強一致性,保留資料的最終一致性。
BASE理論
-
BASE是基本可用,軟狀態,最終一致性。是對CAP中一致性和可用性許可權的結果,是基於CAP定理演化而來的,核心思
想是即使無法做到強一致性,但每個應用都可以根據自身的業務特定,採用適當的方式來使系統達到最終一致性
2PC提交
-
二階段提交協議是將事務的提交過程分成提交事務請求和執行事務提交兩個階段進行處理。
階段一:提交事務請求
-
事務詢問:協調者向所有的參與者傳送事務內容,詢問是否可以執行事務提交操作,並開始等待各參與者的響應
-
執行事務:各參與者節點執行事務操作,並將Undo和Redo資訊記入事務日誌中
-
如果參與者成功執事務操作,就反饋給協調者Yes響應,表示事物可以執行,如果沒有成功執行事務,就反饋給協調者
No響應,表示事務不可以執行 -
二階段提交一些的階段一夜被稱為投票階段,即各參與者投票票表明是否可以繼續執行接下去的事務提交操作
階段二:執行事務提交
-
假如協調者從所有的參與者或得反饋都是Yes響應,那麼就會執行事務提交。
-
傳送提交請求:協調者向所有參與者節點發出Commit請求
-
事務提交:參與者接受到Commit請求後,會正式執行事務提交操作,並在完成提交之後放棄整個事務執行期間佔用的
事務資源 -
反饋事務提交結果:參與者在完成事物提交之後,向協調者傳送ACK訊息
-
完成事務:協調者接收到所有參與者反饋的ACK訊息後,完成事務
中斷事務
-
假如任何一個參與者向協調者反饋了No響應,或者在等待超市之後,協調者尚無法接收到所有參與者的反饋響應,那麼
就中斷事務。 -
傳送回滾請求:協調者向所有參與者節點發出Rollback請求
-
事務回滾:參與者接收到Rollback請求後,會利用其在階段一種記錄的Undo資訊執行事物回滾操作,並在完成回滾之
後釋放事務執行期間佔用的資源。 -
反饋事務回滾結果:參與則在完成事務回滾之後,向協調者傳送ACK訊息
-
中斷事務:協調者接收到所有參與者反饋的ACk訊息後,完成事務中斷、
優缺點
-
原理簡單,實現方便
-
缺點是同步阻塞,單點問題,腦裂,保守
3PC提交
-
三階段提,也叫三階段提交協議,是二階段提交(2PC)的改進版本。
-
與兩階段提交不同的是,三階段提交有兩個改動點。引入超時機制。同時在協調者和參與者中都引入超時機制。在第一
階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。 -
三階段提交就有CanCommit、PreCommit、DoCommit三個階段。
Seata分散式事務方案
-
Seata 是一款開源的分散式事務解決方案,致力於提供高效能和簡單易用的分散式事務服務。Seata 將為使用者提供了
AT、TCC、SAGA 和 XA 事務模式,為使用者打造一站式的分散式解決方案。
Seata術語
-
TC:事務協調者。維護全域性和分支事務的狀態,驅動全域性事務提交或回滾。
-
TM:事務管理器。定義全域性事務的範圍:開始全域性事務、提交或回滾全域性事務
-
RM:管理分支事務處理的資源,與TC交談以註冊分支事務和報告分支事務的狀態,並驅動分支事務提交或回滾。
Seata的2PC方案
-
一階段:業務資料和回滾日誌記錄在同一個本地事務中提交,釋放本地鎖和連線資源。
-
二階段:提交非同步化,非常快速地完成。回滾通過一階段的回滾日誌進行反向補償。
-
一階段本地事務提交前,需要確保先拿到 全域性鎖 。拿不到全域性鎖 ,不能提交本地事務。
-
拿全域性鎖的嘗試被限制在一定範圍內,超出範圍將放棄,並回滾本地事務,釋放本地鎖。
-
在資料庫本地事務隔離級別讀已提交或以上的基礎上,Seata(AT 模式)的預設全域性隔離級別是 讀未提交
-
如果應用在特定場景下,必需要求全域性的 讀已提交 ,目前 Seata 的方式是通過 SELECT FOR UPDATE 語句的代理。
Seata執行流程分析
-
每個RM使用DataSourceProxy連結資料路,目的是使用ConnectionProxy,使用資料來源和資料代理的目的是在第一階段
將undo_log和業務資料放在一個本地事務提交,這樣就儲存了只要有業務操作就一定有undo_log -
在第一階段undo_log中存放了資料修改前後修改後的值,為事務回滾做好準別,所以第一階段完成就已經將分支事務提
交了,也就釋放了鎖資源 -
TM開啟全域性事務開始,將XID全域性事務ID放在事務上下文中,通過feign呼叫也將XID傳入下游分支事務,每個分支事務
將自己的Branch ID 分支事務ID與XID關聯 -
第二階段全域性事務提交,TC會通知各分支參與者提交分支事務,在第一階段就已經提交了分支事務,這裡各參與者只需
要刪除undo_log即可,並且可以非同步執行,第二階段很快可以完成 -
如果某一個分支事務異常,第二階段就全域性事務回滾操作,TC會通知各分支參與者回滾分支事務,通過XID和
Branch-ID找到對應的回滾日誌,通過回滾日誌生成的反向SQL並執行,以完成分支事務回滾到之前
Seata的實戰案列
-
github.com/seata/seata…
-
github.com/seata/seata…
TCC分散式事務
-
TCC是服務化的兩階段程式設計模型,其Try、Confirm、Cancel,3個方法均由業務編碼實現
-
TCC要求每個分支事務實現三個操作:預處理Try,確認Confirm,撤銷Cancel。
-
Try操作做業務檢查及資源預留,
-
Confirm做業務確認操作
-
Cancel實現一個與Try相反的操作即回滾操作。
-
TM首先發起所有的分支事務Try操作,任何一個分支事務的Try操作執行失敗,TM將會發起所有分支事務的Cancel操作,
若Try操作全部成功,TM將會發起所有分支事務的Confirm操作,其中Confirm/Cancel操作若執行失敗,TM會進行重試。
TCC的三個階段
-
Try階段是做業務檢查(一致性)及資源預留(隔離),此階段僅是一個初步操作,它和後續的Confirmy一起才能構成一個完整
的業務邏輯 -
Confirm階段是做確認提交,Try階段所有分支事務執行成功後開始執行Confirm,通常情況下,採用TCC則認為
Confirm階段是不會出錯的,即:只要Try成功,Confirm一定成功,若Confirm階段真的出錯,需要引入重試機制或人工
處理 -
Cancel階段是在業務執行錯誤需要回滾到狀態下執行分支事務的取消,預留資源的釋放,通常情況下,採用TCC則認為
Cancel階段也一定是真功的,若Cance階段真的出錯,需要引入重試機制或人工處理 -
TM事務管理器:TM事務管理器可以實現為獨立的服務,也可以讓全域性事務發起方充當TM的角色,TM獨立出來是為了公
用元件,是為了考慮系統結構和軟體的複用 -
TM在發起全域性事務時生成全域性事務記錄,全域性事務ID貫穿整個分散式事務呼叫鏈條,用來記錄事務上下文,追蹤和記錄
狀態,用於Confirm和cacel失敗需要進行重試,因此需要實現冪等
TCC的三種異常處理情況
冪等處理
-
因為網路抖動等原因,分散式事務框架可能會重複呼叫同一個分散式事務中的一個分支事務的二階段介面。所以分支事務
的二階段介面Confirm/Cancel需要能夠保證冪等性。如果二階段介面不能保證冪等性,則會產生嚴重的問題,造成資源
的重複使用或者重複釋放,進而導致業務故障。 -
對於冪等型別的問題,通常的手段是引入冪等欄位進行防重放攻擊。對於分散式事務框架中的冪等問題,同樣可以祭出
這一利器。 -
冪等記錄的插入時機是參與者的Try方法,此時的分支事務狀態會被初始化為INIT。然後當二階段的Confirm/Cancel執行
時會將其狀態置為CONFIRMED/ROLLBACKED。 -
當TC重複呼叫二階段介面時,參與者會先獲取事務狀態控制表的對應記錄檢視其事務狀態。如果狀態已經為
CONFIRMED/ROLLBACKED,那麼表示參與者已經處理完其分內之事,不需要再次執行,可以直接返回冪等成功的結果
給TC,幫助其推進分散式事務。
空回滾
-
當沒有呼叫參與方Try方法的情況下,就呼叫了二階段的Cancel方法,Cancel方法需要有辦法識別出此時Try有沒有執行。如果Try還沒執行,表示這個Cancel操作是無效的,即本次Cancel屬於空回滾;如果Try已經執行,那麼執行的是正常的回滾邏輯。
-
要應對空回滾的問題,就需要讓參與者在二階段的Cancel方法中有辦法識別到一階段的Try是否已經執行。很顯然,可以
繼續利用事務狀態控制表來實現這個功能。 -
當Try方法被成功執行後,會插入一條記錄,標識該分支事務處於INIT狀態。所以後續當二階段的Cancel方法被呼叫時,
可以通過查詢控制表的對應記錄進行判斷。如果記錄存在且狀態為INIT,就表示一階段已成功執行,可以正常執行回滾操
作,釋放預留的資源;如果記錄不存在則表示一階段未執行,本次為空回滾,不釋放任何資源。
資源懸掛
-
問題:TC回滾事務呼叫二階段完成空回滾後,一階段執行成功
-
解決:事務狀態控制記錄作為控制手段,二階段發現無記錄時插入記錄,一階段執行時檢查記錄是否存在
TCC和2PC比較
-
2PC通常都是在跨庫的DB層面,而TCC則在應用層面處理,需要通過業務邏輯實現,這種分散式事務的實現方式優勢在
於,可以讓應用自己定義資料操作的粒度,使得降低鎖衝突,提高吞吐量成為可能 -
而不足之處則在於對應用的侵入性非常強,業務邏輯的每個分支都需要實現Try,confirm,cancel三個操作。此外,其實
現難度也比較大,需要按照網路狀態,系統故障的不同失敗原因實現不同的回滾策略
Hmily框架實現TCC案列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#賬戶A
try :
try 的冪等效驗
try 的懸掛處理
檢查餘額是否夠 30 元
扣減 30 元
confirm:
空處理即可,通常TCC階段是認為confirm是不會出錯的
cancel:
cancel冪等效驗
cacel空回滾處理
增加可用餘額 30 元,回滾操作
#賬戶B
try :
空處理即可
confirm:
confirm的冪等效驗
正式增加 30 元
cancel:
空處理即可
|
RocketMQ實現可靠訊息最終一致性
-
可靠訊息最終一致性就是保證訊息從生產方經過訊息中介軟體傳遞到消費方的一致性
-
RocketMQ主要解決了兩個功能:本地事務與訊息傳送的原子性問題。事務參與方接收訊息的可靠性
-
可靠訊息最終一致性事務適合執行週期長且實時性要求不高的場景,引入訊息機制後,同步的事務操作變為基於訊息執行
的非同步操作,避免分散式事務中的同步阻塞操作的影響,並實現了兩個服務的解耦
最大努力通知
最大努力通知與可靠訊息一致性有什麼不同
-
可靠訊息一致性,發起通知方需要保證將訊息發出去,並且將訊息傳送到接收通知方,訊息的可靠性由發起通知方保證
-
最大努力通知,發起通知方盡最大的努力將業務處理結果通知為接收通知方,但是訊息可能接收不到,此時需要接收通知
方主動呼叫發起通知方的介面查詢業務,通知可靠性關鍵在於接收通知方
兩者的應用場景
-
可靠訊息一致性關注的是交易過程的事務一致,以非同步的方式完成交易
-
最大努力通知關注的是交易後的通知事務,即將交易結果可靠的通知出去
基於MQ的ack機制實現最大努力通知
-
利用MQ的ack機制由MQ向接收通知方傳送訊息通知,發起方將普通訊息傳送到MQ
-
接收通知監聽MQ,接收訊息,業務處理完成迴應ACK
-
接收通知方如果沒有迴應ACK則MQ會重複通知,按照時間間隔的方式,逐步拉大通知間隔
-
此方案適用於內部微服務之間的通知,不適應與通知外部平臺
方案二:增加一個通知服務區進行通知,提供外部第三方時適用
分散式事務方案對比分析
-
2PC 最大的一個詬病是一個阻塞協議。RM在執行分支事務後需要等待TM的決定,此時服務會阻塞鎖定資源。由於其阻
塞機制和最差時間複雜度高,因此,這種設計不能適應隨著事務涉及的服務數量增加而擴充套件的需要,很難用於併發較高以
及子事務生命週期較長的分散式服務中 -
如果拿TCC事務的處理流程與2PC兩階段提交做比較,2PC通常都是在跨庫的DB層面,而TCC則在應用層面處理,需要通
過業務邏輯來實現。這種分散式事務的優勢在於,可以讓應用自定義資料操作的粒度,使得降低鎖衝突,提高吞吐量成為
可能。而不足之處在於對應用的侵入性非常強,業務邏輯的每個分支都需要實現三個操作。此外,其實現難度也比較大,
需要按照網路狀態,系統故障等不同失敗原因實現不同的策略。 -
可靠訊息最終一致性事務適合執行週期長且實時性要求不高的場景。引入訊息機制後,同步的事務操作變為基於訊息執行
的非同步操作,避免了分散式事務中的同步阻塞操作的影響,並實現了兩個服務的解耦,典型的場景:註冊送積分,登陸送
優惠券等 -
最大努力通知是分散式事務中要求最低的一種,適用於一些最終一致性時間敏感度低的業務,允許發起通知方業務處理失
敗,在接收通知方收到通知後積極進行失敗處理,無論發起通知方如何處理結果都不會影響到接收通知方的後續處理,發
起通知方需提供查詢執行情況介面,用於接收通知方校對結果,典型的應用場景:銀行通知,支付結果通知等。
2PCTCC可靠訊息最大努力通知