Spring Boot 接口冪等插件使用

冪等概述

  • 冪等性原本是數學上的概念,即使公式:f(x)=f(f(x)) 能夠成立的數學性質。用在編程領域,則意爲對同一個系統,使用同樣的條件,一次請求和重複的多次請求對系統資源的影響是一致的。

  • 冪等性是分佈式系統設計中十分重要的概念,具有這一性質的接口在設計時總是秉持這樣的一種理念:調用接口發生異常並且重複嘗試時,總是會造成系統所無法承受的損失,所以必須阻止這種現象的發生

  • 實現冪等的方式很多,目前基於請求令牌機制適用範圍較廣。其核心思想是爲每一次操作生成一個唯一性的憑證,也就是 token。一個 token 在操作的每一個階段只有一次執行權,一旦執行成功則保存執行結果。對重複的請求,返回同一個結果(報錯)等。參考《冪等性淺談》

冪等處理實現

加入依賴

<dependency>
    <groupId>com.pig4cloud.plugin</groupId>
    <artifactId>idempotent-spring-boot-starter</artifactId>
    <version>0.0.1</version>
</dependency>

配置 Redis 鏈接

spring:
  redis:
    host: 127.0.0.1
    port: 6379

接口

@Idempotent(key = "#key", expireTime = 10, info = "請勿重複查詢")
@GetMapping("/test")
public String test(String key) {
    return "success";
}

測試

  • 10 個獨立線程請求

  • 執行查看結果,10 個請求只會有一個成功

  • 查看後臺異常報錯,9 個異常報錯滿足預期

idempotent 註解說明

  • key: 冪等操作的唯一標識,使用 spring el 表達式 用#來引用方法參數 。 可爲空則取當前 url + args 做請求的唯一標識

  • expireTime: 有效期 默認:1 有效期要大於程序執行時間,否則請求還是可能會進來

  • timeUnit: 時間單位 默認:s (秒)

  • info: 冪等失敗提示信息,可自定義

  • delKey: 是否在業務完成後刪除 key true:刪除 false:不刪除

冪等處理設計原理

流程設計參考

  • 1.請求開始前,根據 key 查詢 查到結果:報錯 未查到結果:存入 key-value-expireTime key=ip+url+args

  • 2.請求結束後,直接刪除 key 不管 key 是否存在,直接刪除 是否刪除,可配置

  • 3.expireTime 過期時間,防止一個請求卡死,會一直阻塞,超過過期時間,自動刪除 過期時間要大於業務執行時間,需要大概評估下;

  • 4.此方案直接切的是接口請求層面。

  • 5.過期時間需要大於業務執行時間,否則業務請求 1 進來還在執行中,前端未做遮罩,或者用戶跳轉頁面後再回來做重複請求 2,在業務層面上看,結果依舊是不符合預期的。

  • 6.建議 delKey = false。即使業務執行完,也不刪除 key,強制鎖 expireTime 的時間。預防 5 的情況發生。

  • 7.實現思路:同一個請求 ip 和接口,相同參數的請求,在 expireTime 內多次請求,只允許成功一次。

  • 8.頁面做遮罩,數據庫層面的唯一索引,先查詢再添加,等處理方式應該都處理下。

  • 9.此註解只用於冪等,不用於鎖,100 個併發這種壓測,會出現問題,在這種場景下也沒有意義,實際中用戶也不會出現 1s 或者 3s 內手動發送了 50 個或者 100 個重複請求,或者弱網下有 100 個重複請求;

總結

項目推薦: Spring Cloud 、Spring Security OAuth2的RBAC權限管理系統 歡迎關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章