基于 Redis 實現秒殺資格判斷,提升并發性能

在互聯網電商平臺上,秒殺活動往往會吸引大量用戶同時搶購,如何高效地處理高并發請求,保證用戶體驗,是一個重要的技術挑戰。本文將介紹如何基于 Redis 實現秒殺資格的判斷,提高并發性能。

基本思路

秒殺活動的核心流程可以歸納為以下幾個步驟:

  1. 檢查庫存是否足夠。
  2. 判斷用戶是否已經參加過此次秒殺。
  3. 扣減庫存。
  4. 記錄用戶的秒殺信息。
  5. 返回訂單 ID。

為了保證高并發情況下的執行效率和數據一致性,我們采用 Redis 來處理這些操作,并利用 Lua 腳本保證操作的原子性。

Lua 腳本實現

下面是一段 Lua 腳本,它能夠在 Redis 中執行上述的秒殺操作:

--- 秒殺資格判斷 Lua 腳本
--- 1. 參數列表
local voucherId = ARGV[1] -- 優惠券 ID
local userId = ARGV[2] -- 用戶 ID--- 2. 數據 key
local stockKey = 'seckill:stock:' .. voucherId -- 庫存 key
local orderKey = 'seckill:order:' .. voucherId -- 訂單 key--- 3. 腳本邏輯
--- 3.1. 判斷庫存是否足夠
if (tonumber(redis.call('get', stockKey)) <= 0) thenreturn 1
end
--- 3.2. 判斷用戶是否已經參與過秒殺
if (redis.call('sismember', orderKey, userId) == 1) thenreturn 2
end
--- 3.3. 扣減庫存
redis.call('incrby', stockKey, -1)
--- 3.4. 記錄用戶秒殺信息
redis.call('sadd', orderKey, userId)
return 0

Java 代碼實現

接下來展示如何在 Java 中調用上述 Lua 腳本,并處理返回結果:

@Override
public Result seckillVoucher(Long voucherId) {// 獲取當前用戶 IDLong userId = UserHolder.getUser().getId();// 1. 執行 Lua 腳本Long result = stringRedisTemplate.execute(SECKILL_SCRIPT,Collections.emptyList(),voucherId.toString(), userId.toString());// 2. 判斷結果int r = result.intValue();if (r != 0) {// 2.1. 如果結果不為 0,說明沒有購買資格return Result.fail(r == 1 ? "庫存不足" : "不能重復下單");}// 2.2. 如果結果為 0,說明有購買資格,生成訂單 ID 并保存到阻塞隊列中long orderId = redisIdWorker.nextId("order");// TODO: 將訂單信息保存到數據庫或消息隊列中// 3. 返回訂單 IDreturn Result.ok(orderId);
}

代碼詳解

  1. Lua 腳本部分

    • 定義兩個參數:優惠券 ID 和用戶 ID。
    • 使用 Redis 的 get 命令獲取當前庫存,判斷庫存是否足夠。
    • 使用 Redis 的 sismember 命令判斷用戶是否已經參與過秒殺活動。
    • 如果庫存足夠且用戶沒有參與過,則使用 incrby 命令扣減庫存,使用 sadd 命令記錄用戶信息。
  2. Java 代碼部分

    • 獲取當前用戶 ID。
    • 調用 stringRedisTemplate.execute 方法執行 Lua 腳本,并傳遞參數。
    • 根據 Lua 腳本返回的結果判斷用戶是否有秒殺資格。
    • 如果用戶有秒殺資格,則生成訂單 ID,并將訂單信息保存到數據庫或消息隊列中。
    • 返回訂單 ID。

對比:

圖1是從數據庫查,圖2是基于Redis,可見平均值提高了很多。

總結

通過使用 Redis 和 Lua 腳本,可以高效地處理秒殺活動中的高并發請求,確保數據的準確性和一致性。這種方法不僅提高了系統的性能,還保證了用戶的秒殺體驗。希望本文對你理解和實現秒殺系統有所幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35226.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35226.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35226.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI 編程還有前景嘛?

