成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們一起聊聊如何保證接口冪等性?高并發(fā)下的接口冪等性如何實(shí)現(xiàn)?

開(kāi)發(fā) 前端
具體到HTTP接口或者服務(wù)間的API調(diào)用,接口冪等性就可以理解為當(dāng)客戶端對(duì)同一接口發(fā)起多次相同的請(qǐng)求時(shí),服務(wù)端系統(tǒng)也應(yīng)該確保只執(zhí)行一次相應(yīng)的操作,并且不論接收到了多少次請(qǐng)求,系統(tǒng)的狀態(tài)變更始終是一致的,不會(huì)因?yàn)橹貜?fù)的請(qǐng)求而導(dǎo)致數(shù)據(jù)的錯(cuò)誤。

什么是接口冪等性

接口冪等性這一概念源于數(shù)學(xué),原意是指一個(gè)操作如果連續(xù)執(zhí)行多次所產(chǎn)生的結(jié)果與僅執(zhí)行一次的效果相同,那么我們就稱這個(gè)操作是冪等的。在互聯(lián)網(wǎng)領(lǐng)域,特別是在Web服務(wù)、API設(shè)計(jì)和分布式系統(tǒng)中,接口冪等性具有非常重要的意義。

具體到HTTP接口或者服務(wù)間的API調(diào)用,接口冪等性就可以理解為當(dāng)客戶端對(duì)同一接口發(fā)起多次相同的請(qǐng)求時(shí),服務(wù)端系統(tǒng)也應(yīng)該確保只執(zhí)行一次相應(yīng)的操作,并且不論接收到了多少次請(qǐng)求,系統(tǒng)的狀態(tài)變更始終是一致的,不會(huì)因?yàn)橹貜?fù)的請(qǐng)求而導(dǎo)致數(shù)據(jù)的錯(cuò)誤。

比如我們常常遇到的訂單創(chuàng)建,支付等業(yè)務(wù)。

  • 如果一個(gè)“創(chuàng)建訂單”接口實(shí)現(xiàn)了冪等性,當(dāng)收到兩次同樣的創(chuàng)建請(qǐng)求時(shí),系統(tǒng)應(yīng)該要么拒絕第二個(gè)請(qǐng)求(因?yàn)樗呀?jīng)是重復(fù)請(qǐng)求),要么確保只有一個(gè)訂單被創(chuàng)建,而不是兩個(gè)完全一樣的訂單。
  • 對(duì)于一個(gè)“支付”接口,冪等性要求即便用戶由于網(wǎng)絡(luò)原因反復(fù)點(diǎn)擊支付按鈕,服務(wù)端也只會(huì)扣除用戶賬戶一次金額,避免重復(fù)扣費(fèi)。

導(dǎo)致接口冪等性問(wèn)題的原因

