冪等簡單的定義:redis
系統中的屢次操做,無論多少次,都應該產生同樣的效果,或返回同樣的效果。數據庫
好比實際的業務請求爲建立一個活動,理論上須要根據業務形態開發冪等建立活動的接口,這樣在相同參數調用接口屢次建立活動時,只能夠建立成功一次。安全
因爲查詢天生的是冪等請求,因此針對於查詢場景能夠不作業務角度的冪等約束,查詢冪等的約束可能是針對於資源控制,安全防刷,流控來作的。分佈式
試想有這樣一個場景:
A系統傳遞userId和活動Id調用B系統發券,若是B系統發券成功,須要返回A系統本次發券userId和發券code。
因爲B系統須要對本身發出去的券進行限制防止超發,因此會根據userId和code創建冪等攔截。
可是A系統的調用次數是不受信的,B系統會對屢次重複的請求作攔截,這樣形成一部分A的請求爲無效請求,被直接打回。
可是A系統接受B系統的返回值中是須要code的,若是沒有收到code,A系統會認爲調用B系統失敗,進行重試,結果就形成了A系統不停被重試,B系統攔截無效請求,返回默認值,A再重試的死循環。優化
解決這個場景問題有兩種方法:設計
第一種方案明顯的缺點在於,針對於重複發送的請求都會轉化成一次查詢操做,這樣無形中加大了對於B系統資源的浪費,同時因爲發券接口邏輯中引入了查詢邏輯,形成此接口違反了「單一職能原則」,在將來圍繞這個接口的新業務邏輯形成的代碼修改時,好比容許對同一個用戶發送多張券,可能出現潛在的bug問題。code
第二種方案則是我選擇的更好的方案,也是更支持的方案,一個接口最好只作一件事,這樣一個接口只作發券,同時對於屢次重複發券作請求攔截,沒有必要放無效請求到系統核心邏輯中,更沒有必要所以引入查詢邏輯消耗系統資源。
在調用B系統發券接口由於攔截重複請求,返回重複請求狀態碼後,系統A調用B系統的查詢接口,進行已發送code的查詢,這樣在使用角度和後期業務迭代角度及系統資源使用和將來優化角度來講,都存在必定的空間,而不會形成代碼複雜度提高引入隱患bug。索引
針對於冪等操做還有以下幾種方案:token