国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Redis+唯一序列號的方案實現接口冪等性

開發 前端
接口冪等性是指同一接口被多次調用時,產生的業務結果是一致的,不會因為重復調用而導致非預期的副作用。在分布式系統中,由于網絡延遲、重試機制、負載均衡等因素,接口重復調用幾乎是不可避免的,因此保證接口冪等性是系統設計中至關重要的一環。

前言

接口冪等性是指同一接口被多次調用時,產生的業務結果是一致的,不會因為重復調用而導致非預期的副作用。在分布式系統中,由于網絡延遲、重試機制、負載均衡等因素,接口重復調用幾乎是不可避免的,因此保證接口冪等性是系統設計中至關重要的一環。

冪等性實現方案對比

方案

優點

缺點

適用場景

Redis + 唯一序列號

高性能,支持分布式

依賴 Redis,需客戶端生成序列號

大部分分布式接口場景

數據庫唯一索引

實現簡單,不依賴其他組件

性能較低,對數據庫有壓力

數據插入類接口

令牌機制

服務端生成令牌,安全性高

增加一次請求交互,流程復雜

安全性要求高的場景

狀態機控制

符合業務邏輯,天然冪等

僅適用于有狀態流轉的業務

訂單狀態變更等場景

悲觀鎖

實現簡單,安全性高

并發性能差

并發量低的場景

樂觀鎖

并發性能好

實現相對復雜

并發量高的場景

Redis + 唯一序列號方案介紹

Redis+唯一序列號方案是實現接口冪等性的常用方案之一,其核心思想是:

  • 客戶端發起請求時,生成一個全局唯一的序列號(Serial Number
  • 服務端接收到請求后,先檢查該序列號在Redis中是否存在
  • 如果不存在,將序列號存入Redis,并執行業務邏輯
  • 如果已存在,說明是重復請求,直接返回成功或相應結果,不重復執行業務邏輯

該方案利用Redis的高性能、原子操作和過期時間特性,能夠高效地實現分布式環境下的接口冪等性控制。

效果圖

圖片

實現細節

唯一序列號需要滿足以下特性:

  • 全局唯一性:確保不同請求不會產生相同的序列號
  • 不可預測性:防止惡意猜測序列號
  • 高效生成:生成過程不能成為系統瓶頸
  • 包含業務含義(可選):便于問題排查和追蹤

常用的生成方式:

  • UUID/GUID:通用唯一識別碼,本地生成,性能高
  • 雪花算法(Snowflake):生成64位全局唯一ID,包含時間戳信息
  • 數據庫自增ID:通過數據庫生成唯一ID,性能較低
  • 業務信息 + 隨機數:結合用戶ID、時間戳等業務信息生成

Redis 存儲設計

鍵(Key)設計:
idempotent:{業務類型}:{序列號}
值(Value)設計:

可以存儲請求相關信息,如用戶ID、請求時間等,便于后續分析和問題排查。

過期時間(TTL):

根據業務場景設置合理的過期時間,避免Redis內存溢出。例如:

  • 支付類接口:24小時
  • 訂單類接口:7
  • 一般查詢接口:1小時
處理流程
客戶端 -> 生成唯一序列號 -> 攜帶序列號發起請求 -> 服務端
服務端 -> 檢查Redis中是否存在該序列號
       -> 不存在:存儲序列號到Redis,執行業務邏輯,返回結果
       -> 存在:直接返回之前的處理結果

實現示例

生成唯一序列號工具類
public class SerialNumberGenerator {
    
    /**
     * 生成UUID作為唯一序列號
     */
    public static String generateUUID() {
        return UUID.randomUUID().toString();
    }
    
    /**
     * 生成包含業務前綴的唯一序列號
     */
    public static String generateWithPrefix(String prefix) {
        return prefix + ":" + UUID.randomUUID().toString().replaceAll("-", "");
    }
}
Redis 操作工具類
@Component
public class RedisIdempotentUtils {
    
    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 檢查并設置序列號
     * @param key 序列號鍵
     * @param value 存儲的值
     * @param expireTime 過期時間
     * @param timeUnit 時間單位
     * @returntrue-首次請求,false-重復請求
     */
    public boolean checkAndSet(String key, Object value, long expireTime, TimeUnit timeUnit) {
        // 使用Redis的setIfAbsent實現原子操作,確保線程安全
        Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, timeUnit);
        return Boolean.TRUE.equals(result);
    }
    
    /**
     * 獲取序列號對應的值
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
    
    /**
     * 構建Redis鍵
     */
    public String buildKey(String businessType, String serialNumber) {
        return"idempotent:" + businessType + ":" + serialNumber;
    }
}
接口冪等性控制實現
@RestController
public class PaymentController {
    
    @Resource
    private RedisIdempotentUtils redisIdempotentUtils;
    
    @Resource
    private PaymentService paymentService;
    
