基于 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.rhkb.cn/news/360815.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

规则引擎-Aviator 表达式校验是否成立

目录 介绍特性使用更多文献支持 介绍 Aviator是一个轻量级、高性能的Java表达式执行引擎&#xff0c;它动态地将表达式编译成字节码并运行。 特性 支持绝大多数运算操作符&#xff0c;包括算术操作符、关系运算符、逻辑操作符、位运算符、正则匹配操作符(~)、三元表达式(?:…

申请专利前需要了解的步骤

申请专利前需要了解的步骤 在创新日益成为推动社会进步的重要动力的今天&#xff0c;专利的申请与保护显得尤为重要。然而&#xff0c;对于许多初次接触专利申请的人来说&#xff0c;这个过程可能会显得复杂而繁琐。 一、明确创新内容并评估其可专利性 在申请专利前&#xff…

vue3前后端开发:响应式对象不能直接成为前后端数据传输的对象

如图所示&#xff1a;前端控制台打印显示数据是没问题的&#xff0c;后端却显示没有接收到相应数据&#xff0c;但是后端的确接收到了一组空数据 直接说原因&#xff1a;这种情况唯一的原因是没有按正确格式传递参数。每个人写错的格式各有不同&#xff0c;我只是说明一下我在…

Python+Pytest+Allure+Yaml接口自动化测试框架详解

PythonPytestAllureYaml接口自动化测试框架详解 编撰人&#xff1a;CesareCheung 更新时间&#xff1a;2024.06.20 一、技术栈 PythonPytestAllureYaml 版本要求&#xff1a;Python3.7.0,Pytest7.4.4,Allure2.18.1,PyYaml6.0 二、环境配置 1、安装python3.7&#xff0c;并配置…

[Redis]事务

Redis事务 Redis 事务提供了一种将多个命令请求打包的功能。然后&#xff0c;再按顺序执行打包的所有命令&#xff0c;并且不会被中途打断。 但是&#xff0c;事务中的每条命令都会与 Redis 服务器进行网络交互&#xff0c;比较浪费资源 所以&#xff0c;日常开发中不建议使…

小区业主管理系统

摘 要 随着城市化进程的加速和人口的不断增加&#xff0c;小区的数量也在不断增加。小区作为城市居民居住的主要场所&#xff0c;其管理工作也变得越来越重要。传统的小区业主管理方式存在诸多问题&#xff0c;如信息传递不畅、业务处理效率低下等。因此&#xff0c;开发一个高…

搜维尔科技:「研讨会」惯性动捕技术在工效学领域应用研讨会

Movella将于7月2日&#xff08;周二&#xff09;下午2点举行主题为惯性动捕技术在工效学领域应用的研讨会。来自Movella的伙伴赋能经理Jeffrey Muller作为嘉宾出席&#xff0c;届时主讲人将为大家带来Xsens惯性动捕技术在工效学领域的应用分享。同时&#xff0c;研讨会还邀请多…

高频面试题基本总结回顾1(含笔试高频算法整理)

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

从零开始做题:修猫

修猫 1 题目 2 解题 2.1 使用Stegslove分析图片 (base) ┌──(holyeyes㉿kali2023)-[~/Misc/tool-misc] └─$ java -jar Stegsolve.jar 2.2 analyse -frame browser 2.3 得到flag DASCTF{818ca3a840e768da7d5fcdeaedd5012f}

基于Java微信小程序校园订餐系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…

springcloud-gateway 路由加载流程

问题 Spring Cloud Gateway版本是2.2.9.RELEASE&#xff0c;原本项目中依赖服务自动发现来自动配置路由到微服务的&#xff0c;但是发现将spring.cloud.gateway.discovery.locator.enabledfalse 启动之后Gateway依然会将所有微服务自动注册到路由中&#xff0c;百思不得其解&a…

1.8 HTTP协议结构

我们来看一下HTTP协议到底由哪些部分组成&#xff0c;也就是HTTP协议的结构。知道了这些知识才能在接口测试中游刃有余。 我们看上图&#xff0c;HTTP协议由四部分组成 起始行 描述请求和响应的基本信息。 当是请求时&#xff1a;请求方法是GET&#xff0c;调用的地址&#…

JAVA【案例5-2】模拟默认密码自动生成

【模拟默认密码自动生成】 1、案例描述 本案例要求编写一个程序&#xff0c;模拟默认密码的自动生成策略&#xff0c;手动输入用户名&#xff0c;根据用户名自动生成默认密码。在生成密码时&#xff0c;将用户名反转即为默认的密码。 2、案例目的 &#xff08;1&#xff09…

区块链技术与数字货币

1.起源 ➢中本聪(Satoshi Nakamoto), 2008 ➢比特币:一种点对点的电子现金系统 2.分布式账本技术原理 1.两个核心技术&#xff1a; ➢以链式区块组织账本数据实现账本数据的不可篡改 ➢分布式的可信记账机制 2.共识机制&#xff1a;由谁记账 ➢目的&#xff1a; ⚫ 解…

C语言基础——函数(2)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 文章目录 前言 一、return语句 二、数组做函数参数 三、嵌套调用和链式访问 3.1 嵌套调用 3.2 链式访问 四、函数声明和定义 4.1 单个文件 4.2 多个文件 总结 前言 大家好啊&#xff0c;继我们上一…

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

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

Python爬虫学习 | Scrapy框架详解

一.Scrapy框架简介 何为框架&#xff0c;就相当于一个封装了很多功能的结构体&#xff0c;它帮我们把主要的结构给搭建好了&#xff0c;我们只需往骨架里添加内容就行。scrapy框架是一个为了爬取网站数据&#xff0c;提取数据的框架&#xff0c;我们熟知爬虫总共有四大部分&am…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十七)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 27节&#xff09; P27《26.Stage模型-UIAbility的启动模式》 本节讲解 UIAbility的启动模式&#xff1a;Stage模型的应用&#x…

排序之插入排序----直接插入排序和希尔排序(1)

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 排序之插入排序----直接插入排序和希尔排序(1) 收录于专栏【数据结构初阶】 本专栏旨在分享学习数据结构学习的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…

算法训练营day20--235. 二叉搜索树的最近公共祖先+701.二叉搜索树中的插入操作 +450.删除二叉搜索树中的节点

一、235. 二叉搜索树的最近公共祖先 题目链接&#xff1a;https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/ 文章讲解&#xff1a;https://programmercarl.com/0235.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E8%BF%91…