要向杜絕冪等性,那么我們就要之道導(dǎo)致接口冪等性問(wèn)題的原因有哪些。接口冪等性問(wèn)題通常由以下多種原因引起:

  1. 網(wǎng)絡(luò)波動(dòng)不穩(wěn)定:網(wǎng)絡(luò)通信中的丟包、延遲等情況可能導(dǎo)致客戶端未收到服務(wù)端的響應(yīng)或服務(wù)端未收到客戶端的請(qǐng)求,此時(shí)客戶端可能會(huì)重試發(fā)送請(qǐng)求,導(dǎo)致接口被重復(fù)調(diào)用。
  2. 用戶操作:用戶快速重復(fù)點(diǎn)擊導(dǎo)致,例如用戶在等待響應(yīng)時(shí),由于不確定是否操作成功,可能會(huì)多次點(diǎn)擊提交按鈕,進(jìn)而發(fā)送多次相同的請(qǐng)求。再比如頁(yè)用戶頻繁刷新頁(yè)面,尤其是在某些提交操作尚未完成時(shí),刷新頁(yè)面可能會(huì)重新發(fā)送請(qǐng)求。還有用戶可能在瀏覽器上點(diǎn)擊回退然后再重復(fù)之間的提交操作,這都可能會(huì)導(dǎo)致重新發(fā)送請(qǐng)求。
  3. 重試機(jī)制:在高可用性設(shè)計(jì)中,客戶端常常設(shè)置有重試機(jī)制,當(dāng)請(qǐng)求失敗或超時(shí)時(shí)會(huì)自動(dòng)重新發(fā)起請(qǐng)求。而在分布式系統(tǒng)中,服務(wù)間調(diào)用也可能有重試策略,以應(yīng)對(duì)臨時(shí)故障。比如Nginx重試,RPC重試,或者調(diào)用方業(yè)務(wù)層中進(jìn)行重試。
  4. 定時(shí)任務(wù)或異步處理:在定時(shí)任務(wù)中如果定時(shí)任務(wù)調(diào)度或邏輯設(shè)計(jì)不當(dāng),可能會(huì)導(dǎo)致同一任務(wù)被執(zhí)行多次。或者在消息隊(duì)列中,消息可能會(huì)因?yàn)楫惓5仍虮恢貜?fù)消費(fèi)。
  5. 并發(fā)控制:缺乏有效的并發(fā)控制手段,導(dǎo)致在并發(fā)環(huán)境下,針對(duì)同一資源的操作被多次執(zhí)行。

總的來(lái)說(shuō),導(dǎo)致接口冪等性問(wèn)題可以粗略的歸類于兩種情況:前端調(diào)用以及服務(wù)端調(diào)用,那么我們可以針對(duì)這兩種情況看一下如何去保證接口冪等。

如何保證接口冪等?

前端調(diào)用

頁(yè)面控制

頁(yè)面調(diào)用接口時(shí)可以通過(guò)禁用(如按鈕置灰或顯示加載狀態(tài))防止用戶在請(qǐng)求未完成前重復(fù)點(diǎn)擊,從而減少不必要的重復(fù)請(qǐng)求和可能的數(shù)據(jù)沖突。雖然在前端進(jìn)行按鈕置灰等操作可以輔助提高系統(tǒng)的冪等性表現(xiàn),但是這個(gè)方式只是從用戶體驗(yàn)和用戶行為控制的角度來(lái)避免重復(fù)提交的一種方法,并沒(méi)有從系統(tǒng)設(shè)計(jì)層面完全解決接口本身的冪等性問(wèn)題。

使用RPG模式

PRG(POST/Redirect/GET)模式是一種前端交互策略,旨在解決用戶刷新頁(yè)面時(shí)可能導(dǎo)致表單數(shù)據(jù)重復(fù)提交的問(wèn)題。它巧妙地利用了HTTP協(xié)議的特性,具體的交互流程如下:

  1. 用戶在網(wǎng)頁(yè)表單中填寫數(shù)據(jù),并通過(guò)POST請(qǐng)求將其發(fā)送至服務(wù)器進(jìn)行處理,例如創(chuàng)建新資源或更新現(xiàn)有數(shù)據(jù)。
  2. 服務(wù)器接收到POST請(qǐng)求后,對(duì)提交的數(shù)據(jù)進(jìn)行有效處理和持久化存儲(chǔ),并在操作成功后不直接返回處理結(jié)果,而是通過(guò)HTTP響應(yīng)碼302或303實(shí)現(xiàn)重定向,指示客戶端發(fā)起一個(gè)新的GET請(qǐng)求去訪問(wèn)一個(gè)特定的URL。
  3. 客戶端遵照服務(wù)器的重定向指示,自動(dòng)發(fā)送GET請(qǐng)求訪問(wèn)新的URL,此時(shí)返回的頁(yè)面將展示之前POST操作處理完畢的結(jié)果。
  4. 當(dāng)用戶在此后刷新頁(yè)面時(shí),瀏覽器只會(huì)按照常規(guī)方式重新發(fā)起GET請(qǐng)求,而非重新提交POST數(shù)據(jù),因此有效地避免了重復(fù)提交引發(fā)的潛在問(wèn)題。
