一分錢引起的系統設計「踩坑」案例

摘要:阿里妹導讀:阿里巴巴的電商業務十分複雜,一方面是市場多樣化,業務多樣化,另外是消費者,商家的影響面很是廣,任何一個小故障均可能引起一些社會問題,因此阿里對產品的質量,對服務的連續性有嚴格的要求。阿里技術人員在平常的研發運維過程當中,積累了豐富的實戰經驗。數據庫

阿里妹導讀:阿里巴巴的電商業務十分複雜,一方面是市場多樣化,業務多樣化,另外是消費者,商家的影響面很是廣,任何一個小故障均可能引起一些社會問題,因此阿里對產品的質量,對服務的連續性有嚴格的要求。阿里技術人員在平常的研發運維過程當中,積累了豐富的實戰經驗。今天,阿里妹將爲你們分享一個關於故障,排查,分析和改進的真實案例。他山之石能夠攻玉,但願對廣大開發和運維工程師帶來幫助。安全

背景說明併發

某日,作產品X的開發接到客戶公司電話,說是對帳出了1分錢的差錯,沒法處理。本着「客戶第一」的宗旨,開發立立刻線查看狀況。查完發現,按照產品X當日的年化收益率,正常狀況下用戶在轉入57元后一共收益3分錢,合計是57.03元。可是該客戶當日卻有一筆消費57.04元,致使客戶公司系統對多出的1分錢處理不了。再進一步分析,發現用戶收益結轉時多了1分錢的收益,而且已消費……運維

也就是說,原本用戶只有3分錢收益,結果多發了1分錢給他,也就給公司形成1分錢的損失!用戶在產品X裏當天收益本應該是0.03元,怎麼會變成0.04元呢?多出的1分錢收益從哪裏來的呢?分佈式

數據庫記錄分析阿里雲

帶着上面的一系列疑問,開發人員首先排查了產品X收益的數據庫記錄。經過查詢數據庫發現,該用戶收益結轉在同一天內存在2筆交易記錄。交易記錄1建立時間爲8:00:23,記錄2建立時間爲8:00:29,交易記錄1和2的最後修改時間均爲8:00:29,如圖4-1所示。線程

正常狀況下產品X收益天天只會結轉一次,而這個用戶當日有兩筆收益結轉記錄。開發人員懷疑,極可能是出現了併發問題。設計

繼續跟蹤第一筆「TXID a」的記錄,開發確認線上日誌存在超時狀況,失敗緣由是數據庫連接數已滿,線程等待提交。日誌

分佈式鎖超時時間是5s,第一筆記錄從建立到修改提交經歷了6s,因而可知是在分佈式鎖失效以後,得到了數據庫連接,進行提交成功。blog

有了以上三個排查思路後,咱們能夠開始逆推整個過程。

過程逆推

根據數據庫記錄逆推當時的運行狀況,如圖4-2所示。

(1)因爲數據庫鏈接數被佔滿,流水1建立的事務處於等待提交狀態。

(2)系統A發現交易失敗,重試次數不滿8次的,當即發起重試,觸發生成流水2的請求。

(3)5s之內數據均被分佈式鎖攔截,沒法提交。

(4)通過5s後,系統B的分佈式鎖失效,此時事務仍在等待未提交。

(5)6s時,流水2成功越過數據庫查詢冪等校驗發起事務,此時流水1拿到數據庫鏈接,流水1和2兩個事務同時提交。

(6)因爲數據庫未作惟一索引,且支付受理模塊打穿下層冪等原則,生成2個TXID,致使兩事務同時提交成功。

(7)收益結轉重複記帳,用戶多了一筆收入。

深刻分析

完成了整個問題的過程逆推後,開發人員進一步分析,發現問題真正的緣由仍是在系統設計上。如圖4-3所示,系統A的事務容許必定時間的等待,而上層業務的重試時間又比這個等待的時間要短。這就存在一個問題:系統A的事務還在等待中,業務就又發起了重試。若是是在這個應用場景下(可能業務上對重試要求更高一些),那麼對冪等控制的要求就更高了。而僅僅經過一個分佈式鎖來控制,若是分佈式鎖的超時時間設置的比事務容許等待的時間短,那麼在鎖失效以後就必定會同時提交兩筆請求。

圖4-3 分佈式鎖超時併發控制時間軸

繼續對整個過程抽象化,開發人員得出一個結論:分佈式鎖在如下條件同時知足的狀況下併發控制會被打穿。

(1)上層業務系統層面有重試機制。

(2)業務請求存在必定時間以後提交成功的狀況,例如本例中第一次請求在事務等待6s後得到了數據庫連接,提交數據庫成功。

(3)下游系統缺少其餘有效的冪等控制手段。

思考

瞭解了問題的前因後果後,接下來要怎麼解決這類問題呢?咱們想了如下幾個方案。

(1)調整B系統上的tr和分佈式鎖超時時間,tr超時調整爲10s,分佈式鎖超時調整爲30s。

(2)防止作收益結轉產生併發控制冪等,調整了收益結轉流水號的生成規則:前8位取X收益結轉傳入的交易號的前8位,第10位系統版本設置爲「9」,最後8位seq取交易號的最後8位,下降問題出現概率。

方案一:調整超時時間

調整超時時間後,業務重試時間與分佈式鎖有效時間的分佈時間軸如圖4-4所示,即在事務容許等待後提交成功的時間以外,再進行重試,另外分佈式鎖在整個階段均有效,防止提交。

圖4-4 分佈式鎖超時併發控制時間軸

方案一驗證有效。

方案二:增長冪等控制(推薦)

如圖4-5所示,單純靠分佈式鎖不是控制併發冪等的方式,最穩妥的方式仍是在提交記錄的時候經過數據庫嚴格控制冪等。確保不論如何設置超時時間,都不會出現冪等控制的問題。

圖4-5 分佈式鎖超時併發控制時間軸

方案二驗證有效。

小結

資金安全無小事,而冪等控制又是資金安全中的重中之重。回顧本文案例,從問題分析定位,到整個邏輯的梳理清洗,其中涉及了三個時間軸的相互做用,再加上事務、分佈式鎖、重試等,整個問題發生的邏輯仍是比較複雜的。所以,在系統併發冪等控制設計中,單純的分佈式鎖並不具有嚴格控制併發冪等的做用,建議在系統設計時,將第三方惟一性的冪等控制做爲冪等控制的兜底方案,控制好這道冪等防線,這樣不論業務如何設計,就萬變不離其宗了。

做者:阿里云云棲社區 連接:https://www.jianshu.com/p/ae8a69185a5f 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索