在系統對接過程中,當出現接口調用異常的情況時,程序員可能會用一些專業術語來答疑......對于0基礎同學,自然是需要自行百度一番,學習一下!?
接下來,先學習【冪等】
PS: 小白參考1.1~1.4內容即可,達到基本理解。
1.1 冪等是什么
簡單講,就是同一個操作,不管執行多少次(1次或者N次),最終產生的效果都和只執行1次的效果一樣。
即 “做一次”和“做N次”的效果是等價的。
1.2 冪等的重要性
在網絡世界,特別涉及到訂單、支付、重要狀態變更時,因為未知因素“不小心重復執行”是非常非常常見的事情。如:
- 做了觸發按鈕,不小心點擊了多次;
- 網絡信號不好,請求發送了2次
- 系統在處理時 卡頓崩潰了,恢復后重新處理了一次等等
如果沒有冪等處理,那這些重復操作會導致各種后果:重復扣錢;重復創建訂單(只要1個,但是生成了多個);狀態錯亂(已發貨變成待發貨)等
1.3 如何實現冪等?
通過具體的場景示例
1.扣款接口(需要冪等性)——錢不能多扣!
-
操作:?你用手機支付買一杯奶茶,點擊“確認支付”按鈕。
-
冪等要求:?無論這個“確認支付”的指令因為網絡卡頓、手抖等原因被系統收到了1次還是100次,你的賬戶應該只被扣一次奶茶的錢(比如20元),奶茶店也只收到一次20元。
-
非冪等的可怕后果:?如果接口不冪等,系統收到兩次“確認支付”指令,就可能扣你40元!奶茶店也可能收到40元或者系統混亂。這絕對不行!
如何實現?
系統設計扣款接口時,需要有個機制 可識別到 “這是同一個訂單/交易”
-
給每個支付請求一個唯一“訂單號” (ID):就像快遞單號。
-
系統記錄處理過的訂單號:系統收到支付請求,先查這個訂單號是否處理過。
-
如果沒處理過:執行扣款、記錄狀態(已支付)、記下這個訂單號。
-
如果已經處理過:直接返回上次支付成功的結果(比如“支付成功,已扣款20元”),不再執行實際扣款操作!
-
-
結果:?用戶點了N次,只要訂單號一樣,系統只扣一次錢,每次都告訴你支付成功(效果等同于只執行一次)。
場景二:查詢余額接口 (天生冪等) - 查多少次都行!
-
-
操作:?你打開手機銀行APP,點擊“查詢余額”。
-
冪等體現:?你點1次,顯示余額是1000元。你手快點錯了,連續狂點10次“查詢余額”,每次返回的結果都還是顯示1000元(假設期間沒有其他交易)。查詢這個操作本身不會改變你的余額。做一次和做十次,結果都一樣(余額顯示1000元),沒有額外副作用。
-
為什么天生冪等??因為這個操作只是“讀”數據,不“寫”(修改)數據。讀操作通常不會改變系統狀態。
-
1.4?冪等性的關鍵點
- 核心目標:防止重復操作帶來壞影響,尤其是在會修改數據的操作上。(扣錢、下單、改狀態)
- 核心表現:同一個請求(通常有唯一標識/主鍵 來識別,eg:訂單號、流水號等),執行多次==執行1次的效果。
- 允許重復調用:但重復調用時,系統能識別出來并確保最終結果正確(要么和第一次結果一致要么不作任何修改)
- 重要性:這個是系統穩定的基準之一。不然系統數據會一團糟。
- 常見需要冪等的操作: 支付、創建訂單、更新狀態(如確認收貨)、退款等
- 常見天生冪等的操作:查詢、獲取信息
1.5?術語版解答
接口冪等性 (Idempotency)?是指:
一個操作(通常由 HTTP 方法表示)被設計成:當客戶端向服務器發送一次或多次具有相同參數的相同請求時,服務器端的最終狀態改變(或產生的副作用)是相同的,并且通常返回相同的響應結果。
關鍵點解析:
-
操作 (Operation):?指通過 API 接口執行的特定動作,如創建資源、更新資源、刪除資源、支付等。
-
多次相同請求 (Identical Requests):?請求的語義(意圖)和關鍵參數(通常包括一個唯一的冪等鍵?
Idempotency-Key
)必須完全相同。這些請求可能因網絡問題、客戶端重試、超時重發等原因而產生。 -
最終狀態/副作用 (State/Side Effects):?指操作在服務器端數據庫、文件系統或其他持久化存儲中引起的實際變化,以及可能觸發的后續流程(如發送通知、扣款等)。
-
效果相同 (Same Effect):
-
對于修改狀態的操作(
PUT
,?DELETE
, 特定?POST
):執行一次和多次,服務器資源最終達到的狀態是完全一致的。 -
對于不修改狀態的操作(
GET
,?HEAD
):多次執行總是返回相同的結果(假設資源在此期間未被其他操作修改)。
-
-
響應結果 (Response):?在多次執行中,服務器通常應返回相同的 HTTP 狀態碼和響應體(尤其是成功響應)。第一次執行成功后,后續重復請求應返回成功(如?
200 OK
?或?201 Created
)并可能包含首次執行的結果,而不是報錯(除非請求本身無效)。
實現冪等性的典型技術方案:
-
冪等鍵 (Idempotency Key):
-
客戶端在發送非冪等操作(如創建訂單的?
POST
)時,在請求頭(如?Idempotency-Key: <unique_value>
)或請求體中提供一個全局唯一的標識符(UUID 是最佳選擇)。 -
服務端存儲該 Key 與首次請求的響應結果。
-
當收到相同 Key 的請求時:
-
若 Key 存在且對應請求已完成:直接返回存儲的響應結果,不執行實際操作。
-
若 Key 存在但對應請求仍在處理中:返回?
409 Conflict
?或?425 Too Early
,提示客戶端稍后重試。 -
若 Key 不存在:正常處理請求,處理完成后存儲 Key 和響應結果。
-
-
-
唯一業務標識 (Unique Business Identifier):
-
利用業務本身的唯一標識(如訂單號、交易流水號、用戶名)作為冪等鍵。
-
服務端在處理請求前,檢查該唯一標識對應的資源是否已存在或操作是否已執行。
-
若已存在/已執行:返回已有資源或成功響應(實現冪等)。
-
若不存在/未執行:執行操作并創建資源/記錄狀態。
-
-
狀態機與樂觀鎖 (State Machine & Optimistic Locking):
-
定義資源明確的狀態(如?
待支付
?->?已支付
?->?已完成
)。 -
更新操作(如?
支付
)需要指定期望的當前狀態(如?待支付
)。 -
服務端檢查資源當前狀態是否與期望狀態一致:
-
一致:執行狀態轉換(如?
待支付
?->?已支付
),操作成功。 -
不一致(如狀態已是?
已支付
):說明操作已執行過,返回當前狀態(實現冪等)。常配合版本號(ETag)或更新時間戳實現樂觀鎖。
-
-