Token機(jī)制

Token機(jī)制是一種廣泛應(yīng)用互聯(lián)網(wǎng)領(lǐng)域的認(rèn)證與授權(quán)方法,特別是Web服務(wù)系統(tǒng)。token可以理解為一種安全憑證,它是由服務(wù)端生成并頒發(fā)給客戶端的一段經(jīng)過(guò)加密處理的字符串或數(shù)據(jù)結(jié)構(gòu),用來(lái)代表用戶的某種狀態(tài)或權(quán)限。

通過(guò)Token機(jī)制,我們可以解決接口冪等性問(wèn)題。在接口中,我們?cè)试S重復(fù)提交,但是要保證重復(fù)提交不產(chǎn)生副作用,比如點(diǎn)擊n次只產(chǎn)生一條記錄,客戶端每次請(qǐng)求都需要攜帶一個(gè)唯一的Token,而服務(wù)器則驗(yàn)證這個(gè)Token的有效性。如果服務(wù)器收到了一個(gè)已經(jīng)使用過(guò)的Token就會(huì)認(rèn)為這是一個(gè)重復(fù)請(qǐng)求并拒絕處理,從而確保接口的冪等性具體流握如下Token機(jī)制是一種常用的方法,用于確保接口的冪等性和防止重復(fù)請(qǐng)求。具體流程如下:

  1. 生成Token當(dāng)用戶開(kāi)始執(zhí)行一個(gè)需要確保冪等性的操作(如支付、下單、更新用戶信息等)時(shí),服務(wù)端會(huì)生成一個(gè)唯一的、有時(shí)效性的token。這個(gè)token可以是一個(gè)隨機(jī)字符串或者帶有時(shí)間戳和其他相關(guān)信息的哈希值,確保其唯一性。
  2. 存儲(chǔ)Token生成的token會(huì)被存儲(chǔ)在服務(wù)端的一個(gè)臨時(shí)存儲(chǔ)介質(zhì)中,如Redis、Memcached或數(shù)據(jù)庫(kù),同時(shí)設(shè)置一個(gè)合理的過(guò)期時(shí)間(例如15分鐘)。
  3. 傳遞Token將生成的token返回給客戶端,客戶端在進(jìn)行后續(xù)的API調(diào)用時(shí),需將此token作為請(qǐng)求參數(shù)或放在請(qǐng)求頭中一并發(fā)送給服務(wù)端。
  4. 驗(yàn)證Token服務(wù)端在接收到帶有token的請(qǐng)求時(shí),首先檢查token是否存在并且有效(未過(guò)期且未被使用過(guò))。如果token有效且未被使用,則執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,并在執(zhí)行完成后立即從存儲(chǔ)介質(zhì)中移除或標(biāo)記為已使用。若token已失效或已被使用,則拒絕此次請(qǐng)求,返回相應(yīng)的錯(cuò)誤提示,確保同一個(gè)操作不會(huì)被執(zhí)行兩次。
  5. 限制并發(fā)在并發(fā)場(chǎng)景下,通過(guò)原子操作(如Redis的SETNX命令)確保在驗(yàn)證token有效的同時(shí),將其刪除或更新?tīng)顟B(tài),避免多個(gè)請(qǐng)求同時(shí)通過(guò)驗(yàn)證。

圖片圖片

服務(wù)端控制

在服務(wù)端接口處理邏輯時(shí),可以通過(guò)通過(guò)一些特定的標(biāo)識(shí)符或請(qǐng)求參數(shù)來(lái)校驗(yàn)請(qǐng)求的冪等性,以確保同樣的請(qǐng)求不會(huì)被重復(fù)處理。

唯一標(biāo)識(shí)符