    /**
     * 支付接口
     * @param serialNumber 唯一序列號,從請求頭獲取
     * @param paymentRequest 支付請求參數
     */
    @PostMapping("/api/payment")
    public Result<PaymentResponse> processPayment(
            @RequestHeader("Idempotent-Serial") String serialNumber,
            @RequestBody PaymentRequest paymentRequest) {
        
        // 1. 構建Redis鍵
        String redisKey = redisIdempotentUtils.buildKey("payment", serialNumber);
        
        // 2. 檢查是否為重復請求
        boolean isFirstRequest = redisIdempotentUtils.checkAndSet(
                redisKey, 
                paymentRequest.getUserId(), 
                24, 
                TimeUnit.HOURS);
        
        if (!isFirstRequest) {
            // 重復請求,返回之前的處理結果或提示
            Object userId = redisIdempotentUtils.get(redisKey);
            PaymentResponse cachedResponse = getCachedPaymentResponse(serialNumber);
            return Result.success("重復請求,已處理", cachedResponse);
        }
        
        try {
            // 3. 首次請求,執行業務邏輯
            PaymentResponse response = paymentService.processPayment(paymentRequest);
            
            // 4. 緩存處理結果(可選)
            cachePaymentResponse(serialNumber, response);
            
            return Result.success("支付成功", response);
        } catch (Exception e) {
            // 5. 業務處理失敗,刪除序列號(根據業務需求決定)
            // redisTemplate.delete(redisKey);
            return Result.fail("支付失敗:" + e.getMessage());
        }
    }
    
    // 緩存和獲取支付結果的方法(實際實現略)
    private void cachePaymentResponse(String serialNumber, PaymentResponse response) {
        // 實現緩存邏輯
    }
    
    private PaymentResponse getCachedPaymentResponse(String serialNumber) {
        // 實現獲取緩存邏輯
        return new PaymentResponse();
    }
}

使用注意事項

  • 序列號傳遞方式:建議通過請求頭(Header)傳遞,避免侵入業務參數
  • 過期時間設置:根據業務場景合理設置,一般應大于業務最大處理時間
  • 異常處理:業務處理失敗時,根據實際需求決定是否刪除 Redis 中的序列號
  • Redis 高可用:確保Redis服務的高可用,可采用主從復制、哨兵或集群模式
  • 監控告警:對Redis的內存使用、接口重復請求數等指標進行監控
  • 序列號生成:確保序列號的唯一性,避免因生成策略問題導致的沖突

方案優化建議

  • 序列號壓縮:對序列號進行壓縮處理,減少Redis存儲占用
  • 本地緩存:在服務端增加本地緩存(如Caffeine),減少對Redis的訪問
  • 批量清理:對于過期數據,可采用定時任務批量清理,減輕Redis負擔
  • 分級存儲:根據業務重要性,對不同接口設置不同的存儲策略和過期時間
  • 異步處理:對于非核心流程,可采用異步方式處理,提高響應速度
責任編輯:武曉燕 來源: 一安未來
相關推薦

2024-11-01 09:28:02

2017-11-22 09:46:53

分布式架構系統

2024-06-24 01:00:00

2024-08-29 09:01:39

2025-02-23 08:00:00

冪等性Java開發

2024-03-13 15:18:00

接口冪等性高并發

2020-11-12 07:43:06

Redis冪等性接口

2022-05-23 11:35:16

jiekou冪等性

2021-01-18 14:34:59

冪等性接口客戶端

2021-01-13 11:23:59

分布式冪等性支付

2025-03-17 08:07:11

2025-10-24 07:52:56

2025-02-26 08:20:18

2020-07-15 08:14:12

高并發

2023-03-07 08:19:16

接口冪等性SpringBoot

2023-08-29 13:53:00

前端攔截HashMap

2022-04-25 11:26:16

開發SpringBoot

2009-09-04 08:17:04

Windows 7序列號檢查器

2021-03-28 09:45:05

冪等性接口數據

2011-04-19 09:25:51

點贊
收藏

51CTO技術棧公眾號

