欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實現(xiàn)接口冪等性的4種方案

 更新時間:2021年03月07日 14:25:27   作者:JeffDuuuuu  
這篇文章主要介紹了SpringBoot實現(xiàn)接口冪等性的4種方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

一、什么是冪等性

冪等是一個數(shù)學與計算機學概念,在數(shù)學中某一元運算為冪等時,其作用在任一元素兩次后會和其作用一次的結果相同。
在計算機中編程中,一個冪等操作的特點是其任意多次執(zhí)行所產生的影響均與一次執(zhí)行的影響相同。冪等函數(shù)或冪等方法是指可以使用相同參數(shù)重復執(zhí)行,并能獲得相同結果的函數(shù)。這些函數(shù)不會影響系統(tǒng)狀態(tài),也不用擔心重復執(zhí)行會對系統(tǒng)造成改變。

二、什么是接口冪等性

在HTTP/1.1中,對冪等性進行了定義。它描述了一次和多次請求某一個資源對于資源本身應該具有同樣的結果(網絡超時等問題除外),即第一次請求的時候對資源產生了副作用,但是以后的多次請求都不會再對資源產生副作用。
這里的副作用是不會對結果產生破壞或者產生不可預料的結果。也就是說,其任意多次執(zhí)行對資源本身所產生的影響均與一次執(zhí)行的影響相同。

三、為什么需要實現(xiàn)冪等性

在接口調用時一般情況下都能正常返回信息不會重復提交,不過在遇見以下情況時可以就會出現(xiàn)問題,如:

  • 前端重復提交表單:在填寫一些表格時候,用戶填寫完成提交,很多時候會因網絡波動沒有及時對用戶做出提交成功響應,致使用戶認為沒有成功提交,然后一直點提交按鈕,這時就會發(fā)生重復提交表單請求。
  • 用戶惡意進行刷單:例如在實現(xiàn)用戶投票這種功能時,如果用戶針對一個用戶進行重復提交投票,這樣會導致接口接收到用戶重復提交的投票信息,這樣會使投票結果與事實嚴重不符。
  • 接口超時重復提交:很多時候 HTTP 客戶端工具都默認開啟超時重試的機制,尤其是第三方調用接口時候,為了防止網絡波動超時等造成的請求失敗,都會添加重試機制,導致一個請求提交多次。
  • 消息進行重復消費:當使用 MQ 消息中間件時候,如果發(fā)生消息中間件出現(xiàn)錯誤未及時提交消費信息,導致發(fā)生重復消費。

使用冪等性最大的優(yōu)勢在于使接口保證任何冪等性操作,免去因重試等造成系統(tǒng)產生的未知的問題。

四、引入冪等性后對系統(tǒng)的影響

冪等性是為了簡化客戶端邏輯處理,能放置重復提交等操作,但卻增加了服務端的邏輯復雜性和成本,其主要是:

  • 把并行執(zhí)行的功能改為串行執(zhí)行,降低了執(zhí)行效率。
  • 增加了額外控制冪等的業(yè)務邏輯,復雜化了業(yè)務功能;

所以在使用時候需要考慮是否引入冪等性的必要性,根據(jù)實際業(yè)務場景具體分析,除了業(yè)務上的特殊要求外,一般情況下不需要引入的接口冪等性。

五、Restful API 接口的冪等性

現(xiàn)在流行的 Restful 推薦的幾種 HTTP 接口方法中,分別存在冪等行與不能保證冪等的方法,如下:

  • √滿足冪等
  • x不滿足冪等
  • -可能滿足也可能不滿足冪等,根據(jù)實際業(yè)務邏輯有關

方法類型 是否冪等 描述
Get Get 方法用于獲取資源。其一般不會也不應當對系統(tǒng)資源進行改變,所以是冪等的。
Post × Post 方法一般用于創(chuàng)建新的資源。其每次執(zhí)行都會新增數(shù)據(jù),所以不是冪等的。
Put - Put 方法一般用于修改資源。該操作則分情況來判斷是不是滿足冪等,更新操作中直接根據(jù)某個值進行更新,也能保持冪等。不過執(zhí)行累加操作的更新是非冪等。
Delete - Delete 方法一般用于刪除資源。該操作則分情況來判斷是不是滿足冪等,當根據(jù)唯一值進行刪除時,刪除同一個數(shù)據(jù)多次執(zhí)行效果一樣。不過需要注意,帶查詢條件的刪除則就不一定滿足冪等了。例如在根據(jù)條件刪除一批數(shù)據(jù)后,這時候新增加了一條數(shù)據(jù)也滿足條件,然后又執(zhí)行了一次刪除,那么將會導致新增加的這條滿足條件數(shù)據(jù)也被刪除。

