基于 Redis 实现秒杀资格判断,提升并发性能

news2025/1/11 13:55:11

在互联网电商平台上,秒杀活动往往会吸引大量用户同时抢购,如何高效地处理高并发请求,保证用户体验,是一个重要的技术挑战。本文将介绍如何基于 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) then
    return 1
end
--- 3.2. 判断用户是否已经参与过秒杀
if (redis.call('sismember', orderKey, userId) == 1) then
    return 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) {
    // 获取当前用户 ID
    Long 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. 返回订单 ID
    return 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.coloradmin.cn/o/1862991.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot整合MongoDB JPA使用

一、整合MongoDB SpringDataMongoDB是 SpringData家族成员之一&#xff0c;MongoDB的持久层框架&#xff0c;底层封装了 mongodb-driver。mongodb-driver 是 MongoDB官方推出的 Java连接 MongoDB的驱动包&#xff0c;相当于JDBC驱动。 SpringBoot整合 MongoDB&#xff0c;引入…

MySQL数据库—MHA高可用配置及故障切换

目录 一、MHA概述 1.什么是 MHA 2.MHA 的组成 &#xff08;1&#xff09;MHA Node&#xff08;数据节点&#xff09; &#xff08;2&#xff09;MHA Manager&#xff08;管理节点&#xff09; (3)MHA 的特点 二、MHA的一主两从部署 实验设计 实验具体操作 1.配置主…

一次breach1靶机的渗透测试

1.端口扫描和信息收集 2.CMS后台信息收集 3.解密HTTPS流量 4.tomcat的后台利用 5.提权 1.端口扫描和信息收集&#xff1a; 首先进行主机发现&#xff0c;找到目标机器&#xff1a; nmap -sP 192.168.110.1/24 找到目标机器&#xff0c;进行端口扫描&#xff1a; nmap -T4 …

CS144 Lab3 TCPSender复盘

一.基础概念 1.TCPSender在TCPSocket中的地位与作用 Lab0中实现了基于内存模拟的流控制-字节流&#xff08;ByteStream&#xff09;&#xff0c;底层使用std::deque实现&#xff0c;根据最大容量Capacity进行容量控制。个人理解它相当于应用层的输入输出缓存区&#xff0c;用户…

【opencv - C++ - Ubuntu】putText 显示中文最快方法

话不多说&#xff0c;直接上代码 #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/freetype.hpp>using namespace std; using namespace cv;int main(void) {Mat image(1000, 1800, CV_8UC3, Scalar(200,162,33));Ptr<freetype::F…

如何找到合适的Python第三方库?

找合适的Python库其实很简单&#xff0c;按照以下三步法&#xff0c;你能找到90%的Python库。 1、百度谷歌搜索 明确自己的需求&#xff0c;用Python来干什么&#xff0c;力求简短明了。比如定位“数据分析”&#xff0c;然后去搜索关键词【Python数据分析第三方库】&#xf…

【嵌入式Linux】i.MX6ULL 外部中断服务函数的初始化

文章目录 1. Cortex-A7 中断系统1.1 分析1.2 具体处理流程 2. 外部中断服务函数的初始化2.1 基本流程分析2.2 具体代码分析2.2.1. 定义中断处理类型和结构体2.2.2. 初始化中断系统2.2.3. 注册中断处理函数2.2.4. 具体的中断处理逻辑2.2.5. 默认的中断处理函数 3. 完整代码 本文…

django学习入门系列之第三点《案例 小米商城二级菜单》

文章目录 样例划分区域搭建骨架logo区域完整代码 小结往期回顾 样例 划分区域 搭建骨架 <!-- 二级菜单部分 --> <div class"sub-header"><div class"container"><div class"logo">1</div><div class"sea…

[word] Word表格怎么填充序列号? #微信#微信#笔记

Word表格怎么填充序列号&#xff1f; Word表格怎么填充序列号&#xff1f;在Excel中填充序列号是很轻松的事情&#xff0c;在Word表格中填充序列号就没那么简单&#xff0c;但是还是有小技巧&#xff0c;可以实现Word表格序号填充&#xff0c;还能自动更新。 1、插入序号 先…

JAVAEE之网络原理_传输控制协议(TCP)的滑动窗口、流量控制、拥塞控制、延迟应答、捎带应答机制

前言 在前面几节&#xff0c;我们讲解了TCP协议的基本概念、报文格式。还介绍了确认应答机制、超时重传、连接管理机制&#xff0c;在本节中 我们将会继续介绍TCP协议的其他机制。 一、滑动窗口机制&#xff08;效率机制&#xff09; 在前面的章节中我们讨论了确认应答策略&…

C++ ─── vector的实现

知识点&#xff1a; ① 因为vector是模版&#xff0c;所以声明和定义都放在.h中&#xff0c;防止出现编译错误 .h不会被编译&#xff0c;在预处理中.h在.cpp中展开所以在编译时只有.cpp 而 .cpp顺序编译&#xff0c;只会进行向上查找&#xff0c;因此至少有函数的声明。 ②memc…

【Linux】进程 | 控制块pcb | task_struct | 创建子进程fork

目录 Ⅰ. 进程的概念&#xff08;Process&#xff09; 1. 什么是进程&#xff1f; 2. 多进程管理 3. 进程控制块&#xff08;PCB&#xff09; task_struct 的结构 Ⅱ. 进程查看与管理 1. 使用指令查看进程 2. /proc 查看进程信息 3. 获取进程 ID 4. 创建子进程 原因…

在Ubuntu22.04 使用stable-diffusion-webui 秋叶整合包

背景 众所周知&#xff0c;赛博菩萨已经发布了windows下的整合包&#xff0c;开箱即用&#xff0c;且集成度较高。 那我为啥非要在Ubuntu下使用呢&#xff1f; 当然是因为主力机就是Ubuntu系统啦。而且涉及到sd webui API 的调用&#xff0c;在Ubuntu 下调试更加方便一点。 那…

PG实践|内置函数之GENERATE_SERIES之深入理解

&#x1f4eb; 作者简介&#xff1a;「六月暴雪飞梨花」&#xff0c;专注于研究Java&#xff0c;就职于科技型公司后端工程师 &#x1f3c6; 近期荣誉&#xff1a;华为云云享专家、阿里云专家博主、腾讯云优秀创作者、ACDU成员 &#x1f525; 三连支持&#xff1a;欢迎 ❤️关注…

2024年第十五届蓝桥杯青少组大赛8月24日开启

据蓝桥杯青少组官网显示&#xff0c;2024年第十五届蓝桥杯青少组大赛8月24日开启。 蓝桥杯青少组历届题库地址&#xff1a;http://www.6547.cn/question/cat/2 蓝桥杯青少组历届真题下载&#xff1a;http://www.6547.cn/wenku/list/10

【神经网络】CNN网络:深入理解卷积神经网络

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&#xff01; CNN网络&#xff1a;深入理解…

VideoLLaMA 2:多模态视频理解新突破,音频理解能力再升级,挑战 GPT-4V

前言 近年来&#xff0c;人工智能技术飞速发展&#xff0c;尤其是大模型的出现&#xff0c;为视频理解和生成领域带来了前所未有的机遇。然而&#xff0c;现有的视频大模型&#xff08;Video-LLM&#xff09;在处理视频中复杂的时空信息和音频信息方面仍存在不足&#xff0c;例…

【C++11(二)】lambda表达式和可变参数模板

一、可变参数模板 C11的新特性可变参数模板 能够让您创建可以接受 可变参数的函数模板和类模板 // Args是一个模板参数包&#xff0c;args是一个函数形参参数包 // 声明一个参数包Args...args&#xff0c;这个参数包中可以包含0到任意个模板参数。 template <class ...Arg…

笔记101:OSQP求解器的底层算法 -- ADMM算法

前言1&#xff1a;这篇博客仅限于介绍拉格朗日乘子法&#xff0c;KKT条件&#xff0c;ALM算法&#xff0c;ADMM算法等最优化方法的使用以及简版代码实现&#xff0c;但不会涉及具体的数学推导&#xff1b;不过在下面我会给出具体数学推导的相关文章和截图&#xff0c;供学有余力…

Elasticsearch:使用 Llamaindex 的 RAG 与 Elastic 和 Llama3

这篇文章是对之前的文章 “使用 Llama 3 开源和 Elastic 构建 RAG” 的一个补充。我们可以在本地部署 Elasticsearch&#xff0c;并进行展示。我们将一步一步地来进行配置并展示。你还可以参考我之前的另外一篇文章 “Elasticsearch&#xff1a;使用在本地计算机上运行的 LLM 以…