国产亚洲欧美日韩美女| 国内国产精品久久| 色综合激情久久| www.国产亚洲| 性人久久久久| 国产精品麻豆久久| 欧美另类z0zxhd电影| 久99久视频| 欧美电影在线观看一区| 亚洲乱码中文字幕综合| www.99色| 日韩精品91亚洲二区在线观看| 在线电影av不卡网址| 自拍偷拍第1页| 午夜久久tv| 伊人久久综合97精品| 久久精品xxx| 欧美一区二区性| 日本韩国欧美三级| 日本久久久网站| 亚洲三级影院| 午夜精品久久17c| 亚洲女优视频| 97精品国产97久久久久久久久久久久| 欧美激情videoshd| 亚洲一区在线不卡| 国产高清久久| 亚洲自拍高清视频网站| 国产高清一区| 日韩三级电影| 精品一区二区三区视频在线观看| 一区精品在线| 久久久精品欧美丰满| 三年中国国语在线播放免费| 99re热在线观看| 久久精品夜色噜噜亚洲aⅴ| 国产精品视频黄色| 欧美亚洲一区三区| 丁香综合av| 久久人体大胆视频| 久久精品国产亚洲a∨麻豆| 免费美女久久99| 在线精品视频视频中文字幕| 日本xxxxxx| 91精品国产视频| 色青青草原桃花久久综合 | 99热这里只有精品7| 日韩不卡免费视频| 99久久久无码国产精品性色戒| 国内精品伊人久久久久av一坑| 亚洲在线播放电影| 国产精品亲子伦对白| 污片在线免费观看| 欧美性极品xxxx娇小| 欧美一级特黄a| 成人国产在线观看| 久久这里只有精品18| 成人免费观看av| jizz欧美激情18| 色吊一区二区三区| 3d玉蒲团在线观看| 另类美女黄大片| 亚洲男人都懂第一日本| 亚洲一区二区三区毛片 | 韩国精品一区二区| 国产永久免费高清在线观看| 亚洲国产精品va在线观看黑人| 永久免费在线观看| 欧美亚洲丝袜传媒另类| 97电影在线观看| 日韩国产欧美精品一区二区三区| 青青草原国产在线| 中日韩午夜理伦电影免费| av日韩在线播放| 91欧美激情另类亚洲| 日韩国产高清影视| 亚洲熟妇av一区二区三区漫画| 亚洲欧美在线高清| 国产人成在线观看| 中文欧美在线视频| 91九色精品| 一区二区三区免费看| 26uuu成人网一区二区三区| 成人黄色网页| 国产老女人精品毛片久久| 天天碰免费视频| 亚洲成av人影院| 亚洲国产伊人| 日本一区二区三区视频免费看| 国产精品欧美一区二区三区| 电影k8一区二区三区久久 | 成人精品3d动漫| 中文字幕亚洲一区| 成人一区二区三区中文字幕| 国产亚洲人成a在线v网站| 欧美在线www| 丝袜亚洲另类丝袜在线| 日韩小视频在线播放| 99re热视频这里只精品| 日本福利片高清在线观看| 色婷婷久久av| 亚洲综合激情五月| 欧美日韩卡一卡二| 一本色道久久综合亚洲精品高清| 在线免费福利| 国产精品国产精品| 欧美亚日韩国产aⅴ精品中极品| 久久av资源| 日本天堂影院在线视频| 国产麻豆乱码精品一区二区三区| 中文欧美日本在线资源| 懂色aⅴ精品一区二区三区蜜月| 一级日本在线| 日韩精品黄色网| 久久成人羞羞网站| av色图一区| 欧美下载看逼逼| 亚洲第五色综合网| 97久久超碰国产精品电影| 亚洲一区二区三区中文字幕在线观看 | 国产成人亚洲综合a∨婷婷| 国产不卡123| 污视频网站观看| 91在线看网站| 欧美在线观看网址综合| 国产精品免费免费| 成人黄色小视频| 黄色网址在线播放| 国产精品久久久久久久9999| 99久久精品免费观看| 久久99影视| 亚洲精品66| 日本一欧美一欧美一亚洲视频| 最新国产乱人伦偷精品免费网站| 日韩一区二区三区资源| 国产精品久久久久久久美男| 日本韩国欧美一区| 国产大片一区二区| 自拍日韩欧美| 欧美xx视频| 免费黄色在线观看| 成人频在线观看| 日韩一级特黄毛片| 蜜桃日韩视频| 久久精品ww人人做人人爽| 欧美一级二级三级九九九| 亚洲人成在线电影| 福利视频一区二区| 99久久伊人网影院| 日韩**一区毛片| 日韩av自拍| 亚洲资源网站| 激情中国色综合| 蜜桃成人精品| h片在线免费观看| 成人在线播放视频| 国产一区二区三区精品在线观看| 成人免费一区| 在线视频亚洲专区| 自拍视频亚洲| 亚洲动漫在线观看| 奇米影视777在线欧美电影观看 | 一区二区日韩欧美| 久久亚洲欧美| 亚洲少妇中出一区| 菠萝菠萝蜜在线视频免费观看 | 久久69成人| 日韩综合久久| 日韩av首页| 蜜桃视频www网站在线观看| 国产高清视频在线观看| 97在线观看免费观看高清| 91网在线播放| 日韩成人av电影| 国产在线视频欧美一区| 天天射成人网| 国产精品亚洲产品| 国产亚洲一级| 久久狠狠一本精品综合网| 麻豆久久久久久久| 国产成人精品亚洲午夜麻豆| 99久久伊人网影院| 亚洲综合在线视频| 欧美午夜激情视频| 日韩有码在线播放| 国产免费黄视频| 久久久资源网| 日日夜夜天天综合| 91精品国产乱码久久久竹菊| 久久理论电影| 美国av一区二区| 国产欧美日韩中文久久| 日韩欧美中文免费| 亚洲精品一区二区在线观看| 成年无码av片在线| 日本免费不卡一区二区| 中文字幕免费在线| 中文字幕久久精品一区二区| 亚洲精品tv| 91caoporm在线视频|