一、什么是冪等性?
在數學里,冪等有兩種主要的定義。
- 在某二元運算下,冪等元素是指被自己重復運算的結果等于它自己的元素。例如,乘法下唯一兩個冪等實數為0和1。
- 某一元運算為冪等的時,其作用在任一元素兩次后會和其作用一次的結果相同。例如,高斯符號便是冪等的。
在計算機領域,冪等性指多次操作對系統產生的影響與一次操作相同。舉個例子,假設要刪除用戶A,無論請求多少次,操作結果都是刪除用戶A,而不會刪除用戶B。
在RESTful風格的接口中,冪等性表現在HTTP請求方法中:
-
GET
冪等,即要獲取用戶A的信息,多次請求系統,返回的皆是用戶A的信息。是返回結果相同而不是返回內容相同。 -
POST
非冪等,用戶注冊,多次調用接口,會新增多條用戶數據。 -
PUT
冪等,put請求與post的區別是,post請求傾向于新增數據,而put請求傾向于更新數據,如果數據不存在則會根據客戶端提供的完整數據資源創建數據。所以對于put操作來說,多次調用接口產生的結果是一樣的,即客戶端提交的數據都會被更新到系統中。 -
PATCH
非冪等,patch是對put的補充。顧名思義patch即補丁,用于更新子資源的部分內容,同樣地,如果要更新的數據不存在則允許創建數據。可以發現patch和put非常相似,那為什么put是冪等的,而patch非冪等呢?因為patch允許根據客戶端提供的某個值動態計算更新內容,例如每次調用某個參數+1,則多次調用會產生不同結果。
二、接口中的冪等性
無論是微服務中各個子系統相互之間的調用,還是客戶端對服務端的調用,都存在網絡延遲等問題,會導致重復請求接口,這時候接口就需要支持冪等性,來防止出現問題。
最經典的一個例子就是訂單支付操作,假如因為網絡問題等因素導致用戶重復提交,這時候不可能對用戶重復扣款,否則客服電話就要被打爆了。
那么服務端接口對于冪等性應該如何支持呢?有如下兩個思路:
1. 邏輯判斷處理
支付時對訂單狀態進行判斷,如果該訂單已支付,則不應該再次進行扣款操作。
2. 請求帶ticket
異步請求獲取ticket,此ticket是唯一并且一次性的,保存在頁面中,每次發起支付請求都帶上ticket,后端檢查ticket,若支付成功則刪除ticket,這樣就算重復提交也不會導致重復扣款。