接口的冪等性指的是:同一個接口,多次發出同一個請求,必須保證操作只執行一次。
保證接口冪等性的方式有多種,下面列舉幾種常用的。
1. token機制
/--------\                     /--------\                               /-------\
|        |-----1.獲取token---->|        |                               |       |
| client |<----3.返回token-----| server |-----2.生成token,存入redis---->| redis |
|        |-----4.攜帶token---->|        |                               |       |
\--------/                     \--------/                               \-------/
                                 |
                                 |
                                 v
                           判斷token是否存在?  ----------不存在--------> 代表重復請求,不進行業務處理
                                 |
                                存在
                                 v
                          刪除token,進行業務處理
2. 使用Post/Redirect/Get模式
在提交后執行頁面重定向,這就是所謂的Post-Redirect-Get(PRG)模式,簡單來說就是當用戶提交連表單后,跳轉到一個重定向的信息頁面,這樣就避免用戶按F5刷新導致的重復提交,而且也不會出現瀏覽器表單重復提交的警告,也能消除按瀏覽器前進和后退導致同樣重復提交的問題。
3.樂觀鎖
如果更新已有數據,可以進行加鎖更新,也可以設計表結構時使用樂觀鎖,通過version來做樂觀鎖,這樣既能保證執行效率,又能保證冪等, 樂觀鎖的version版本在更新業務數據要自增。
4. 緩沖隊列
將請求都快速地接收下來后放入緩沖隊列中,后續使用異步任務處理隊列中的數據,過濾掉重復的請求,該解決方案優點是同步處理改成異步處理、高吞吐量,缺點則是不能及時地返回請求結果,需要后續輪詢得處理結果。
除了上面這幾種方式之外,還有其他方法也可以達此目的。
異步接口
接口執行異步任務保證冪等性的含義是,客戶端調用接口,接口啟動異步任務后返回給客戶端,怎么保證異步任務正在執行過程中接口被重復調用,實際的異步任務邏輯只執行一次?
有兩種方式解決:
1. 接口端過濾:這個問題關在在于重復調用,因此在接口端區分出某兩次調用是否是重復調用就可以解決這個問題,因此可以通過集中式存儲,保存請求記錄,服務端在收到請求后,用原子性查詢和保存操作,保證對于重復的請求只保存一個,這樣就算是分布式場景,其他節點收到請求后也可以通過集中存儲查詢此次調用是否是重復調用。
2. 異步任務端校驗:如果不在接口段過濾,在創建異步任務時,可以采用剛才提到的緩沖隊列,過濾掉重復請求,對于分布式環境可以采用分布式緩存系統實現。