分布式系統---冪等性設計


  WEB資源或API方法的冪等性是指一次和多次請求某一個資源應該具有同樣的副作用。冪等性是系統的接口對外一種承諾(而不是實現), 承諾只要調用接口成功, 外部多次調用對系統的影響是一致的。冪等性是分布式系統設計中的一個重要概念,對超時處理、系統恢復等具有重要意義。聲明為冪等的接口會認為外部調用失敗是常態, 並且失敗之后必然會有重試。例如,在因網絡中斷等原因導致請求方未能收到請求返回值的情況下,如果該資源具備冪等性,請求方只需要重新請求即可,而無需擔心重復調用會產生錯誤。實際上,我們常用的HTTP協議的方法是具有冪等性語義要求的,比如:get方法用於獲取資源,不應有副作用,因此是冪等的;post方法用於創建資源,每次請求都會產生新的資源,因此不具備冪等性;put方法用於更新資源,是冪等的;delete方法用於刪除資源,也是冪等的。

常見用來保證冪等的手段:

1.MVCC方案
  多版本並發控制,該策略主要使用update with condition(更新帶條件來防止)來保證多次外部請求調用對系統的影響是一致的。在系統設計的過程中,合理的使用樂觀鎖,通過version或者updateTime(timestamp)等其他條件,來做樂觀鎖的判斷條件,這樣保證更新操作即使在並發的情況下,也不會有太大的問題。例如

select * from tablename where condition=#condition# //取出要跟新的對象,帶有版本versoin
update tableName set name=#name#,version=version+1 where version=#version#

  在更新的過程中利用version來防止,其他操作對對象的並發更新,導致更新丟失。為了避免失敗,通常需要一定的重試機制。

2.去重表
  在插入數據的時候,插入去重表,利用數據庫的唯一索引特性,保證唯一的邏輯。

3.悲觀鎖

  select for update,整個執行過程中鎖定該訂單對應的記錄。注意:這種在DB讀大於寫的情況下盡量少用。

4. select + insert
  並發不高的后台系統,或者一些任務JOB,為了支持冪等,支持重復執行,簡單的處理方法是,先查詢下一些關鍵數據,判斷是否已經執行過,在進行業務處理,就可以了。注意:核心高並發流程不要用這種方法。

5.狀態機冪等
  在設計單據相關的業務,或者是任務相關的業務,肯定會涉及到狀態機,就是業務單據上面有個狀態,狀態在不同的情況下會發生變更,一般情況下存在有限狀態機,這時候,如果狀態機已經處於下一個狀態,這時候來了一個上一個狀態的變更,理論上是不能夠變更的,這樣的話,保證了有限狀態機的冪等。

6. token機制,防止頁面重復提交

  業務要求:頁面的數據只能被點擊提交一次
  發生原因:由於重復點擊或者網絡重發,或者nginx重發等情況會導致數據被重復提交
解決辦法:

  • 集群環境:采用token加redis(redis單線程的,處理需要排隊)
  • 單JVM環境:采用token加redis或token加jvm內存

處理流程:

  • 數據提交前要向服務的申請token,token放到redis或jvm內存,token有效時間
  • 提交后后台校驗token,同時刪除token,生成新的token返回

  token特點:要申請,一次有效性,可以限流 

7. 對外提供接口的api如何保證冪等 

  如銀聯提供的付款接口:需要接入商戶提交付款請求時附帶:source來源,seq序列號。source+seq在數據庫里面做唯一索引,防止多次付款,(並發時,只能處理一個請求)

  總結: 冪等性應該是合格程序員的一個基因,在設計系統時,是首要考慮的問題,尤其是在像支付寶,銀行,互聯網金融公司等涉及的都是錢的系統,既要高效,數據也要准確,所以不能出現多扣款,多打款等問題,這樣會很難處理,用戶體驗也不好 。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM