主題: 支付類冪等性測試分享
HI all:
最近在測試掃碼支付的時候,嘗試測試了支付接口的冪等性,結合實例和網上資料一並分享給大家。
-
冪等性概念
-
數學中的定義:其任意多次執行所產生的影響均與一次執行的影響相同。比如f(f(x)) = f(x).
-
HTTP協議中的定義:在HTTP/1.1規范中冪等性的定義是:HTTP方法的冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。其中GET,PUT, DELETE
方法是符合冪等性的,因為獲取資源和刪除資源無論執行多少次,產生的效果是一樣的。Post方法不符合冪等性。
那么冪等性為什么在金融類的支付,扣款,提現中如此重要呢。一句話是保證資金的安全性,提現不能讓用戶成功提現兩筆,支付也同樣不能。
適用場景:
1.前端重復提交選中的數據,應該后台只產生對應這個數據的一個反應結果。
2.我們發起一筆付款請求,應該只扣用戶賬戶一次錢,當遇到網絡重發或系統bug重發,也應該只扣一次錢;
3.創建業務訂單,一次業務請求只能創建一個,創建多個就會出大問題。
4.客戶對一筆合同還款,一次業務請求只能成功一次,成功兩次公司會窮死的(囧)
比如假設有一個從賬戶取錢的遠程API(可以是HTTP的,也可以不是),我們暫時用類函數的方式記為:
如何服務端返回取現成功的OK請求丟失了,客戶端再發一次請求,如果服務端沒有做冪等性設計,那不是被取現成功兩次 amount金額被減了兩次。
-
如何測試冪等性
冪等性如此重要,那我們在具體的測試執行中該如何設計用例場景呢。主要有以下幾種方法(有其他方法手段,歡迎補充)
-
前端重復快速點擊(一般前端會做提交)
-
網絡重發,比如在掃碼支付時,商戶在掃碼時,先斷網掃碼一次再重連掃碼
-
對同一筆訂單,不同商戶同時掃碼
-
對同一筆業務並發請求,比如並發提現
-
Nginx重發情況(這種情況還沒試過,要對nginx比較熟悉才行)
-
開發如何保證冪等性(歡迎開發大神提供更多解決方案)
-
token機制,防止頁面重復提交
-
悲觀鎖獲取數據的時候加鎖獲取select * from table_xxx where id='xxx' for update;注意:id字段一定是主鍵或者唯一索引,不然是鎖表
-
樂觀鎖
樂觀鎖只是在更新數據那一刻鎖表,其他時間不鎖表,所以相對於悲觀鎖,效率更高。
-
分布式鎖
-
狀態機冪等
更多參考資料:
1. 高並發的核心技術-冪等的實現方案
2. RocketMQ支持事務消息機制
謝謝~~~~~
工作中測試同事分享文章