客戶端每次發(fā)起請(qǐng)求會(huì)攜帶一個(gè)全局唯一的標(biāo)識(shí)符。服務(wù)器接收到請(qǐng)求后就會(huì)對(duì)這個(gè)標(biāo)識(shí)符進(jìn)行檢查,若服務(wù)器發(fā)現(xiàn)該標(biāo)識(shí)符已經(jīng)在系統(tǒng)中存在,表明這是一個(gè)重復(fù)請(qǐng)求,此時(shí)服務(wù)器可以選擇忽略該請(qǐng)求,或者向客戶端返回已處理過(guò)相同請(qǐng)求的結(jié)果信息。若服務(wù)器未找到該標(biāo)識(shí)符存在于系統(tǒng)內(nèi),則認(rèn)定該請(qǐng)求為新請(qǐng)求,服務(wù)器將繼續(xù)對(duì)其進(jìn)行正常處理,并將此唯一標(biāo)識(shí)符保存至系統(tǒng)中,以便于后續(xù)對(duì)接收的請(qǐng)求進(jìn)行有效性校驗(yàn),防止同一請(qǐng)求的重復(fù)處理。比如我們?cè)谝笊嫌蜤RP系統(tǒng)對(duì)接訂單平臺(tái)時(shí)就會(huì)要求上游傳遞一個(gè)賬號(hào)下全局唯一的一個(gè)參考單號(hào),這個(gè)參考單號(hào)一個(gè)很重要的作用就是保證接口冪等性。

請(qǐng)求參數(shù)

某些請(qǐng)求參數(shù)確實(shí)可以用來(lái)輔助校驗(yàn)請(qǐng)求的冪等性。例如,時(shí)間戳可以作為一種可能的請(qǐng)求參數(shù),在處理請(qǐng)求時(shí),服務(wù)器可以通過(guò)比較時(shí)間戳與服務(wù)器當(dāng)前時(shí)間來(lái)判斷請(qǐng)求的有效性。若時(shí)間戳與當(dāng)前時(shí)間之間的差異超出預(yù)設(shè)的合理范圍(如幾秒鐘到幾分鐘不等,具體閾值視業(yè)務(wù)場(chǎng)景而定),服務(wù)器可以推測(cè)該請(qǐng)求可能是由于網(wǎng)絡(luò)延遲或者其他原因?qū)е碌闹貜?fù)提交。

單純依靠時(shí)間戳來(lái)判斷冪等性和重復(fù)請(qǐng)求并不完全準(zhǔn)確,因?yàn)椴煌目蛻舳藭r(shí)間可能并不精確同步,而且時(shí)間戳本身無(wú)法保證全局唯一性。但是它可以作為一種有效的輔助手段來(lái)減少重復(fù)處理的可能性。

狀態(tài)機(jī)設(shè)計(jì)

對(duì)于狀態(tài)轉(zhuǎn)移類的操作類型的業(yè)務(wù),可采用狀態(tài)機(jī)設(shè)計(jì),每次請(qǐng)求只允許合法的狀態(tài)變遷,非法狀態(tài)變遷(如已經(jīng)完成的訂單不允許再次支付)將被拒絕。

樂(lè)觀鎖

在更新數(shù)據(jù)時(shí),可以通過(guò)版本號(hào)或時(shí)間戳等機(jī)制判斷數(shù)據(jù)是否已被修改,防止因并發(fā)請(qǐng)求導(dǎo)致的多次更新問(wèn)題。具體做法:

  1. 在數(shù)據(jù)庫(kù)表中增加一個(gè)版本號(hào)字段(version)或者時(shí)間戳字段(timestamp)。
  2. 客戶端第一次請(qǐng)求時(shí)獲取數(shù)據(jù)的版本號(hào)或時(shí)間戳。
  3. 客戶端發(fā)起更新操作時(shí),將上次讀取的版本號(hào)或時(shí)間戳一起發(fā)送回服務(wù)器。
  4. 服務(wù)器在執(zhí)行更新操作前,首先檢查當(dāng)前數(shù)據(jù)庫(kù)中的版本號(hào)或時(shí)間戳是否與客戶端提交的一致。

