redis秒杀(PHP版本)
前提提要
今天产品端提了个需求,院校组要求借调我去帮忙,因为我以前做过商城,现在他们需求做一个积分商城,需要做一个秒杀模块,结果毫无意外的我被借调过去了,刚好可以复习一下以前的知识,现在介绍一下redis的秒杀机制,首先大家需要了解redis的基础信息,可以参考小编的前面的文章 https://blog.csdn.net/masterphp/article/details/130728703,现在开始介绍redis秒杀,只要有两种方式来实现,锁和队列
秒杀流程概述
在进行Redis的实现之前,我们先简要介绍一下秒杀的流程:
1.用户在前端页面选择要秒杀的商品,并提交订单;
2.系统校验用户提交的订单是否合法,如商品库存是否充足、用户是否符合参加条件等;
3.系统将订单信息写入数据库,并返回给用户订单处理中的状态;
4.用户在订单处理中不断轮询订单状态,直到订单完成。
在秒杀流程中,系统需要进行多次校验和处理,其中最关键的部分就是判断商品库存是否充足,这部分需要保证数据的可靠性和并发性。
秒杀实现原理
1.使用Redis队列存储订单:秒杀活动中,会有大量的订单请求同时涌入系统,若采用传统的关系型数据库进行存储,会导致并发量过大,数据库连接数量过多,从而降低系统的性能和稳定性。为了解决这个问题,我们可以使用队列来存储订单信息。Redis中提供了List类型的数据结构,可用作队列的实现。通过将订单信息放入Redis队列中,系统可以快速处理大量的订单请求,并以先到先服务的顺序进行处理。
2.使用Redis预减库存:秒杀活动中,需要对商品库存进行实时监控,否则会因为库存不够而导致订单处理失败。但是,如果每个订单都从数据库中查询商品库存,将会增加数据库的压力,导致系统并发性能降低。
为了解决这个问题,我们可以使用Redis的预减库存策略。当用户抢购时,我们先使用Redis缓存中的商品库存信息,并实时更新该缓存信息,如果库存已经减少至0,则直接返回秒杀失败。
3.使用Redis分布式锁:在秒杀活动中,虽然我们使用Redis队列和预减库存,但是系统仍然需要面对大量的并发请求。在这些请求中,可能会有多个用户同时对同一个商品进行抢购,这就需要我们使用分布式锁来保证数据的可靠性。Redis的分布式锁使用方式非常简单,在抢购开始时,我们使用Redis的SETNX操作来尝试获取分布式锁,如果获取成功,则对库存进行操作,操作完成后,释放分布式锁。如果获取分布式锁失败,则需等待一段时间重试。
乐观锁实现方式
//添加商品库存
public function addGoodsStock(Request $request)
{
//接受数据
$goods_id = $request->input('goods_id');
$store = $request->input('store');
//设置商品库存的key
$key = 'seckill_goods_id_'.$goods_id;
$res = Redis::set($key,$store);
return $res;
}
//用户秒杀商品
public function buy(Request $request)
{
//接受数据
$uid = $request->input('uid');
$goods_id = $request->input('goods_id');
//商品库存key
$key = 'seckill_goods_id_'.$goods_id;
//监听对应的key,事务提交之前,如果key被修改,则事务被打断
Redis::watch($key);
//获取商品库存
$store = Redis::get($key);
//抢购成功用户集合key
$setKey = 'userGoodsSuccess';
//判断该用户是否已经抢购过(该用户id是否在抢购用户集合中)
$userBuyStatus = Redis::sismember($setKey,$uid);
if($userBuyStatus){
return '您已抢过!';
}
if($store){
//记录用户信息,更新库存(保证这一组命令,要么全部成功,要么都不成功)
Redis::multi();//开始事务
Redis::decr($key);//减少库存
//将用户id添加到抢购成功用户集合中
Redis::sadd($setKey,$uid);
$result = Redis::exec();//提交,判断当前的key是否被某个客户端修改了
//结果判断
if($result){
//操作数据库,修改商品库存销量
DB::table('goods')->where('id', $goods_id)->decrement('stock', 1, ['sale' => DB::raw('`sale`+1')]);
//创建订单信息
return '抢购成功!';
}else{
return '抢购失败,请重试!';
}
}else{
return '已抢光!';
}
}
队列实现方式
//初始化库存队列
public function init(Request $request)
{
//接受参数
$goods_id = $request->input('goods_id');
$store = $request->input('store');
//获取key
$key = 'list_seckill_goods_id_'.$goods_id;
//防止对已经设置过的商品库存进行覆盖
if(!empty(Redis::llen($key))) {
return '已经设置了库存';
}
//初始化缓存,删除抢购用户id队列key和成功信息保存key,这个是抢购时生成的,防止错乱,初始化删除
$userListKey = 'user_goods_id_'.$goods_id;
Redis::command('del', [$userListKey, 'success']);
// 将商品存入Redis链表中
for($i = 1; $i <= $store; $i++) {
Redis::lpush($key, $i);
}
//设置过期时间
Redis::expire($key, 120);
echo '商品存入队列成功,数量:'.Redis::llen($key);
}
//redis队列抢购
public function start(Request $request)
{
// 模拟随机登录用户
$uid = mt_rand(1, 9999);
//$uid = $request->input('uid');
$goods_id = $request->input('goods_id');
//获取key
$key = 'list_seckill_goods_id_'.$goods_id;
//从链表的头部删除一个元素,返回删除的元素,因为pop操作是原子性,即使很多用户同时到达,也是依次执行
$count = Redis::lpop($key);
if (!$count) {
return '已抢光!';
}
//已抢购用户id队列
$userListKey = 'user_goods_id_'.$goods_id;
//判断该用户是否已经抢购过(该用户id是否在抢购用户集合中)
$userBuyStatus = Redis::sismember($userListKey,$uid);
if($userBuyStatus){
return '您已抢过!';
}
//将用户id添加到抢购成功用户集合中
Redis::sadd($userListKey,$uid);
$msg = '抢到的人为:'.$uid.',抢到商品的顺序为第'.$count.'个';
Redis::lpush('success', $msg);
//操作数据库,修改商品库存销量
DB::table('goods')->where('id', $goods_id)->decrement('stock', 1, ['sale' => DB::raw('`sale`+1')]);
//创建订单信息
return '恭喜您抢购成功!';
}
相关文章:
redis秒杀(PHP版本)
前提提要 今天产品端提了个需求,院校组要求借调我去帮忙,因为我以前做过商城,现在他们需求做一个积分商城,需要做一个秒杀模块,结果毫无意外的我被借调过去了,刚好可以复习一下以前的知识,现在介…...
图形用户界面(GUI)在AI去衣技术中的作用与重要性
引言: 随着人工智能技术的不断进步,AI去衣这一概念逐渐进入公众视野。它指的是利用深度学习算法,从图片或视频中自动移除人物的衣物,生成相应的“裸体”图像。尽管这项技术在道德和隐私方面引发了诸多争议,但其背后的技…...
如何阅读:一个已被证实的低投入高回报的学习方法的笔记
系列文章目录 如何有效阅读一本书笔记 如何阅读:一个已被证实的低投入高回报的学习方法 麦肯锡精英高效阅读法笔记 读懂一本书笔记 文章目录 系列文章目录第一章 扫清阅读障碍破解读不快、读不进去的谜题一切为了阅读小学教师让你做,但中学老师阻止你做的…...
pycharm 安装“通义灵码“并测试
过程:“File>setting>Plugins” 提示: 翻译之后: 点击"接受"之后,提示一下图片,点击ok 安装完成: 安装完"通义灵码"之后,需要登陆,登陆后测试 参考…...
React 之 useMemo Hook (九)
useMemo 是 React 的一个Hook,它允许你“记住”一些计算值,只有在依赖项之一发生变化时才会重新计算这些值。这有助于避免不必要的重新计算和渲染,从而提高应用程序的性能。 代码栗子(计算一个斐波那契数列的值)&#…...
短视频矩阵系统源码saas开发--可视化剪辑、矩阵托管、多功能合一开发
短视频矩阵系统源码saas开发(可视化剪辑、矩阵托管、智能私信聚合、线索转化、数据看板、seo关键词、子账号等多个板块开发) 短视频矩阵系统是一种集成了多种功能的系统,旨在帮助用户在短视频平台上进行高效的内容创作、管理和发布。根据您提…...
百度大模型文心一言api 请求错误码 一览表
错误码说明 千帆大模型平台API包含两类,分别为大模型能力API和大模型平台管控API,具体细分如下: 大模型能力API 对话Chat续写Completions向量Embeddings图像Images 大模型平台管控API 模型管理Prompt工程服务管理模型精调数据管理TPM&RP…...
Unity调用智谱API(简单操作 文本实时翻译)
代码展示: using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI;public class ZhiPuAi : MonoBehaviour {// API的端点URLpublic string…...
Android 开机启动扫描SD卡apk流程源码分析
在开机的时候,装在SD卡的apk和装在系统盘的apk扫描过程不一样,系统盘apk在系统启动过程中扫描,而SD卡上的就不是,等系统启动好了才挂载、扫描,下面就说下SD扫描的流程: 在SystemServer启动MountService&am…...
如何恢复回收站中被删除的文件?3个恢复策略,实测有用!
“刚刚一不小心把回收站清空了,大家有什么好用的方法可以帮我恢复回收站中删除的文件吗?快帮帮我吧!” 在使用电脑的过程中,我们有时可能会不小心将重要的文件或文件夹删除到回收站,并且随后可能进一步从回收站中彻底删…...
Unity---版本控制软件
13.3 版本控制——Git-1_哔哩哔哩_bilibili Git用的比较多 Git 常用Linux命令 pwd:显示当前所在路径 ls:显示当前路径下的所有文件 tab键自动补全 cd:切换路径 mkdir:在当前路径下创建一个文件夹 clear:清屏 vim…...
基于大模型的idea提炼:围绕论文和引用提炼idea之ResearchAgent
前言 对本博客比较熟悉的朋友知道,我司论文项目组正在基于大模型做论文的审稿(含CS英文论文审稿、和金融中文论文审稿)、翻译,且除了审稿翻译之外,我们还将继续做润色/修订、idea提炼(包含论文检索),是一个大的系统,包…...
前端深度扩展
1 为什么要有webpack 模块化管理:构建工具支持Common JS、ES6模块等规范;依赖管理:在大型项目中,手动管理文件依赖关系。webpack可以自动分析项目中的依赖关系,将其打包成1个或多个优化过的文件,减少页面加…...
雷军-2022.8小米创业思考-6-互联网七字诀之专注:有所为,有所不为;克制贪婪,少就是多;一次解决一个最迫切的需求
第六章 互联网七字诀 专注、极致、口碑、快,这就是我总结的互联网七字诀,也是我对互联网思维的高度概括。 专注 从商业角度看,专注就是要“把鸡蛋尽量放在一个篮子里”。这听起来似乎有些不合理,大家的第一反应可能是“风险会不会…...
【禅道客户案例】北大软件携手禅道,开启产品化之路新征程
在项目制项目模式下,软件公司根据客户的需求进行短期项目开发,具有灵活、高效、受众面广的优点,在业界得到了广泛的应用。但这种模式也面临诸多挑战,软件公司需要不断地开发新项目来维持业务增长,由于没有自己的产品也…...
解释泛型(Generics)在Java中的用途
在Java中,泛型(Generics)是一种在编译时期提供类型检查和约束的机制,它使得类和接口可以被参数化,即你可以定义一个类或接口,并通过参数传入具体的类型。泛型增加了代码的复用性和类型安全性,同…...
给网站网页PHP页面设置密码访问代码
将MkEncrypt.php文件上传至你网站根目录下或者同级目录下。 MkEncrypt.php里面添加代码,再将调用代码添加到你需要加密的页进行调用 MkEncrypt(‘123456’);括号里面123456修改成你需要设置的密码。 密码正确才能进去页面,进入后会存下cookies值&…...
124.反转链表(力扣)
题目描述 代码解决(思路1:双指针) class Solution { public:ListNode* reverseList(ListNode* head) {ListNode*temp;//保存cur下一个节点ListNode*curhead;ListNode*preNULL;while(cur){tempcur->next;// 保存一下 cur的下一个节点&#…...
【数据库原理及应用】期末复习汇总高校期末真题试卷06
试卷 一、选择题 1. ________是长期存储在计算机内的有组织,可共享的数据集合. A.数据库管理系统 B.数据库系统 C.数据库 D.文件组织 1. 有12个实体类型,并且它们之间存在15个不同的二元联系,其中4个是1:1联系类型,5…...
Offline:IQL
ICLR 2022 Poster Intro 部分离线强化学习的对价值函数采用的是最小化均方bellman误差。而其中误差源自单步的TD误差。TD误差中对target Q的计算需要选取一个max的动作,这就容易导致采取了OOD的数据。因此,IQL取消max,,通过一个期望回归算子…...
告别死记硬背!信息系统项目管理师(高项)思维导图活用法:从考前3个月到考前一天的全周期规划
信息系统项目管理师备考革命:用思维导图构建你的动态知识引擎 备考信息系统项目管理师(高项)的过程,常常让考生陷入两难困境:一方面要掌握庞杂的知识体系,另一方面又要应对实际工作中的时间压力。传统死记硬…...
PiliPlus视频播放进度条:自定义绘制与交互实现终极指南
PiliPlus视频播放进度条:自定义绘制与交互实现终极指南 【免费下载链接】PiliPlus PiliPlus 项目地址: https://gitcode.com/gh_mirrors/pi/PiliPlus PiliPlus是一款功能强大的视频播放器应用,其中自定义视频播放进度条是其核心功能之一。这个进度…...
用Matlab+Yalmip+Gurobi搞定微电网优化配置:从电工杯A题到实战避坑指南
MatlabYalmipGurobi微电网优化实战:从建模到竞赛应用的完整指南 微电网优化配置是能源系统研究中的经典问题,也是数学建模竞赛中的高频考点。去年电工杯A题就曾让参赛者头疼——如何在满足负荷需求的前提下,合理配置风光储系统,实…...
Qwen3-0.6B-FP8多场景落地:建筑图纸问答+规范条文即时检索系统
Qwen3-0.6B-FP8多场景落地:建筑图纸问答规范条文即时检索系统 1. 引言:当轻量化大模型遇上专业领域 想象一下,你是一位建筑设计师,正在电脑前审阅一份复杂的CAD图纸。你需要快速理解某个构件的尺寸,或者确认某个设计…...
显卡性能调优:从系统瓶颈到高效GPU资源分配的完整指南
显卡性能调优:从系统瓶颈到高效GPU资源分配的完整指南 【免费下载链接】Atlas 🚀 An open and lightweight modification to Windows, designed to optimize performance, privacy and security. 项目地址: https://gitcode.com/GitHub_Trending/atlas…...
021工程微服务治理实战:Spring Cloud Alibaba 2024 全景落地指南
工程微服务治理实战:Spring Cloud Alibaba 2024 全景落地指南 在工程行业数字化转型的深水区,我们面临着独特的技术挑战:一个大型地产项目往往涉及设计、采购、施工、监理、成本、营销等十几个业务域,服务调用链路复杂;…...
Python实战:出租车计费模拟器开发(附完整代码与测试用例)
Python实战:出租车计费模拟器开发(附完整代码与测试用例) 出租车计费系统是城市交通中不可或缺的一部分,而用Python模拟这一过程不仅能帮助初学者理解条件分支和输入输出处理,还能培养将现实问题转化为代码的思维能力。…...
Qwen3Guard-Gen-8B真实案例:如何用AI模型自动拦截不当言论
Qwen3Guard-Gen-8B真实案例:如何用AI模型自动拦截不当言论 1. 引言:内容安全的新挑战 在数字内容爆炸式增长的今天,各类平台都面临着内容审核的巨大压力。传统的关键词过滤和规则匹配系统已经难以应对日益复杂的网络环境,特别是…...
阿里通义Z-Image-Turbo WebUI图像生成模型:从安装到生成,一站式教程
阿里通义Z-Image-Turbo WebUI图像生成模型:从安装到生成,一站式教程 1. 引言 在当今数字内容创作蓬勃发展的时代,AI图像生成技术正以前所未有的速度改变着我们的创作方式。阿里通义实验室推出的Z-Image-Turbo模型,凭借其出色的图…...
springboot-vue基于web的天气预报气候研究系统
目录系统架构设计技术栈选择功能模块划分数据库设计接口设计规范前端实现要点后端实现要点部署方案扩展性考虑测试计划项目时间规划注意事项项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作系统架构设计 采用前后端分离架构&am…...
