介面冪等設計

2021-08-29 20:52:49 字數 1275 閱讀 8370

在系統設計時,經常會出現每次操作結果都需要一致的場景。比如典型的restful get請求 ,每次請求url/student/1(查詢第乙個學生),結果都是一樣的。當然排除再修改學生資訊後又查詢的情況。

介面冪等,通俗的定義可以為:每次同樣的請求操作該介面,得到的結果都是一樣的。

先給個場景,同樣的訂單編號發起兩筆支付,按道理資料庫裡面只能存乙份資料。

冪等的實現方式有很多種形式,目前就列舉幾種常見的介紹。

第一種:先查詢後插入。

首先通過查詢訂單表,如果庫里沒有這個訂單編號,就將該訂單的請求落到支付表。

分析:採用這種方式(先查後插),操作分了兩步,不是原子操作。如果該訂單沒有落庫,多執行緒環境下,a,b 兩個執行緒同時查詢都沒有記錄,就都往表裡插了記錄。

第二種:使用分布式鎖

由於第一種方案在多執行緒環境下可能會插入多條一樣的資料,那就先使用分布式鎖鎖住資源--訂單編號,然後再使用第一種方案。

分析:這樣確實控制住了多執行緒問題,但是引入了第三方元件,同時如果分布式鎖掛了,請求也就失效了,有點浪費請求資源(雖然這種情況不常出現)。

第三種:使用資料庫的唯一性約束(unique)

由於上面兩種方案都有所缺陷,那就考慮使用資料庫自帶的unique約束。在插入資料庫報唯一性約束錯誤時,編碼提示資料插入已成功。

分析:通過使用資料自帶的唯一性約束,將資料問題控制在了資料插入,而且只能有一次成功。相比前兩種,可用性更強。

第四種:分布式快取

使用分布式快取這種架構,比如redis。如果判斷redis已經存在key,肯定是不能去庫裡面插入資料了。

分析:如果分布式快取掛了,資料庫還是可以插入兩條一樣的資料。分布式快取起不到攔截作用!

第五種:唯一性約束(unique)+ 分布式快取

那有沒有好的方案呢?肯定有。

將每次插入成功的資料新增快取裡,如果快取中有了,那肯定是不能資料插入了(資料庫裡面也有了該資料),這樣就可以在高併發的情況下,防止大量請求打到資料庫,從而造成效能問題。就算分布式快取掛了,也可以退化為第三種方案。

如果快取是有限的,可以考慮將資料加過期時間,從而避免記憶體被打崩。

以後四種都是常見的解決冪等控制方案。

如果沒有高併發場景,第一種就可以很好的實現方案,簡潔且符合常規思路。

如果少量高併發場景,並且分布式鎖穩定,第二種,第四種方案也可以使用,請評估中介軟體維護問題。

如果要不想引入分布式鎖帶來的問題,可以使用第三種方案。

如果需要高效能,高可用,可以考慮第五種。

其實問題的解決方案都是和業務使用場景契合的,如果不好選,推薦使用第三種,真的簡單粗暴!

介面冪等性設計

在系統中,乙個介面執行多次,與執行一次的效果是一致的 冪等性的核心思想 通過唯一的業務單號保證冪等 update自身帶鎖。直接update不會出現併發修改問題。樂觀鎖是先查詢在修改 update 商品表 set 庫存 庫存 購買量 version 查詢version值 1 where version...

使用redis設計冪等介面

冪等 冪等性是系統的介面對外一種承諾 而不是實現 承諾只要呼叫介面成功,外部多次呼叫對系統的影響是一致的.宣告為冪等的介面會認為外部呼叫失敗是常態,並且失敗之後必然會有重試 舉個例子 有乙個訂單系統,對外提供了乙個處理介面,如果有個訂單001是要扣除使用者的100塊錢,那麼訂單001被多次呼叫,也只...

關於介面冪等性的設計

關於支付相關,訂單相關以及一些涉及費用的操作在業務上都是要求介面具有冪等性的。否則在高併發的場景下,同一筆交易請求多次,則會造成損失,這是不可忽視的錯誤。例如一筆訂單,因為網路或者操作的原因,造成同時發起了兩次申請。一般的介面設計中,對於重 起的交易都是先查詢是否存在這筆訂單,如果不存在,則繼續進行...