如果一致,說(shuō)明在這期間數(shù)據(jù)沒(méi)有被其他事務(wù)修改過(guò),于是更新數(shù)據(jù)并遞增版本號(hào)或更新時(shí)間戳。

如果不一致,說(shuō)明數(shù)據(jù)已經(jīng)被修改過(guò),此時(shí)服務(wù)器拒絕本次更新請(qǐng)求,返回錯(cuò)誤提示,客戶端可以根據(jù)錯(cuò)誤信息決定是否重新獲取最新數(shù)據(jù)再嘗試更新。

通過(guò)這種方式,即使客戶端因?yàn)榫W(wǎng)絡(luò)原因或其他因素導(dǎo)致同一請(qǐng)求被多次發(fā)送,樂(lè)觀鎖機(jī)制能確保只有在數(shù)據(jù)未被其他事務(wù)修改的前提下,才會(huì)執(zhí)行更新操作,從而達(dá)到接口冪等的效果。

實(shí)現(xiàn)冪等性方案示例

從上述的幾種解決冪等性問(wèn)題的方案來(lái)看,使用token機(jī)制可以保證在不同請(qǐng)求動(dòng)作下的冪等性。所以我們以此作為方案作為示例方案。

準(zhǔn)備工作

我們使用Redis保存Token令牌,引入SpringBoot,Redis,ULID相關(guān)的依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.7.0</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.7.0</version>
</dependency>

<dependency>
    <groupId>com.github.f4b6a3</groupId>
    <artifactId>ulid-creator</artifactId>
    <version>5.2.0</version>
</dependency>

Redis相關(guān)的配置:

spring.redis.database=0  
spring.redis.host=127.0.0.1  
spring.redis.port=6379  
spring.redis.password=  
spring.redis.pool.max-active=8  
spring.redis.pool.max-wait=-1  
spring.redis.pool.max-idle=8  
spring.redis.pool.min-idle=0  
spring.redis.timeout=60  


server.port=8080  
server.servlet.context-path=/coderacademy

生成Token令牌

使用ULID生成隨機(jī)字符串,然后將其保存在Redis當(dāng)中。這里以idempotent_token+賬戶+請(qǐng)求操作類型+token作為key。

private StringRedisTemplate stringRedisTemplate;

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


/**
 * 生成token令牌
 *
 * @param accountSecret 賬戶令牌
 * @param operatorType 接口請(qǐng)求類型,可以是接口url或者其他可以區(qū)分接口服務(wù)類型的值
 * @return token令牌
 */
@Override
public String generateToken(String accountSecret, String operatorType) {
    // 創(chuàng)建或獲取ULID生成器實(shí)例
    long timestampInMillis = LocalDateTime.now().atZone(ZoneOffset.systemDefault()).toInstant().toEpochMilli();
    Ulid ulid = UlidCreator.getUlid(timestampInMillis);
    String token = ulid.toString();
    // 設(shè)置存入 Redis 的 Key
    String key = String.format(IDEMPOTENT_TOKEN_PREFIX, accountSecret, operatorType, token);
    // 存儲(chǔ) Token 到 Redis,且設(shè)置過(guò)期時(shí)間為5分鐘
    stringRedisTemplate.opsForValue().set(key, accountSecret, 5, TimeUnit.MINUTES);
    // 返回 Token
    return token;
}

校驗(yàn)Token令牌

這里我們使用Redis執(zhí)行Lua命令去查找以及刪除key,Lua 表達(dá)式能保證命令執(zhí)行的原子性。

/**
     * 驗(yàn)證 Token 正確性
     *
     * @param token token 字符串
     * @param operatorType 接口請(qǐng)求類型,可以是接口url或者其他可以區(qū)分接口服務(wù)類型的值
     * @return 驗(yàn)證結(jié)果
     */
