最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis分布式鎖解決超賣問題的使用示例

 更新時間:2023年09月11日 11:21:10   作者:猿究院楊樹林  
超賣問題通常出現(xiàn)在多用戶并發(fā)操作的情況下,即多個用戶嘗試購買同一件商品,導致商品庫存不足或者超賣,本文就來介紹一下超賣問題,感興趣的可以了解一下

前言

超賣問題通常出現(xiàn)在多用戶并發(fā)操作的情況下,即多個用戶嘗試購買同一件商品,導致商品庫存不足或者超賣。解決超賣問題的方法有很多:樂觀鎖、Redis分布式鎖、消息隊列等。分布式鎖是一種多節(jié)點共享的同步機制,通過在多個節(jié)點之間協(xié)調(diào)訪問資源,確保在同一時間只有一個節(jié)點能夠獲取鎖并執(zhí)行關(guān)鍵操作。在電商網(wǎng)站中,可以將每個商品的庫存作為共享資源,使用分布式鎖來控制并發(fā)訪問。

分布式鎖的目的是保證在分布式部署的應用集群中,多個服務(wù)在請求同一個方法或者同一個業(yè)務(wù)操作的情況下,對應業(yè)務(wù)邏輯只能被一臺機器上的一個線程執(zhí)行,避免出現(xiàn)并發(fā)問題。

分布式鎖要滿足的條件:

  • 多進程互斥:同一時刻,只有一個進程可以獲取鎖
    ● 阻塞鎖(可選):獲取鎖失敗時可否重試
    重入鎖(可選):獲取鎖的代碼遞歸調(diào)用時,依然可以獲取鎖
  • 保證鎖可以釋放:任務(wù)結(jié)束或出現(xiàn)異常,鎖一定要釋放,避免死鎖

Redis分布式鎖:

在實現(xiàn)Redis分布式鎖之前,我們先來看看為什么Redis能實現(xiàn)分布式鎖:

在Redis中,利用Redis的setnx命令,這個命令的特征時如果多次執(zhí)行,只有第一次執(zhí)行會成功,可以實現(xiàn)互斥的效果。這滿足了多線程互斥的要求。

SETNX lock thread1

在Redis中,利用Redis的del命令,可以刪除一個key,即釋放鎖。

DEL lock

如果獲取鎖成功后服務(wù)宕機,發(fā)生了不釋放鎖的問題,Redis也可以通過給Key加有效時間,讓超時自動釋放。這樣一來,也滿足了保證鎖可以釋放,達到了分布式鎖必須滿足的條件!

EXPIRE lock 10  

并且,也不用擔心在EXPIRE設(shè)置有效期之前服務(wù)宕機,Redis的set命令可以滿足setnx和expirr的原子性,用一個指令完成兩個步驟!

set lock thread1 EX 10 NX

分布式架構(gòu)中實現(xiàn)

加Redis坐標

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

配置Redis端口信息

Spring:
	redis:
	    port: 6379
	    host: localhost

構(gòu)造加鎖工具類

public interface ILock {
    /**
     * 嘗試獲取鎖
     * @param timeoutSec 鎖持有的超時時間,過期后自動釋放
     * @return true代表獲取鎖成功; false代表獲取鎖失敗
     */
    boolean tryLock(long timeoutSec);
    /**
     * 釋放鎖
     */
    void unlock();
}
public class SimpleRedisLock implements ILock  {
    private StringRedisTemplate stringRedisTemplate;
    public SimpleRedisLock(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }
    @Override
    public boolean tryLock(long timeoutSec) {
        Boolean secuss = stringRedisTemplate.opsForValue()
                .setIfAbsent("lock", "thread", timeoutSec, TimeUnit.SECONDS);
        return secuss;
    }
    @Override
    public void unlock() {
        stringRedisTemplate.delete("lock");
    }
}

在實際秒殺業(yè)務(wù)代碼上加鎖、解鎖

@PostMapping("/kill")
    public String executeSeckillProduct(int productId,int seckillCount){
        //獲取鎖對象
        SimpleRedisLock redisLock =new SimpleRedisLock(stringRedisTemplate);
        //嘗試獲取鎖對象
        boolean isLock = redisLock.tryLock(1200);
        if(!isLock){
            return "獲取鎖失敗";
        }
        Product product = productService.findByPid(productId);
        if(product.getStock()<seckillCount){
            return "庫存不足";
        }
        product.setStock(product.getStock()-seckillCount);
        int row = productService.reduceInventory(product);
        if(row>0){
            //新增秒殺記錄
            SeckillRecord record = new SeckillRecord();
            record.setPid(product.getPid());
            record.setCount(seckillCount);
            record.setPanme(product.getPname());
            record.setTime(new Timestamp(System.currentTimeMillis()));
            recodeService.save(record);
        }
        //釋放鎖
        redisLock.unlock();
        return "秒殺成功";
    }

測試

在測試Redis分布式鎖之前,我先用了GetWay網(wǎng)關(guān)同意了API接口,由網(wǎng)關(guān)分發(fā)路由請求,通過OpenFegin實現(xiàn)通信并做到負載均衡效果,并對秒殺服務(wù)做了節(jié)點擴展,盡可能的模擬除了分布式架構(gòu):網(wǎng)關(guān)配置:

server:
  port: 7000
spring:
  application:
    name: gateway-application
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: reckill_route
          uri: lb://service-reckill
          order: 1
          predicates:
            - Path=/reckill-serv/**
          filters:
            - StripPrefix=1

先測試不加分布式鎖的效果:數(shù)據(jù)庫庫存:10

秒殺記錄:0

運行服務(wù):

JMeter測試數(shù)據(jù):每秒500個請求

JMeter端口信息:

測試結(jié)果:

庫存還剩6個,消耗4個。

秒殺記錄已經(jīng)一片糊涂了:

加上分布式鎖測試:測試數(shù)據(jù)如上。庫存為0:

秒殺記錄:

節(jié)點拓展后的三個秒殺服務(wù):

三個服務(wù)都共同通過負載均衡消費了請求!

但還要注意的一點是,對于鎖的把控一定要按時釋放,一次的不釋放,可能都會導致后續(xù)請求無法成功!

到此這篇關(guān)于Redis分布式鎖解決超賣問題的使用示例的文章就介紹到這了,更多相關(guān)Redis 超賣內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis?lua限流算法實現(xiàn)示例

    redis?lua限流算法實現(xiàn)示例

    這篇文章主要為大家介紹了redis?lua限流算法實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Spring?Boot?緩存?與?Redis問題小結(jié)

    Spring?Boot?緩存?與?Redis問題小結(jié)

    本文總結(jié)SpringBoot緩存方案,對比Redis與EnCache優(yōu)劣,指出Redis支持集群但效率較低,EnCache速度快但不支持分布式,SpringBoot默認使用ConcurrentHashMapManager,本文給大家介紹Spring?Boot緩存與Redis問題小結(jié),感興趣的朋友一起看看吧
    2025-07-07
  • Redis妙用之存儲用戶token問題

    Redis妙用之存儲用戶token問題

    這篇文章主要介紹了Redis妙用之存儲用戶token問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Redis配置文件代碼講解

    Redis配置文件代碼講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Redis配置文件的說明內(nèi)容,需要的朋友們可以學習下。
    2020-03-03
  • Redis的數(shù)據(jù)存儲及String類型的實現(xiàn)

    Redis的數(shù)據(jù)存儲及String類型的實現(xiàn)

    這篇文章主要介紹了Redis的數(shù)據(jù)存儲及String類型的實現(xiàn),redis作為k-v數(shù)據(jù)存儲,因查找和操作的時間復雜度都是O(1)和豐富的數(shù)據(jù)類型及數(shù)據(jù)結(jié)構(gòu)的優(yōu)化,了解了這些數(shù)據(jù)類型和結(jié)構(gòu)更有利于我們平時對于redis的使用,需要的朋友可以參考下
    2022-10-10
  • Redis 命令的詳解及簡單實例

    Redis 命令的詳解及簡單實例

    這篇文章主要介紹了Redis 命令的詳解及簡單實例的相關(guān)資料,這里提供基礎(chǔ)語法及使用實例,需要的朋友可以參考下
    2017-08-08
  • Redis高效查詢大數(shù)據(jù)的實踐與優(yōu)化詳細指南

    Redis高效查詢大數(shù)據(jù)的實踐與優(yōu)化詳細指南

    Redis 是一種高性能的鍵值存儲數(shù)據(jù)庫,廣泛應用于緩存,排行榜,計數(shù)器等場景,本文將圍繞如何高效查詢Redis中滿足條件的數(shù)據(jù)展開討論,感興趣的小伙伴可以了解下
    2025-04-04
  • redis中hiredis-API函數(shù)的調(diào)用方法

    redis中hiredis-API函數(shù)的調(diào)用方法

    這篇文章主要介紹了redis中hiredis-API函數(shù)的調(diào)用,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-09-09
  • redis-sentinel基礎(chǔ)概念及部署流程

    redis-sentinel基礎(chǔ)概念及部署流程

    Redis Sentinel是Redis的高可用解決方案,通過監(jiān)控主從節(jié)點、自動故障轉(zhuǎn)移、通知機制及配置提供,實現(xiàn)集群故障恢復與服務(wù)持續(xù)可用,核心組件包括Sentinel節(jié)點、主節(jié)點和從節(jié)點,部署需配置參數(shù),驗證主節(jié)點變化即成功
    2025-08-08
  • redis常用命令、常見錯誤、配置技巧等分享

    redis常用命令、常見錯誤、配置技巧等分享

    這篇文章主要介紹了redis常用命令、常見錯誤、配置技巧等分享,本文分享了12條redis知識,需要的朋友可以參考下
    2015-02-02

最新評論

西宁市| 夏津县| 西昌市| 合作市| 桂林市| 中西区| 义乌市| 张北县| 饶平县| 宣恩县| 鄂托克前旗| 新乡县| 乐昌市| 东兰县| 怀宁县| 泽普县| 万全县| 萝北县| 柳河县| 鄂托克前旗| 鄂尔多斯市| 罗平县| 会同县| 东阳市| 玉树县| 雷州市| 南涧| 岗巴县| 安国市| 峨眉山市| 桃园市| 桃源县| 四川省| 宁国市| 福贡县| 新干县| 道真| 深水埗区| 津南区| 蓝山县| 平乡县|