如何高效排查系统故障?一分钱引发的系统设计“踩坑”案例
阿里妹導讀:阿里巴巴的電商業務十分復雜,一方面是市場多樣化,業務多樣化,另外是消費者,商家的影響面非常廣,任何一個小故障都可能引發一些社會問題,所以阿里對產品的質量,對服務的連續性有嚴格的要求。阿里技術人員在日常的研發運維過程中,積累了豐富的實戰經驗。今天,阿里妹將為大家分享一個關于故障,排查,分析和改進的真實案例。他山之石可以攻玉,希望對廣大開發和運維工程師帶來幫助。
背景說明
某日,做產品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所示。
圖4-1 用戶當日收益結轉數據庫記錄分析
正常情況下產品X收益每天只會結轉一次,而這個用戶當日有兩筆收益結轉記錄。開發人員懷疑,很可能是出現了并發問題。
繼續跟蹤第一筆“TXID a”的記錄,開發確認線上日志存在超時情況,失敗原因是數據庫鏈接數已滿,線程等待提交。
分布式鎖超時時間是5s,第一筆記錄從創建到修改提交經歷了6s,由此可見是在分布式鎖失效之后,獲得了數據庫鏈接,進行提交成功。
有了以上三個排查思路后,我們可以開始逆推整個過程。
過程逆推
根據數據庫記錄逆推當時的運行情況,如圖4-2所示。
(1)由于數據庫連接數被占滿,流水1創建的事務處于等待提交狀態。
(2)系統A發現交易失敗,重試次數不滿8次的,立即發起重試,觸發生成流水2的請求。
(3)5s以內數據均被分布式鎖攔截,無法提交。
(4)經過5s后,系統B的分布式鎖失效,此時事務仍在等待未提交。
(5)6s時,流水2成功越過數據庫查詢冪等校驗發起事務,此時流水1拿到數據庫連接,流水1和2兩個事務同時提交。
(6)由于數據庫未做唯一索引,且支付受理模塊打穿下層冪等原則,生成2個TXID,導致兩事務同時提交成功。
(7)收益結轉重復記賬,用戶多了一筆收入。
圖4-2 數據庫分布式鎖超時并發控制失效
深入分析
完成了整個問題的過程逆推后,開發人員進一步分析,發現問題真正的原因還是在系統設計上。如圖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 分布式鎖超時并發控制時間軸
方案二驗證有效。
小結
資金安全無小事,而冪等控制又是資金安全中的重中之重。回顧本文案例,從問題分析定位,到整個邏輯的梳理清洗,其中涉及了三個時間軸的相互作用,再加上事務、分布式鎖、重試等,整個問題發生的邏輯還是比較復雜的。因此,在系統并發冪等控制設計中,單純的分布式鎖并不具備嚴格控制并發冪等的作用,建議在系統設計時,將第三方唯一性的冪等控制作為冪等控制的兜底方案,控制好這道冪等防線,這樣不論業務如何設計,就萬變不離其宗了。
總結
以上是生活随笔為你收集整理的如何高效排查系统故障?一分钱引发的系统设计“踩坑”案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 燃!阿里AI技术取得重大突破:连破中、英
- 下一篇: 如何降低90%Java垃圾回收时间?以阿