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

  WEB資源或API方法的冪等性是指一次和屢次請求某一個資源應該具備一樣的反作用。冪等性是系統的接口對外一種承諾(而不是實現), 承諾只要調用接口成功, 外部屢次調用對系統的影響是一致的。冪等性是分佈式系統設計中的一個重要概念,對超時處理、系統恢復等具備重要意義。聲明爲冪等的接口會認爲外部調用失敗是常態, 而且失敗以後必然會有重試。例如,在因網絡中斷等緣由致使請求方未能收到請求返回值的狀況下,若是該資源具有冪等性,請求方只須要從新請求便可,而無需擔憂重複調用會產生錯誤。實際上,咱們經常使用的HTTP協議的方法是具備冪等性語義要求的,好比:get方法用於獲取資源,不該有反作用,所以是冪等的;post方法用於建立資源,每次請求都會產生新的資源,所以不具有冪等性;put方法用於更新資源,是冪等的;delete方法用於刪除資源,也是冪等的。nginx

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

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來防止,其餘操做對對象的併發更新,致使更新丟失。爲了不失敗,一般須要必定的重試機制。redis

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

3.悲觀鎖api

  select for update,整個執行過程當中鎖定該訂單對應的記錄。注意:這種在DB讀大於寫的狀況下儘可能少用。網絡

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

5.狀態機冪等
  在設計單據相關的業務,或者是任務相關的業務,確定會涉及到狀態機,就是業務單據上面有個狀態,狀態在不一樣的狀況下會發生變動,通常狀況下存在有限狀態機,這時候,若是狀態機已經處於下一個狀態,這時候來了一個上一個狀態的變動,理論上是不可以變動的,這樣的話,保證了有限狀態機的冪等。jvm

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在數據庫裏面作惟一索引,防止屢次付款,(併發時,只能處理一個請求)

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

相關文章
相關標籤/搜索