private boolean validToken(String token, String accountSecret, String operatorType) {
    // 設(shè)置 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 = String.format(IDEMPOTENT_TOKEN_PREFIX, accountSecret, operatorType, token);
    // 執(zhí)行 Lua 腳本
    Long result = stringRedisTemplate.execute(redisScript, Arrays.asList(key, operatorType));
    // 根據(jù)返回結(jié)果判斷是否成功成功匹配并刪除 Redis 鍵值對(duì),若果結(jié)果不為空和0,則驗(yàn)證通過(guò)
    if (result != null && result != 0L) {
        System.out.println(String.format("驗(yàn)證 token=%s,key=%s,value=%s 成功", token, key, operatorType));
        return true;
    }
    System.err.println(String.format("驗(yàn)證 token=%s,key=%s,value=%s 失敗", token, key, operatorType));
    return false;
}

業(yè)務(wù)代碼以及接口

我們?cè)趯?shí)現(xiàn)模擬創(chuàng)建訂單的服務(wù),在創(chuàng)建訂單之前,首先校驗(yàn)token令牌。

/**
 * 創(chuàng)建訂單接口
 *
 * @param requestVO     創(chuàng)建訂單參數(shù)
 * @param accountSecret 賬戶令牌
 * @param token         token令牌
 * @return 生成的訂單號(hào)
 */
@Override
public String createOrder(OrderCreateRequestVO requestVO, String accountSecret, String token) {
    // 根據(jù) Token 和與用戶相關(guān)的信息到 Redis 驗(yàn)證是否存在對(duì)應(yīng)的信息
    boolean result = validToken(token, accountSecret, "createOrder");
    if (!result){
        // 這里需要自定義異常,統(tǒng)一處理異常,再統(tǒng)一響應(yīng)返回
        throw new RuntimeException("重復(fù)的請(qǐng)求");
    }
    // 根據(jù)驗(yàn)證結(jié)果響應(yīng)不同信息
    return "Success";
}

校驗(yàn)如果不存在token,則說(shuō)明請(qǐng)求時(shí)重復(fù)請(qǐng)求,直接拋出異常,由統(tǒng)一異常管理,直接返回客戶端請(qǐng)求失敗的錯(cuò)誤信息。關(guān)于SpringBoot中統(tǒng)一異常處理,統(tǒng)一結(jié)果響應(yīng),請(qǐng)查看:SpringBoot統(tǒng)一結(jié)果返回,統(tǒng)一異常處理,大牛都這么玩。

我們?cè)诙x獲取Token令牌的接口,以及創(chuàng)建訂單的接口。

@RestController
@RequestMapping("order")
public class OrderController {

    private IOrderService orderService;

    /**
     * 獲取token接口
     * @param secret 賬戶令牌
     * @return
     */
    @GetMapping("getToken")
    public String getToken(@RequestHeader("secret") String secret){
        return orderService.generateToken(secret, "createOrder");
    }

    /**
     * 創(chuàng)建訂單接口
     * @param requestVO 參數(shù)
     * @param token token令牌
     * @param secret 賬戶令牌
     * @return 響應(yīng)信息
     */
    @PostMapping("create")
    public OrderCreateResponseVO createOrder(@RequestBody OrderCreateRequestVO requestVO,
                                             @RequestHeader("token") String token,
                                             @RequestHeader("secret") String secret){
        OrderCreateResponseVO responseVO = new OrderCreateResponseVO();
        String result = orderService.createOrder(requestVO, secret, token);
        responseVO.setSuccess(Boolean.TRUE);
        responseVO.setMsg(result);
        return responseVO;
    }

    @Autowired
    public void setOrderService(IOrderService orderService) {
        this.orderService = orderService;
    }
}

我們使用Apifox模擬3個(gè)請(qǐng)求并發(fā)操作。

圖片圖片

執(zhí)行結(jié)果如下:

圖片圖片