六、如何實現(xiàn)冪等性

方案一:數(shù)據(jù)庫唯一主鍵

方案描述

數(shù)據(jù)庫唯一主鍵的實現(xiàn)主要是利用數(shù)據(jù)庫中主鍵唯一約束的特性,一般來說唯一主鍵比較適用于“插入”時的冪等性,其能保證一張表中只能存在一條帶該唯一主鍵的記錄。
使用數(shù)據(jù)庫唯一主鍵完成冪等性時需要注意的是,該主鍵一般來說并不是使用數(shù)據(jù)庫中自增主鍵,而是使用分布式 ID 充當主鍵(可以參考 Java 中分布式 ID 的設計方案 這篇文章),這樣才能能保證在分布式環(huán)境下 ID 的全局唯一性。
適用操作:

  • 插入操作
  • 刪除操作

使用限制:

需要生成全局唯一主鍵 ID;

主要流程:

主要流程:

① 客戶端執(zhí)行創(chuàng)建請求,調用服務端接口。
② 服務端執(zhí)行業(yè)務邏輯,生成一個分布式 ID,將該 ID 充當待插入數(shù)據(jù)的主鍵,然后執(zhí)數(shù)據(jù)插入操作,運行對應的 SQL 語句。
③ 服務端將該條數(shù)據(jù)插入數(shù)據(jù)庫中,如果插入成功則表示沒有重復調用接口。如果拋出主鍵重復異常,則表示數(shù)據(jù)庫中已經存在該條記錄,返回錯誤信息到客戶端。

方案二:數(shù)據(jù)庫樂觀鎖

方案描述:

數(shù)據(jù)庫樂觀鎖方案一般只能適用于執(zhí)行“更新操作”的過程,我們可以提前在對應的數(shù)據(jù)表中多添加一個字段,充當當前數(shù)據(jù)的版本標識。這樣每次對該數(shù)據(jù)庫該表的這條數(shù)據(jù)執(zhí)行更新時,都會將該版本標識作為一個條件,值為上次待更新數(shù)據(jù)中的版本標識的值。

適用操作:

  • 更新操作

使用限制:

需要數(shù)據(jù)庫對應業(yè)務表中添加額外字段;

描述示例:

例如,存在如下的數(shù)據(jù)表中:

id name price
1 小米手機 1000
2 蘋果手機 2500
3 華為手機 1600

為了每次執(zhí)行更新時防止重復更新,確定更新的一定是要更新的內容,我們通常都會添加一個 version 字段記錄當前的記錄版本,這樣在更新時候將該值帶上,那么只要執(zhí)行更新操作就能確定一定更新的是某個對應版本下的信息。

id name price version
1 小米手機 1000 10
2 蘋果手機 2500 21
3 華為手機 1600 5

這樣每次執(zhí)行更新時候,都要指定要更新的版本號,如下操作就能準確更新 version=5 的信息:

UPDATE my_table SET price=price+50,version=version+1 WHERE id=1 AND version=5

上面 WHERE 后面跟著條件 id=1 AND version=5 被執(zhí)行后,id=1 的 version 被更新為 6,所以如果重復執(zhí)行該條 SQL 語句將不生效,因為 id=1 AND version=5 的數(shù)據(jù)已經不存在,這樣就能保住更新的冪等,多次更新對結果不會產生影響。

方案三:防重 Token 令牌

方案描述:

針對客戶端連續(xù)點擊或者調用方的超時重試等情況,例如提交訂單,此種操作就可以用 Token 的機制實現(xiàn)防止重復提交。簡單的說就是調用方在調用接口的時候先向后端請求一個全局 ID(Token),請求的時候攜帶這個全局 ID 一起請求(Token 最好將其放到 Headers 中),后端需要對這個 Token 作為 Key,用戶信息作為 Value 到 Redis 中進行鍵值內容校驗,如果 Key 存在且 Value 匹配就執(zhí)行刪除命令,然后正常執(zhí)行后面的業(yè)務邏輯。如果不存在對應的 Key 或 Value 不匹配就返回重復執(zhí)行的錯誤信息,這樣來保證冪等操作。