自從各個大廠相繼出品 AI 編程助手之后&#xff0c;AI 在編程領域的發展&#xff0c;可謂是幾無寸進。 相比于 AI 在多模態領域火熱&#xff0c;AI 在編程領域的熱度已經完全下來了。 阿七在公眾號搜索了關鍵詞「AI編程」&#xff0c;發現搜索出來的公眾號寥寥無幾&#xff0…

LLM生成模型在生物蛋白質應用:ESM3

參考&#xff1a; https://github.com/evolutionaryscale/esm 通過GPT模型原理&#xff0c;輸入蛋白質序列等模態輸出預測的蛋白質序列及結構 使用 參考&#xff1a;https://colab.research.google.com/github/evolutionaryscale/esm/blob/main/examples/generate.ipynb#sc…

(六)使用統計學方法進行變量有效性測試(43道選擇題)

本文整理了使用統計學方法進行變量有效性測試相關的練習題&#xff0c;共43道&#xff0c;適用于想鞏固理論基礎的同學。來源&#xff1a;如荷學數據科學題庫&#xff08;CDA二級-第7章&#xff09;。 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09;…

【無人機三維路徑規劃】基于樹木生長算法TGA實現復雜城市地形下無人機避障三維航跡規劃附Matlab代碼

% 定義無人機起始位置和目標位置 start_point [0, 0, 0]; % 起始位置 [x, y, z] target_point [100, 100, 100]; % 目標位置 [x, y, z] % 定義城市地形和障礙物信息 city_map imread(‘city_map.png’); % 城市地形圖像 obstacles [ 20, 30, 10; % 障礙物1位置 [x, y, z] …

三分之一的違規行為未被發現

Gigamon 調查顯示&#xff0c;隨著漏洞的針對性越來越強、越來越復雜&#xff0c;企業在檢測漏洞方面也面臨越來越大的困難&#xff0c;超過三分之一的企業表示&#xff0c;現有的安全工具無法在漏洞發生時檢測到它們。 隨著混合云環境變得越來越復雜&#xff0c;以及惡意行為…

Java 語言特定指南

Java 語言特定指南 本 Java 入門指南將教您如何使用 Docker 創建一個容器化的 Spring Boot 應用程序。在本模塊中&#xff0c;您將學習如何&#xff1a; 使用 Maven 容器化并運行一個 Spring Boot 應用程序設置本地開發環境以將數據庫連接到容器、配置調試器&#xff0c;并使…

篩斗數據:引領未來,以技術創新推動在線推廣新紀元

在數字化浪潮的推動下&#xff0c;企業在線推廣已成為市場拓展的關鍵手段。然而&#xff0c;在海量信息中精準定位目標用戶&#xff0c;有效提升轉化率&#xff0c;卻是一大挑戰。篩斗數據&#xff0c;作為一家專注于數據提取與分析的技術公司&#xff0c;正以其獨特的技術優勢…

云計算基礎知識

前言&#xff1a; 隨著ICT技術的高速發展&#xff0c;企業架構對計算、存儲、網絡資源的需求更高&#xff0c;急需一種新的架構來承載業務&#xff0c;以獲得持續&#xff0c;高速&#xff0c;高效的發展&#xff0c;云計算應運而生。 云計算背景 信息大爆炸時代&#xff1a…

Linux 標準IO的fopen和fclose

getchar(),putchar() ‐‐‐‐ 一個字符 gets(buf),puts(buf) ‐‐‐‐ 一串字符 scanf(),printf() ‐‐‐‐ 一個字符&#xff0c;一串字符都可以 fopen函數的形式 FILE * fopen(constchar *path , cost char *mode) /* * description : 打開一個文件 * param ‐ path…

進階篇07——InnoDB引擎介紹

概覽 邏輯存儲結構 架構 當執行增刪改查操作時&#xff0c;操作的是緩沖區的數據&#xff0c;如果緩沖區里沒有要操作的數據&#xff0c;就會從磁盤中讀取數據加載到緩沖區中&#xff1b;緩沖區的數據會以一定的頻率通過后臺線程刷新到磁盤中永久存儲。 內存結構 磁盤結構 后…

數據結構(Java):順序表集合類ArrayList

1、線性表 線性表&#xff0c;在邏輯結構上是連續的&#xff08;可理解為連續的一條直線&#xff0c;一對一的關系&#xff09;&#xff0c;而在物理結構上不一定連續&#xff0c;通常以數組和鏈式結構進行存儲。 線性表是一種在實際中廣泛使用的數據結構&#xff0c;常見的線…

Vue介紹與入門(一篇入門)

Vue.js 是一個流行的 JavaScript 框架&#xff0c;專門用于構建用戶界面和單頁面應用程序。它簡單易學&#xff0c;但功能強大&#xff0c;能夠幫助開發者快速構建交互性強的 Web 應用。 本教程旨在幫助那些剛開始學習 Vue.js 的開發者快速入門&#xff0c;并掌握一些基礎知識…

【UE5.1 角色練習】12-坐騎——Part2(讓角色騎上坐騎)

目錄 前言 效果 步驟 一、坐騎的父類 二、將角色附加到坐騎 三、添加坐姿 四、騎上坐騎 五、從坐騎上下來 前言 在上一篇&#xff08;【UE5.1 角色練習】11-坐騎——Part1&#xff08;控制大象移動&#xff09;&#xff09;基礎上繼續實現角色騎上坐騎的功能。 效果 …

語言的數據結構:樹與二叉樹(二叉樹篇)

語言的數據結構&#xff1a;樹與二叉樹&#xff08;二叉樹篇&#xff09; 前言概念特別的二叉樹滿二叉樹完全二叉樹 存儲結構順序存儲鏈式存儲 查找方式 前言 上文說到了樹&#xff0c;有人認為二叉樹是樹的每一個分支都有兩個子節點。其實這也對。但二叉樹在此基礎上還做了限…

RS422串口通信協議介紹和基礎代碼實現

**RS-422串口協議介紹**RS-422是一種工業標準的通信接口&#xff0c;其全稱是“平衡電壓數字接口電路的電氣特性”。它是在RS-232的基礎上發展而來&#xff0c;旨在解決RS-232通信距離短和速率低的缺點。以下是對RS-422串口協議的詳細介紹&#xff1a;傳輸速率與距離&#xff1…

MyCAT 2 簡單入門

MyCAT 2 基礎 什么是 MyCAT 2&#xff1f; MyCAT 2 是一款開源的數據庫中間件&#xff0c;它主要用于解決數據庫的分庫分表、讀寫分離等問題。MyCAT 2 基于 MyCAT 1 的架構進行優化和重構&#xff0c;具有更高的性能和穩定性&#xff0c;支持多種數據庫類型&#xff0c;包括 …

【QCustomPlot實戰系列】QCPGraph區域高亮

使用QCPDataSelection來設置選中的區域&#xff0c;并將QCPGraph的可選擇區域設置成QCP::stMultipleDataRanges void AreaPieces::initCustomPlot(QCustomPlot *parentPlot) {QVector<double> x {0, 1, 2, 3, 4, 5, 6, 7, 8};QVector<double> y {200, 560, 750…

《mysql篇》--mysql常用命令

數據庫操作 顯示當前數據庫 show databases;(database 后面要加s) 這行命令用來顯示當前有多少個數據庫 //mysql中有自帶的四個庫 創建數據庫 create database 數據庫名(name); 創建一個數據庫 create dabase if not exists <數據庫名(name)>; //如果系統有與當前創建…

前端vite+vue3——利用環境變量和路由區分h5、pc模塊打包(從0到1)

?前言 大家好&#xff0c;我是yma16&#xff0c;本文分享 前端vitevue3——利用環境變量和路由對前端區分h5和pc模塊打包&#xff08;從0到1&#xff09;。 背景&#xff1a; 前端本地開發pc和h5的項目&#xff0c;發布時需要區分開h5和pc的頁面 vite Vite 通過在一開始將應…

圖片怎么加水印?快來試試這6個圖片加水印方法(2024年新)

圖片怎么加水印&#xff1f;作為打工人在日常的工作生活中總會遇到各種各樣的工作難題&#xff0c;相信從事電商或者是設計等工作的小伙伴們&#xff0c;遇到最多的問題應該就是給圖片添加水印了。為什么要給圖片加水印&#xff1f;其實給圖片加水印最主要的目的是保護我們的圖…