《專案實戰問題百問百答》02—冪等性及解決方案

作者按:《專案實戰問題百問百答》系列,真實記錄專案實踐中所見、所思、所想。歡迎參與和分享,讓我們一起成長。

冪等性概念:

冪等性原本是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。

在程式設計中一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同。

冪等函式,或冪等方法,是指可以使用相同引數重複執行,並能獲得相同結果的函式。這些函式不會影響系統狀態,也不用擔心重複執行會對系統造成改變。例如,“setTrue()”函式就是一個冪等函式,無論多次執行,其結果都是一樣的。

冪等性是分散式系統設計中十分重要的概念,具有這一性質的介面在設計時總是秉持這樣的一種理念:呼叫介面發生異常並且重複嘗試時,總是會造成系統所無法承受的損失,所以必須阻止這種現象的發生。

冪等有兩個維度:一是空間維度上的冪等,即冪等物件的範圍,是個人還是機構,是某一次交易還是某種型別的交易。。。二是時間維度上的冪等,即冪等的保證時間,是幾秒、幾分鐘還是永久性的。。。

試想這樣的一種場景:在電商平臺上支付後,因為網路原因導致系統提示你支付失敗,於是你又重新付款了一次,等完成後檢查網銀髮現被系統扣了兩次款,這是一種什麼樣的體驗?

造成上述問題的原因可能有很多,比如第一次付款時實際支付成功,但是資訊返回時網路中斷導致系統誤判;又比如第一次付款的確失敗了,但第二次付款時發生意外,導致支付請求被重複傳送等等。在一次支付的過程中,每個環節都有可能會發生問題,我們要如何規避這類問題引發的風險?

冪等的常用思路

1。 資料版本:

多版本併發控制,樂觀鎖的一種實現,在資料更新時需要去比較持有資料的版本號,版本號不一致的操作無法成功。

每一個version只有一次執行成功的機會,一旦失敗必須重新獲取。

2。 去重表:

利用資料庫表單的特性來實現冪等,常用的一個思路是在表上構建唯一性索引,保證某一類資料一旦執行完畢,後續同樣的請求再也無法成功寫入。

3。 TOKEN機制:

這種機制就比較重要了,適用範圍較廣,有多種不同的實現方式。其核心思想是為每一次操作生成一個唯一性的憑證,也就是token。一個token在操作的每一個階段只有一次執行權,一旦執行成功則儲存執行結果。對重複的請求,返回同一個結果。

以電商平臺為例子,電商平臺上的訂單id就是最適合的token。當用戶下單時,會經歷多個環節,比如生成訂單,減庫存,減優惠券等等。

每一個環節執行時都先檢測一下該訂單id是否已經執行過這一步驟,對未執行的請求,執行操作並快取結果,而對已經執行過的id,則直接返回之前的執行結果,不做任何操作。這樣可以在最大程度上避免操作的重複執行問題,快取起來的執行結果也能用於事務的控制等。

例如,設計一個微服務介面的的冪等性:

第一步:生成Token然後放入Redis中儲存。

第二步 :在頁面載入的時候,將Token放入隱藏域中儲存。

第三步:也是解決冪等性最重要的一個環節,當你點選提交的時候,隱藏域中的Token會和Redis中的Token相對比,如果Token一致,那則會提交資料成功,並刪除該Token。

最後,如果使用者再次提交,隱藏域中則沒有和Redis中對應的Token,這就達到了解決微服務中產生的冪等性問題了。

《專案實戰問題百問百答》02—冪等性及解決方案