適用操作:

  • 插入操作
  • 更新操作
  • 刪除操作

使用限制:

  • 需要生成全局唯一 Token 串;
  • 需要使用第三方組件 Redis 進行數(shù)據(jù)效驗;

主要流程:

 ① 服務端提供獲取 Token 的接口,該 Token 可以是一個序列號,也可以是一個分布式 ID 或者 UUID 串。
② 客戶端調用接口獲取 Token,這時候服務端會生成一個 Token 串。
③ 然后將該串存入 Redis 數(shù)據(jù)庫中,以該 Token 作為 Redis 的鍵(注意設置過期時間)。
④ 將 Token 返回到客戶端,客戶端拿到后應存到表單隱藏域中。
⑤ 客戶端在執(zhí)行提交表單時,把 Token 存入到 Headers 中,執(zhí)行業(yè)務請求帶上該 Headers。
⑥ 服務端接收到請求后從 Headers 中拿到 Token,然后根據(jù) Token 到 Redis 中查找該 key 是否存在。
⑦ 服務端根據(jù) Redis 中是否存該 key 進行判斷,如果存在就將該 key 刪除,然后正常執(zhí)行業(yè)務邏輯。如果不存在就拋異常,返回重復提交的錯誤信息。

注意,在并發(fā)情況下,執(zhí)行 Redis 查找數(shù)據(jù)與刪除需要保證原子性,否則很可能在并發(fā)下無法保證冪等性。其實現(xiàn)方法可以使用分布式鎖或者使用 Lua 表達式來注銷查詢與刪除操作。

方案四、下游傳遞唯一序列號

方案描述:

所謂請求序列號,其實就是每次向服務端請求時候附帶一個短時間內唯一不重復的序列號,該序列號可以是一個有序 ID,也可以是一個訂單號,一般由下游生成,在調用上游服務端接口時附加該序列號和用于認證的 ID。
當上游服務器收到請求信息后拿取該 序列號 和下游 認證ID 進行組合,形成用于操作 Redis 的 Key,然后到 Redis 中查詢是否存在對應的 Key 的鍵值對,根據(jù)其結果:

  • 如果存在,就說明已經對該下游的該序列號的請求進行了業(yè)務處理,這時可以直接響應重復請求的錯誤信息。
  • 如果不存在,就以該 Key 作為 Redis 的鍵,以下游關鍵信息作為存儲的值(例如下游商傳遞的一些業(yè)務邏輯信息),將該鍵值對存儲到 Redis 中 ,然后再正常執(zhí)行對應的業(yè)務邏輯即可。

適用操作:

  • 插入操作
  • 更新操作
  • 刪除操作

使用限制:

  • 要求第三方傳遞唯一序列號;
  • 需要使用第三方組件 Redis 進行數(shù)據(jù)效驗;

主要流程:

主要步驟:

① 下游服務生成分布式 ID 作為序列號,然后執(zhí)行請求調用上游接口,并附帶“唯一序列號”與請求的“認證憑據(jù)ID”。
② 上游服務進行安全效驗,檢測下游傳遞的參數(shù)中是否存在“序列號”和“憑據(jù)ID”。
③ 上游服務到 Redis 中檢測是否存在對應的“序列號”與“認證ID”組成的 Key,如果存在就拋出重復執(zhí)行的異常信息,然后響應下游對應的錯誤信息。如果不存在就以該“序列號”和“認證ID”組合作為 Key,以下游關鍵信息作為 Value,進而存儲到 Redis 中,然后正常執(zhí)行接來來的業(yè)務邏輯。

上面步驟中插入數(shù)據(jù)到 Redis 一定要設置過期時間。這樣能保證在這個時間范圍內,如果重復調用接口,則能夠進行判斷識別。如果不設置過期時間,很可能導致數(shù)據(jù)無限量的存入 Redis,致使 Redis 不能正常工作。

七、實現(xiàn)接口冪等示例

