接口冪等性


一、什么是接口冪等性

所謂接口冪等性再就是客戶端的一次請求或多次請求同一個資源產生相同的副作用。如當我們查詢員工信息的時候,不論查多少次反會的結果相同,都是某個員工的信息。注意這里的相同並不是返回的信息是一樣的,因為信息可能會被修改,所以說相同,都是這個員工的信息。

二、為什么需要接口冪等性

在高並發的場景中,可能由於網絡延遲導致調用方沒有及時的收到服務方的響應結果 。舉個栗子,比如我們正在開發一個網上下單系統,當用戶使用我們的系統下單時,我們就需要對該訂單進行發貨處理,我們的網上下單系統會調用發貨系統進行發貨,假如下單系統調用發貨系統時網絡延遲造成前端沒響應,用戶又點了幾次,這樣就會造成重復下單的問題。

在分布式場景中,假如你的某個服務部署了5台機器,前端請求調用,因為某些原因可能重復請求了兩次,因為負載均衡算法落到了倆台機器上,可能會導致重復的業務處理邏輯;又比如說 在使用微服務組件,例如zuul,feign等 在超時的情況下會有重試機制,也可能會導致重試請求多次,如果業務方沒有做好冪等性,就會導致業務處理出錯,比如多次創建訂單,多次扣款,這些坑都會導致很嚴重的問題

三、影響冪等性的操作

在增刪改查四個操作中,尤其要注意增加和修改操作。

1、查詢操作

查詢對結果是不會有改變的,查詢一次和查詢多次沒什么兩樣,因此查詢操作具有天然的冪等性。

2、刪除操作

刪除一次和多次刪除都是把數據刪除。(注意可能返回結果不一樣,刪除的數據不存在,返回0,刪除的數據多條,返回結果多個,在不考慮返回結果的情況下,刪除操作也是具有冪等性的)。

3、更新操作

修改在大多場景下結果一樣,但是如果是增量修改是需要保證冪等性的,如下例子:

把表中id為XXX的記錄的A字段值設置為1,這種操作不管執行多少次都是冪等的
把表中id為XXX的記錄的A字段值增加1,這種操作就不是冪等的

4、添加操作

增加在重復提交的場景下會出現冪等性問題,如以上的支付問題

 

四、保證冪等性

要保證冪等性,就要保證每次請求有唯一的標識,比如用戶id、訂單號、流水號等。
對於第一次請求的時候,就必須要將唯一標識存放到數據庫MySQL或者redis等存儲中。后端服務收到請求,在進行業務處理之前,必須要先檢查這個唯一標識是否存在,如果存在,就可以判定已經此次請求已經處理過,不需要進行重復處理。
在實際開發中保證接口冪等性主要有以下幾個方案,可供參考

(1) 對於要操作的數據,在表中建立唯一索引字段。特別適用於進行一些新增數據,插入操作,比如創建訂單,在MySQL業務表中建立唯一索引字段,當請求過來的時候,如果是多次重試,就違反了表中索引字段的唯一性,就會報錯,業務自然會回滾。

(2) 還是基於MySQL數據庫,在業務表中增加版本號字段,調用方每次請求數據的時候可以先獲取version版本號,然后多傳入一個version版本號字段,業務方在處理請求的時候,會去查新數據庫中的version版本號,判斷一下倆個version的值是否相同,如果version不相同,說明本次請求已經處理過了,直接返回。

(3) 基於業務狀態進行判斷,設計接口的時候,對於每一個業務操作能否操作,設置可以執行的狀態,比如使用狀態機模式,便於檢查業務對象的狀態,接受到請求要進行一些業務處理時,可以先行判斷業務對象的狀態,是否滿足執行操作的條件,如果當前操作已經執行過了,那么狀態就會發生變化,也就不能進行當前操作,直接返回。

(4) 可以在外部存儲中設置一個單獨的去重表,比如使用redis,每次請求過來,生成唯一的key。重復請求過來的時候判斷一下這個key是否存在,如果存在,說明存在重復調用,直接返回。實現接口的冪等性 是業務接口方必須保證的基礎功能,特別是服務與服務間的調用,可以使得服務接口在異常請求情況下,仍然保證接口的准確性,數據的准確性。




免責聲明!

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



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