控制臺(tái)打印日志如下:

圖片圖片

可以看見(jiàn)只有1個(gè)請(qǐng)求成功了,并且控制臺(tái)中打印只有一個(gè)token校驗(yàn)成功。

總結(jié)

冪等性是開(kāi)發(fā)當(dāng)中很常見(jiàn)也很重要的一個(gè)需求,尤其是訂單,支付以及與金錢掛鉤的服務(wù),保證接口冪等性尤其重要。在實(shí)際開(kāi)發(fā)中,我們需要針對(duì)不同的業(yè)務(wù)場(chǎng)景我們需要靈活的選擇冪等性的實(shí)現(xiàn)方式:

  • 如果是web服務(wù),客戶端可以采取在頁(yè)面上使用按鈕置灰禁用,使用PRG模式,或者搭配后端的Token令牌進(jìn)行解決。
  • 在服務(wù)端,我們可以采取唯一標(biāo)識(shí)符,樂(lè)觀鎖,Token令牌,狀態(tài)機(jī)等校驗(yàn)方式。

最后強(qiáng)調(diào)一下,實(shí)現(xiàn)冪等性需要先理解自身業(yè)務(wù)需求,根據(jù)業(yè)務(wù)邏輯來(lái)實(shí)現(xiàn)這樣才合理,處理好其中的每一個(gè)結(jié)點(diǎn)細(xì)節(jié),完善整體的業(yè)務(wù)流程設(shè)計(jì),才能更好的保證系統(tǒng)的正常運(yùn)行。

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)Academy
相關(guān)推薦

2021-03-28 09:45:05

冪等性接口數(shù)據(jù)

2020-07-15 08:14:12

高并發(fā)

2025-02-26 08:20:18

2021-04-14 17:18:27

冪等性數(shù)據(jù)源MySQL

2022-01-04 12:08:46

設(shè)計(jì)接口

2021-01-18 14:34:59

冪等性接口客戶端

2023-09-01 15:27:31

2025-02-23 08:00:00

冪等性Java開(kāi)發(fā)

2024-11-27 08:47:12

2022-03-22 07:57:42

Java多線程并發(fā)

2024-07-10 12:23:10

2021-01-13 11:23:59

分布式冪等性支付

2023-10-26 07:32:42

2024-06-24 01:00:00

2024-08-29 09:01:39

2024-11-01 09:28:02

2023-03-07 08:19:16

接口冪等性SpringBoot

2022-05-23 11:35:16

jiekou冪等性

2021-01-20 07:16:07

冪等性接口token

2023-08-29 13:53:00

前端攔截HashMap
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 免费观看毛片 | 欧美精品在线一区二区三区 | 成人免费视频 | 国产成人高清视频 | 中文字幕不卡视频在线观看 | 日本久久综合 | 亚洲精品久久久久久下一站 | 男人天堂网址 | 国产精品久久久久久久久久了 | 久久综合av| 久久久久国产精品 | 亚洲中国字幕 | 中文字幕不卡在线观看 | 狠狠夜夜| 中国三级黄色录像 | 欧美午夜一区二区三区免费大片 | 亚洲视频www | 国产一区二区三区免费观看在线 | 日韩美av | 久久中文字幕av | 久久99久久98精品免观看软件 | 男人久久天堂 | 粉嫩粉嫩芽的虎白女18在线视频 | 性欧美精品一区二区三区在线播放 | 99精品一区二区 | 黄色永久免费 | 在线成人免费观看 | 丝袜美腿一区 | 美女一区 | 精品综合 | 在线播放国产一区二区三区 | 国产精品久久久久久久久久久久冷 | 日韩中文字幕一区二区 | 亚洲免费一区 | 精品免费国产一区二区三区四区介绍 | 国产精品一区一区 | 色婷婷久久 | 日本不卡免费新一二三区 | 久久久久久免费毛片精品 | 在线视频 亚洲 | 欧美专区在线 |