這里使用防重 Token 令牌方案,該方案能保證在不同請求動作下的冪等性,實現(xiàn)邏輯可以看上面寫的”防重 Token 令牌”方案,接下來寫下實現(xiàn)這個邏輯的代碼。

1、Maven 引入相關依賴

這里使用 Maven 工具管理依賴,這里在 pom.xml 中引入 SpringBoot、Redis、lombok 相關依賴。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.4.RELEASE</version>
 </parent>

 <groupId>mydlq.club</groupId>
 <artifactId>springboot-idempotent-token</artifactId>
 <version>0.0.1</version>
 <name>springboot-idempotent-token</name>
 <description>Idempotent Demo</description>

 <properties>
  <java.version>1.8</java.version>
 </properties>

 <dependencies>
  <!--springboot web-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--springboot data redis-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>
  <dependency>
   <groupId>org.apache.commons</groupId>
   <artifactId>commons-pool2</artifactId>
  </dependency>
  <!--lombok-->
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
  </dependency>
 </dependencies>

 <build>
  <plugins>
   <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
   </plugin>
  </plugins>
 </build>
</project>

2、配置連接 Redis 的參數(shù)

在 application 配置文件中配置連接 Redis 的參數(shù)。Spring Boot 基礎就不介紹了,最新教程推薦看下面的教程。
github.com/javastacks/…

如下:

spring:
 redis:
 ssl: false
 host: 127.0.0.1
 port: 6379
 database: 0
 timeout: 1000
 password:
 lettuce:
  pool:
  max-active: 100
  max-wait: -1
  min-idle: 0
  max-idle: 20

3、創(chuàng)建與驗證 Token 工具類

創(chuàng)建用于操作 Token 相關的 Service 類,里面存在 Token 創(chuàng)建與驗證方法,其中:

  • Token 創(chuàng)建方法: 使用 UUID 工具創(chuàng)建 Token 串,設置以 “idempotent_token:“+“Token串” 作為 Key,以用戶信息當成 Value,將信息存入 Redis 中。
  • Token 驗證方法: 接收 Token 串參數(shù),加上 Key 前綴形成 Key,再傳入 value 值,執(zhí)行 Lua 表達式(Lua 表達式能保證命令執(zhí)行的原子性)進行查找對應 Key 與刪除操作。執(zhí)行完成后驗證命令的返回結果,如果結果不為空且非0,則驗證成功,否則失敗。
import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class TokenUtilService {

 @Autowired
 private StringRedisTemplate redisTemplate;

 /**
  * 存入 Redis 的 Token 鍵的前綴
  */
 private static final String IDEMPOTENT_TOKEN_PREFIX = "idempotent_token:";

 /**
  * 創(chuàng)建 Token 存入 Redis,并返回該 Token
  *
  * @param value 用于輔助驗證的 value 值
  * @return 生成的 Token 串
  */
 public String generateToken(String value) {
  // 實例化生成 ID 工具對象
  String token = UUID.randomUUID().toString();
  // 設置存入 Redis 的 Key
  String key = IDEMPOTENT_TOKEN_PREFIX + token;
  // 存儲 Token 到 Redis,且設置過期時間為5分鐘
  redisTemplate.opsForValue().set(key, value, 5, TimeUnit.MINUTES);
  // 返回 Token
  return token;
 }

 /**
  * 驗證 Token 正確性
  *
  * @param token token 字符串
  * @param value value 存儲在Redis中的輔助驗證信息
  * @return 驗證結果
  */
 public boolean validToken(String token, String value) {
  // 設置 Lua 腳本,其中 KEYS[1] 是 key,KEYS[2] 是 value
  String script = "if redis.call('get', KEYS[1]) == KEYS[2] then return redis.call('del', KEYS[1]) else return 0 end";
  RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);
  // 根據(jù) Key 前綴拼接 Key
  String key = IDEMPOTENT_TOKEN_PREFIX + token;
  // 執(zhí)行 Lua 腳本
  Long result = redisTemplate.execute(redisScript, Arrays.asList(key, value));
  // 根據(jù)返回結果判斷是否成功成功匹配并刪除 Redis 鍵值對,若果結果不為空和0,則驗證通過
  if (result != null && result != 0L) {
   log.info("驗證 token={},key={},value={} 成功", token, key, value);
   return true;
  }
  log.info("驗證 token={},key={},value={} 失敗", token, key, value);
  return false;
 }
}

