介面冪等性

2021-10-04 10:29:57 字數 2687 閱讀 7546

例如: 在http協議中,get請求,會得到同樣的資料

bool get_money(id, amount)

1引數:

id:使用者的賬戶

amount: 表示取多少錢

返回值:

true: 表示取錢成功

false: 表示取錢失敗

情景一:

1、一位使用者a 取100塊錢, 這個請求,傳送到了伺服器

2、伺服器正常的處理了這個請求,把使用者a的總額,減去了100塊錢, 這時,伺服器把處理結果返回給客戶端。

3、伺服器把處理結果,返回給客戶端,可是這時,由於網路不穩定, 導致客戶端沒有接受到伺服器返回的處理結果,這時,使用者(或者客戶端)進行重試,同樣的請求又到伺服器,伺服器又在使用者a的總額中,減去了100塊錢........

使用者a 取了100塊錢, 銀行卻扣了 200.................

這個問題的解決方案是:

客戶端在呼叫這個介面,傳入乙個流水號,

bool get_money(id, amount, serial_number)

對於同乙個操作(同一筆業務)流水號不變(在不同操作中,必須保證流水號的唯一性),

這時,如果伺服器遇到上面那種情況,只需要判斷客戶端傳過來的這個流水號,是否已經操作(處理)過了,如果已經處理過了,就直接把處理結果返回給客戶端

這樣,就不存在上面的問題了

冪等性原本是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。用在程式設計領域,則意為對同乙個系統,使用同樣的條件,一次請求和重複的多次請求對系統資源的影響是一致的

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

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

不同的需求,會有不一樣的解決方案,難度和成本也不一樣。

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

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

冪等性是解決這類問題的方案之一,所以在電商,銀行,網際網路金融等對資料準確性要求很高的領域中,這一特性具有十分重要的地位。

1. mvcc:####

多版本併發控制,樂觀鎖的一種實現,在資料更新時需要去比較持有資料的版本號,版本號不一致的操作無法成功。例如部落格點讚次數自動+1的介面:

public boolean addcount(long id, long version);
update blogtable set count= count+1,version=version+1 where id=321 and version=123
每乙個version只有一次執行成功的機會,一旦失敗必須重新獲取。

2. 去重表:####

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

例子還是上述的部落格點讚問題,要想防止乙個人重複點讚,可以設計一張表,將部落格id與使用者id繫結建立唯一索引,每當使用者點讚時就往表中寫入一條資料,這樣重複點讚的資料就無法寫入。

3. token機制:####

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

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

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

冪等性是分布式領域的一把利刃,每乙個有志與分布式領域的程式設計師都應該熟悉它的設計思想。

1、樂觀鎖

多版本併發控制,該策略主要使用 update with condition(更新帶條件來防止)來保證多次外部請求呼叫對系統的影響是一致的。

在系統設計的過程中,合理的使用樂觀鎖,通過 version 或者 updatetime(timestamp)等其他條件,來做樂觀鎖的判斷條件,這

樣保證更新操作即使在併發的情況下,也不會有太大的問題

2、token機制,防止頁面重複提交

資料提交前要向服務的申請 token,token 放到 redis 中,設定token 有效時間

客戶端每次在呼叫介面的時候,需要在請求頭中,傳遞令牌引數,每次令牌只能用一次,提交資料後後台校驗 token,同時刪除

token,生成新的 token 返回

3、資料庫唯一索引

特殊的表單,可以使用資料唯一索引,重複插入報錯,進行限制重複提交

介面冪等性

token機制 服務端提供傳送token的介面,在分析業務的時候,哪些業務是存在冪等問題的,就必須在執行業務前,先去獲取token,伺服器會把token儲存到人redis中 然後呼叫業務介面請求時,把token攜帶過去,一般放在請求頭 伺服器判斷token是否存在redis中,存在表示第一次請求,然...

介面冪等性

冪等性是系統服務對外一種承諾,承諾只要呼叫介面成功,外部多次呼叫對系統的影響是一致的。宣告為冪等的服務會認為外部呼叫失敗是常態,並且失敗之後必然會有重試 select col1 from tab1 wher col2 2,無論執行多少次都不會改變狀態,是天然的冪等。update tab1 set c...

冪等性學習及介面的冪等性

冪等性學習 一 什麼是冪等性 在這裡需要有以下幾個問題需要注意 2 冪等性不僅僅只是一次或者多次請求的時候對資源沒有 比如根據id對資料庫的查詢操作,此操作對資料庫沒有增刪改,所以多次查詢操作對資料庫結果是沒有任何影響的 3 冪等性還包括了第一次請求資源的時候,對資源產生了 但是在以後多次同樣的請求...