天天看點

【現網】記一次并發沖突導緻流量放大的生産問題

作者:小小怪下士的架構攻略

出處 :https://www.cnblogs.com/Detector/p/17602502.html

  • 事故現象
  • 轉賬
  • 業務背景介紹
  • 問題定位
  • 總結

事故現象

生産環境,轉賬相關請求失敗量暴增。

直接原因

現網多個重試請求同時到達 svr,導緻記憶體資料庫大量傳回時間戳沖突。業務方收到時間戳沖突,自動進行業務重試,服務内部也存在重試,導緻流量放大。

轉賬

首先我們一起了解一下轉賬。轉賬請求在支付場景中的應用頻率非常高,它是現代金融系統中的一個核心功能。在日常生活中,個人和企業都需要進行各種不同類型的轉賬:

  1. 個人間轉賬:朋友、家人之間進行的轉賬,如還款、借款、生日禮物贈送等。
  2. 工資支付:企業向員工支付工資、獎金等。
  3. 稅費繳納:向政府繳納所得稅、增值稅等稅費、政府退回多征收的稅費等。
  4. 跨境彙款:向國外的個人或企業進行的轉賬,如國際貿易、留學生彙款等。
  5. 投資與理财:向股票、基金、保險等金融産品進行的投資轉賬。
  6. 退款與賠付:商家或金融機構向客戶退還購物款項、保險理賠等。
  7. ...

随着移動支付、網上銀行等數字金融服務的普及,轉賬請求在支付場景中的應用頻率越來越高。人們可以随時随地進行轉賬,這背後離不開金融科技的發展帶來的更加便捷、安全、高效的轉賬過程。

業務背景介紹

背景一:轉賬流程

轉賬流程

轉賬常見流程:

【現網】記一次并發沖突導緻流量放大的生産問題

轉賬異常處理

當支付管道系統内部出現異常,比如給轉入方轉錢時遇到被調系統傳回逾時時:

  1. 系統自動重試: 在大多數情況下,支付管道系統會在短時間内自動重試轉賬操作,以確定交易成功。通常,系統會在一定時間内嘗試多次,直到轉賬成功或達到重試次數上限。
  2. 轉賬暫停: 如果系統在多次重試後仍然無法完成轉賬,支付管道可能會暫停該筆轉賬。在這種情況下,會通知轉出方關于轉賬暫停的原因,并可能建議轉出方稍後再次嘗試轉賬。
  3. ** 資金退回:** 如果系統在嘗試一定次數後仍無法完成轉賬,支付管道可能會将資金退回到轉出方的賬戶。轉出方可以選擇在支付管道系統恢複正常後重新發起轉賬。
  4. 客戶通知: 在上述情況下,銀行會通過短信、電話或電子郵件等方式通知轉出方關于轉賬失敗的原因。客戶可以根據銀行的建議采取相應措施。
  5. ...

總之,管道會盡力確定交易的順利進行。

轉賬異常處理流程圖

【現網】記一次并發沖突導緻流量放大的生産問題

背景二:賬戶系統合并

因為公司賬戶系統存在多套,同一個服務商在不同的業務都存在商業合作時,賬戶歸屬不同的系統。降本增效大背景下,相關業務完成了業務賬戶的融合,将同一個商戶在兩個系統上的商戶資訊進行整合,融合到同一個賬戶,友善客戶更好的維護,也友善客戶賬戶資金共享,保證業務不中斷。

改造後上層調用方會傳遞遷移前後兩套uin的參數來進行調用,賬戶系統通過查詢 uin 的映射關系和關系中的遷移狀态判斷實際操作的賬戶。

即兩個不同入口的請求都需要先查詢一次遷移關系,如果賬戶已經遷移,則使用遷移後的賬戶進行操作,這個邏輯同時适用于轉出方 和 轉入方, 是以流程圖上加上了查詢關系的邏輯 藍色部分。

如果操作過程中,賬戶狀态發生了變化,則内部進行重試。

【現網】記一次并發沖突導緻流量放大的生産問題

實際全流程:

【現網】記一次并發沖突導緻流量放大的生産問題

背景三:扣記憶體資料庫邏輯

為了支援高并發的需求,賬戶系統使用的是一個自研的緩存資料庫,資料庫内部有諸多邏輯,其中操作賬戶時,會先 get 資料,再 set 資料, get 的時候會拿到目前資料的的時間戳 和更新序列号,set 的時候,資料庫會校驗這個時間戳的合法性。

是以在請求出現并發時會出現這樣的情況:

【現網】記一次并發沖突導緻流量放大的生産問題

背景四:調用方重試邏輯

調用方除非遇到訂單重複、餘額不足等明确錯誤,不然會推送 MQ 進行重試。

問題定位

相信大家看完上面的背景和前面的現象描述已經知道了問題的原因:業務的重試和系統内部的重試邏輯出現了重疊,導緻了絕對并發(記憶體資料庫的get\set邏輯極快),但是因為涉及到多個系統,每次請求的 uuid 又完全一緻,導緻了定位鍊路過長,定位難度增大。最後在測試環境複現了很多次才複現出來。

總結

針對這個問題給我總結了以下幾點:

  1. 測試環境和生産環境的差異:測試環境很難完全模拟生産環境的各種情況,特别是在并發、性能和壓力測試方面。是以,我們需要更加關注這些方面的測試,并盡量使測試環境接近生産環境。
  2. 完善的測試用例:在設計測試用例時,需要考慮各種異常情況和邊緣條件,包括系統之間的互相調用、失敗重試等情況。這樣可以提高測試的覆寫率,降低類似問題的發生機率。
  3. 強化并發和壓力測試:在軟體測試過程中,應該重點關注并發和壓力測試,模拟大量使用者同時通路和操作,以便發現潛在的性能瓶頸和沖突問題。(常态化性能測試是一個非常好的切入點。後續會專門寫一篇部落格介紹如何進行常态化性能壓測。)
  4. 監控和日志分析:在生産環境中,應該加強對系統的監控和日志分析,以便及時發現并定位問題。同時,測試人員可以通過分析生産環境的監控和日志資料,了解系統在實際運作中的表現,進而改進測試政策。

以下是一些避免類似問題的發生的改進措施:

  1. 測試同學需要與開發團隊緊密合作,了解系統架構和互相調用的關系,以便更好地設計測試用例。
  2. 在系統設計和開發階段,可以引入容錯和熔斷機制,以應對失敗重試和請求放大等問題。測試工程師需要關注這些機制的實作,并在測試中驗證其有效性。
  3. 在測試計劃中明确測試範圍,包括并發測試、壓力測試和性能測試,確定測試環境盡量接近生産環境,有條件的可以使用真實的資料和場景進行測試(現網引流)。
  4. 對于失敗重試等可能會放大流量的邏輯,進行專項測試,模拟各種異常和故障情況(後續會專門寫一篇部落格介紹如何進行混沌注入),驗證系統的穩定性和健壯性。

繼續閱讀