4、創(chuàng)建測試的 Controller 類

創(chuàng)建用于測試的 Controller 類,里面有獲取 Token 與測試接口冪等性的接口,內容如下:

import lombok.extern.slf4j.Slf4j;
import mydlq.club.example.service.TokenUtilService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
public class TokenController {

 @Autowired
 private TokenUtilService tokenService;

 /**
  * 獲取 Token 接口
  *
  * @return Token 串
  */
 @GetMapping("/token")
 public String getToken() {
  // 獲取用戶信息(這里使用模擬數(shù)據(jù))
  // 注:這里存儲該內容只是舉例,其作用為輔助驗證,使其驗證邏輯更安全,如這里存儲用戶信息,其目的為:
  // - 1)、使用"token"驗證 Redis 中是否存在對應的 Key
  // - 2)、使用"用戶信息"驗證 Redis 的 Value 是否匹配。
  String userInfo = "mydlq";
  // 獲取 Token 字符串,并返回
  return tokenService.generateToken(userInfo);
 }

 /**
  * 接口冪等性測試接口
  *
  * @param token 冪等 Token 串
  * @return 執(zhí)行結果
  */
 @PostMapping("/test")
 public String test(@RequestHeader(value = "token") String token) {
  // 獲取用戶信息(這里使用模擬數(shù)據(jù))
  String userInfo = "mydlq";
  // 根據(jù) Token 和與用戶相關的信息到 Redis 驗證是否存在對應的信息
  boolean result = tokenService.validToken(token, userInfo);
  // 根據(jù)驗證結果響應不同信息
  return result ? "正常調用" : "重復調用";
 }
}

5、創(chuàng)建 SpringBoot 啟動類

創(chuàng)建啟動類,用于啟動 SpringBoot 應用?;A教程就不介紹了,建議看下下面的教程,很全了。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

 public static void main(String[] args) {
  SpringApplication.run(Application.class, args);
 }

}

6、寫測試類進行測試

寫個測試類進行測試,多次訪問同一個接口,測試是否只有第一次能否執(zhí)行成功。

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class IdempotenceTest {

 @Autowired
 private WebApplicationContext webApplicationContext;

 @Test
 public void interfaceIdempotenceTest() throws Exception {
  // 初始化 MockMvc
  MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
  // 調用獲取 Token 接口
  String token = mockMvc.perform(MockMvcRequestBuilders.get("/token")
    .accept(MediaType.TEXT_HTML))
    .andReturn()
    .getResponse().getContentAsString();
  log.info("獲取的 Token 串:{}", token);
  // 循環(huán)調用 5 次進行測試
  for (int i = 1; i <= 5; i++) {
   log.info("第{}次調用測試接口", i);
   // 調用驗證接口并打印結果
   String result = mockMvc.perform(MockMvcRequestBuilders.post("/test")
     .header("token", token)
     .accept(MediaType.TEXT_HTML))
     .andReturn().getResponse().getContentAsString();
   log.info(result);
   // 結果斷言
   if (i == 0) {
    Assert.assertEquals(result, "正常調用");
   } else {
    Assert.assertEquals(result, "重復調用");
   }
  }
 }

}

顯示如下:
[main] IdempotenceTest:  獲取的 Token 串:980ea707-ce2e-456e-a059-0a03332110b4
[main] IdempotenceTest:  第1次調用測試接口
[main] IdempotenceTest:  正常調用
[main] IdempotenceTest:  第2次調用測試接口
[main] IdempotenceTest:  重復調用
[main] IdempotenceTest:  第3次調用測試接口
[main] IdempotenceTest:  重復調用
[main] IdempotenceTest:  第4次調用測試接口
[main] IdempotenceTest:  重復調用
[main] IdempotenceTest:  第5次調用測試接口
[main] IdempotenceTest:  重復調用

八、最后總結

冪等性是開發(fā)當中很常見也很重要的一個需求,尤其是支付、訂單等與金錢掛鉤的服務,保證接口冪等性尤其重要。在實際開發(fā)中,我們需要針對不同的業(yè)務場景我們需要靈活的選擇冪等性的實現(xiàn)方式:

