前邊我們已經學習了四種分布式事務解決方案,2PC、TCC、可靠消息最終一致性、最大努力通知,每種解決方案我們通過案例開發進行學習,本章節我們結合互聯網金融項目中的業務場景,來進行分布式事務解決方案可行性分析。
7.1.系統介紹
7.1.1.P2P介紹
P2P金融又叫P2P信貸。其中P2P是 peer-to-peer 或 person-to-person 的簡寫,意思是:個人對個人。P2P金融指個人與個人間的小額借貸交易,一般需要借助電子商務專業網絡平台幫助借貸雙方確立借貸關系並完成相關交易手續。借款者可自行發布借款信息,包括金額、利息、還款方式和時間,實現自助式借款;投資者根據借款人發布的信息,自行決定出借金額,實現自助式借貸。
目前,國家對P2P行業的監控與規范性控制越來越嚴格,出台了很多政策來對其專項整治。並主張采用“銀行存管模式”來規避P2P平台挪用借投人資金的風險,通過銀行開發的“銀行存管系統”管理投資者的資金,每位P2P平台用戶在銀行的存管系統內都會有一個獨立賬號,平台來管理交易,做到資金和交易分開,讓P2P平台不能接觸到資金,就可以一定程度避免資金被挪用的風險。
什么是銀行存管模式?
銀行存管模式涉及到2套賬戶體系,P2P平台和銀行各一套賬戶體系。投資人在P2P平台注冊后,會同時跳轉到銀行再開一個電子賬戶,2個賬戶間有一一對應的關系。當投資人投資時,資金進入的是平台在銀行為投資人開設的二級賬戶中,每一筆交易,是由銀行在投資人與借款人間的交易划轉,P2P平台僅能看到信息的流動。
7.1.2.總體業務流程
7.1.2.業務術語
銀行存管模式:此種模式下,涉及到2套賬戶體系,P2P平台和銀行各一套賬戶體系。投資人在P2P平台注冊后,會同時跳轉到銀行再開一個電子賬戶,2個賬戶間有一一對應的關系。當投資人投資時,資金進入的是平台在銀行為投資人開設的二級賬戶中,每一筆交易,是由銀行在投資人與借款人間的交易划轉,P2P平台僅能看到信息的流動。
標的: P2P業內,習慣把借款人發布的投資項目稱為“標的”。
發標: 借款人在P2P平台中創建並發布“標的”過程。
投標: 投資人在認可相關借款人之后進行的一種借貸行為,對自己中意的借款標的進行投資操作,一個借款標可由單個投資人或多個投資人承接。
滿標: 單筆借款標籌集齊所有借款資金即為滿標,計息時間是以標滿當日開始計息,投資人較多的平台多數會當天滿標。
7.1.2.模塊說明
統一賬號服務
用戶的登錄賬號、密碼、角色、權限、資源等系統級信息的管理,不包含用戶業務信息。
用戶中心
提供用戶業務信息的管理,如會員信息、實名認證信息、綁定銀行卡信息等,“用戶中心”的每個用戶與“統一賬號服務”中的賬號關聯。
交易中心
提供發標、投標等業務。
還款服務
提供還款計划的生成、執行、記錄與歸檔。
銀行存管系統(模擬)
模擬銀行存管系統,進行資金的存管,划轉。
7.2.注冊賬號案例分析
7.2.1.業務流程
采用用戶、賬號分離設計(這樣設計的好處是,當用戶的業務信息發生變化時,不會影響的認證、授權等系統機制),因此需要保證用戶信息與賬號信息的一致性。
用戶向用戶中心發起注冊請求,用戶中心保存用戶業務信息,然后通知統一賬號服務新建該用戶所對應登錄賬號。
7.2.2.解決方案分析
針對注冊業務,如果用戶與賬號信息不一致,則會導致嚴重問題,因此該業務對一致性要求較為嚴格,即當用戶服務和賬號服務任意一方出現問題都需要回滾事務。
根據上述需求進行解決方案分析:
1、采用可靠消息一致性方案
可靠消息一致性要求只要消息發出,事務參與者接到消息就要將事務執行成功,不存在回滾的要求,所以不適用。
2、采用最大努力通知方案
最大努力通知表示發起通知方執行完本地事務后將結果通知給事務參與者,即使事務參與者執行業務處理失敗發起通知方也不會回滾事務,所以不適用。
3、采用Seata實現2PC
在用戶中心發起全局事務,統一賬戶服務為事務參與者,用戶中心和統一賬戶服務只要有一方出現問題則全局事務回滾,符合要求。
實現方法如下:
1、用戶中心添加用戶信息,開啟全局事務
2、統一賬號服務添加賬號信息,作為事務參與者
3、其中一方執行失敗Seata對SQL進行逆操作刪除用戶信息和賬號信息,實現回滾。
4、采用Hmily實現TCC
TCC也可以實現用戶中心和統一賬戶服務只要有一方出現問題則全局事務回滾,符合要求。
實現方法如下:
1、用戶中心
try:添加用戶,狀態為不可用 confirm:更新用戶狀態為可用 cancel:刪除用戶
2、統一賬號服務
try:添加賬號,狀態為不可用 confirm:更新賬號狀態為可用 cancel:刪除賬號
7.3.存管開戶
7.3.1.業務流程
根據政策要求,P2P業務必須讓銀行存管資金,用戶的資金在銀行存管系統的賬戶中,而不在P2P平台中,因此用戶要在銀行存管系統開戶。
用戶向用戶中心提交開戶資料,用戶中心生成開戶請求號並重定向至銀行存管系統開戶頁面。用戶設置存管密碼並確認開戶后,銀行存管立即返回“請求已受理”。在某一時刻,銀行存管系統處理完該開戶請求后,將調用回調地址通知處理結果,若通知失敗,則按一定策略重試通知。同時,銀行存管系統應提供開戶結果查詢的接口,供用戶中心校對結果。
7.3.2.解決方案分析
P2P平台的用戶中心與銀行存管系統之間屬於跨系統交互,銀行存管系統屬於外部系統,用戶中心無法干預銀行存管系統,所以用戶中心只能在收到銀行存管系統的業務處理結果通知后積極處理,開戶后的使用情況完全由用戶中心來控制。
根據上述需求進行解決方案分析:
1、采用Seata實現2PC
需要侵入銀行存管系統的數據庫,由於它的外部系統,所以不適用。
2、采用Hmily實現TCC
TCC侵入性更強,所以不適用。
3、基於MQ的可靠消息一致性
如果讓銀行存管系統監聽 MQ則不合適 ,因為它的外部系統。
如果銀行存管系統將消息發給MQ用戶中心監聽MQ是可以的,但是由於相對銀行存管系統來說用戶中心屬於外部系統,銀行存管系統是不會讓外部系統直接監聽自己的MQ的,基於MQ的通信協議也不方便外部系統間的交互,所以本方案不合適。
4、最大努力通知方案
銀行存管系統內部使用MQ,銀行存管系統處理完業務后將處理結果發給MQ,由銀行存管的通知程序專門發送通知,並且采用互聯網協議通知給第三方系統(用戶中心)。
下圖中發起通知即銀行存管系統:
7.4.滿標審核
7.4.1.業務流程
在借款人標的募集夠所有的資金后,P2P運營管理員審批該標的,觸發放款,並開啟還款流程。
管理員對某標的滿標審批通過,交易中心修改標的狀態為“還款中”,同時要通知還款服務生成還款計划。
7.4.2.解決方案分析
生成還款計划是一個執行時長較長的業務,不建議阻塞主業務流程,此業務對一致性要求較低。
根據上述需求進行解決方案分析:
1、采用Seata實現2PC
Seata在事務執行過程會進行數據庫資源鎖定,由於事務執行時長較長會將資源鎖定較長時間,所以不適用。
2、采用Hmily實現TCC
本需求對業務一致性要求較低,因為生成還款計划的時長較長,所以不要求交易中心修改標的狀態為“還款中”就立即生成還款計划 ,所以本方案不適用。
3、基於MQ的可靠消息一致性
滿標審批通過后由交易中心修改標的狀態為“還款中”並且向還款服務發送消息,還款服務接收到消息開始生成還款計划,基本於MQ的可靠消息一致性方案適用此場景 。
4、最大努力通知方案
滿標審批通過后由交易中心向還款服務發送通知要求生成還款計划,還款服務並且對外提供還款計划生成結果校對接口供其它服務查詢,最大努力 通知方案也適用本場景 。
總結
重點知識回顧:
1)事務的基本概念以及本地事務特性。
CAP、BASE理論的概念。
2PC、TCC、可靠消息最終一致性、最大努力通知各類型原理及特性。
不同分布式事務類型的應用場景討論。
RocketMQ事務消息機制。
Seata與傳統XA原理上的差異。
2)分布式事務對比分析:
在學習各種分布式事務的解決方案后,我們了解到各種方案的優缺點:
2PC 最大的詬病是一個阻塞協議。RM在執行分支事務后需要等待TM的決定,此時服務會阻塞並鎖定資源。由於其阻塞機制和最差時間復雜度高, 因此,這種設計不能適應隨着事務涉及的服務數量增加而擴展的需要,很難用於並發較高以及子事務生命周期較長 (long-running transactions) 的分布式服務中。
如果拿TCC事務的處理流程與2PC兩階段提交做比較,2PC通常都是在跨庫的DB層面,而TCC則在應用層面的處理,需要通過業務邏輯來實現。這種分布式事務的實現方式的優勢在於,可以讓應用自己定義數據操作的粒度,使得降低鎖沖突、提高吞吐量成為可能。而不足之處則在於對應用的侵入性非常強,業務邏輯的每個分支都需要實現try、confirm、cancel三個操作。此外,其實現難度也比較大,需要按照網絡狀態、系統故障等不同的失敗原因實現不同的回滾策略。典型的使用場景:滿,登錄送優惠券等。
可靠消息最終一致性事務適合執行周期長且實時性要求不高的場景。引入消息機制后,同步的事務操作變為基於消息執行的異步操作, 避免了分布式事務中的同步阻塞操作的影響,並實現了兩個服務的解耦。典型的使用場景:注冊送積分,登錄送優惠券等。
最大努力通知是分布式事務中要求最低的一種,適用於一些最終一致性時間敏感度低的業務;允許發起通知方處理業務失敗,在接收通知方收到通知后積極進行失敗處理,無論發起通知方如何處理結果都會不影響到接收通知方的后續處理;發起通知方需提供查詢執行情況接口,用於接收通知方校對結果。典型的使用場景:銀行通知、支付結果通知等。
3)總結:
在條件允許的情況下,我們盡可能選擇本地事務單數據源,因為它減少了網絡交互帶來的性能損耗,且避免了數據弱一致性帶來的種種問題。若某系統頻繁且不合理的使用分布式事務,應首先從整體設計角度觀察服務的拆分是否合理,是否高內聚低耦合?是否粒度太小?分布式事務一直是業界難題,因為網絡的不確定性,而且我們習慣於拿分布式事務與單機事務ACID做對比。
無論是數據庫層的XA、還是應用層TCC、可靠消息、最大努力通知等方案,都沒有完美解決分布式事務問題,它們不過是各自在性能、一致性、可用性等方面做取舍,尋求某些場景偏好下的權衡。