對于下單等存在唯一主鍵的,可以使用“唯一主鍵方案”的方式實現(xiàn)。
對于更新訂單狀態(tài)等相關的更新場景操作,使用“樂觀鎖方案”實現(xiàn)更為簡單。
對于上下游這種,下游請求上游,上游服務可以使用“下游傳遞唯一序列號方案”更為合理。
類似于前端重復提交、重復下單、沒有唯一ID號的場景,可以通過 Token 與 Redis 配合的“防重 Token 方案”實現(xiàn)更為快捷。

上面只是給與一些建議,再次強調一下,實現(xiàn)冪等性需要先理解自身業(yè)務需求,根據(jù)業(yè)務邏輯來實現(xiàn)這樣才合理,處理好其中的每一個結點細節(jié),完善整體的業(yè)務流程設計,才能更好的保證系統(tǒng)的正常運行。最后做一個簡單總結,然后本博文到此結束,如下:

方案名稱 適用方法 實現(xiàn)復雜度 方案缺點
數(shù)據(jù)庫唯一主鍵 插入操作 刪除操作 簡單 只能用于插入操作;- 只能用于存在唯一主鍵場景;
數(shù)據(jù)庫樂觀鎖 更新操作 簡單 只能用于更新操作;- 表中需要額外添加字段;
請求序列號 插入操作 更新操作 刪除操作 簡單 需要保證下游生成唯一序列號;- 需要 Redis 第三方存儲已經請求的序列號;
防重 Token 令牌 插入操作 更新操作 刪除操作 適中 需要 Redis 第三方存儲生成的 Token 串;

到此這篇關于SpringBoot實現(xiàn)接口冪等性的4種方案的文章就介紹到這了,更多相關SpringBoot 接口冪等性內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • IDEA main主函數(shù)如何添加args變量

    IDEA main主函數(shù)如何添加args變量

    這篇文章主要介紹了IDEA main主函數(shù)如何添加args變量,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • 利用Spring Boot如何開發(fā)REST服務詳解

    利用Spring Boot如何開發(fā)REST服務詳解

    這篇文章主要給大家介紹了關于利用Spring Boot如何開發(fā)REST服務的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-12-12
  • 淺談JAVA內存分配與參數(shù)傳遞

    淺談JAVA內存分配與參數(shù)傳遞

    這篇文章主要介紹了JAVA內存分配與參數(shù)傳遞,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • JAVA LinkedList和ArrayList的使用及性能分析

    JAVA LinkedList和ArrayList的使用及性能分析

    JAVA LinkedList和ArrayList的使用及性能分析,這篇文章也是以JAVA List的總結。
    2013-11-11
  • Springboot整合MongoDB的Docker開發(fā)教程全解

    Springboot整合MongoDB的Docker開發(fā)教程全解

    這篇文章主要介紹了Springboot整合MongoDB的Docker開發(fā),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2020-07-07
  • 使用Spark?SQL實現(xiàn)讀取不帶表頭的txt文件

    使用Spark?SQL實現(xiàn)讀取不帶表頭的txt文件

    這篇文章主要為大家詳細介紹了如何使用Spark?SQL實現(xiàn)讀取不帶表頭的txt文件,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-03-03
  • Java如何生成隨機數(shù)不了解下嗎

    Java如何生成隨機數(shù)不了解下嗎

    我們在學習 Java 基礎時就知道可以生成隨機數(shù),可以為我們枯燥的學習增加那么一丟丟的樂趣,本文就來和大家介紹Java生成隨機數(shù)的常用方法,需要的可以參考下
    2023-08-08
  • 一篇文章帶你復習java知識點

    一篇文章帶你復習java知識點

    以下簡單介紹了下我對于這些java基本知識點和技術點的一些看法和心得,這些內容都源自于我這些年來使用java的一些總結,希望能夠給你帶來幫助
    2021-06-06
  • Springboot項目接口限流實現(xiàn)方案

    Springboot項目接口限流實現(xiàn)方案

    這篇文章主要介紹了Springboot項目接口限流實現(xiàn)方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 多用多學之Java中的Set,List,Map詳解

    多用多學之Java中的Set,List,Map詳解

    下面小編就為大家?guī)硪黄嘤枚鄬W之Java中的Set,List,Map詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06

最新評論