【Redis】电商项目秒杀问题之下单接口优化:Redis缓存、MQ以及lua脚本优化高并发背景下的秒杀下单问题

news2024/9/28 13:18:31

目录

一、优化思路

二、缓存库存与订单

1、库存缓存的redis数据结构

2、订单信息缓存的redis数据结构

三、整体流程

四、lua脚本确保权限校验操作的原子性


一、优化思路

【Redis】电商项目秒杀问题之超卖问题与一人一单问题_1373i的博客-CSDN博客icon-default.png?t=N4HBhttps://blog.csdn.net/qq_61903414/article/details/130568972?spm=1001.2014.3001.5501在之前的文章里解决了电商项目项目超卖与一人一单的一些线程安全问题,之前的操作大体流程是:下单请求到达服务器,服务器会先查询库存是否足够,如果足够则继续判断用户是否已经下过单,如果没有下过单则去进行后续扣减库存生成订单这些操作我,完成后返回给客户端。如果在高并发情况下该接口的性能是相对较低的,因为上述操作有许多数据库的读写操作,只有等这些操作完成后我们才能返回响应,那么怎么去优化响应速度呢?

【RabbitMQ】初识消息中间件MQ_1373i的博客-CSDN博客icon-default.png?t=N4HBhttps://blog.csdn.net/qq_61903414/article/details/130138361?spm=1001.2014.3001.5501在之前RabbitMQ的文章中我们有提到MQ的优点,有一个就是异步提速,这里我们可以借鉴这一思路,异步的去处理一些操作。上述的操作其实主要分为两类,一类是对用户是否有购买权限的校验,还有一类是执行后续下单操作。这两类的关系是首先你必须得有购买权限才能去执行后续操作,那么现在我们可以将权限校验这一部分操作提取处理,请求到达服务器后先去进行用户是否有购买权限的校验,也就是先判断库存是否足够与用户是否已下单,如果用户满足购买要求则直接将订单号返回给前端,然后将该订单存入一个阻塞队列中,开启一个扫描线程,扫描该队列异步的去处理后续下单操作,但是此处值得注意的是我们如果使用Java中的阻塞队列的化,其实性能也不一定会提高,因为他是占用jvm资源的,所以我们可以使用RabbitMQ等这些消息队列中间件,我们可以使用redis来实现消息队列的效果,在后续的文章会讲到。现在我们对下单操作进行了优化,此时我们还可以对用户购买权限的校验进行优化,这两个操作都是去查询数据库的,在前面的文章里我们学习了redis缓存的使用,所以我们可以使用redis做缓存将商品的库存与订单信息缓存到redis中,此时请求到服务器后会去redis中获取到库存如果足够,在从redis中查询订单信息是否已存,如果存在则将redis中的库存进行扣减,然后加入订单缓存,将该订单号返回客户端,将订单信息交给MQ异步的去处理扣减数据库库存。

二、缓存库存与订单

1、库存缓存的redis数据结构

库存的缓存使用string就可以了,不过在缓存的时候key需要注意他的命名,在我们使用缓存时也要注意缓存时key的命名,要有区分度比如:业务名+特定信息

2、订单信息缓存的redis数据结构

这里的订单信息缓存我们主要使用它来判断用户是否已经下单所以此处缓存没有必要将所有的订单信息都缓存进来,此处我们只需要缓存用户id即可,在查询时查询该用户id是否存在即可判断,此时我们可以使用set来存储订单信息,key为业务order+商品id,value为购买过该商品的用户id,由于set数据结构的特点,当用户已经下过单时,在进行用户id存入该缓存时如果已经下过单了就会存入失败,以此来判断用户是否下过单

三、整体流程

上述流程还存在线程安全问题,即上述查询库存以及查询缓存订单信息与扣减缓存库存这一系列操作不是原子性的,那么我们可以通过lua脚本来保证上述操作的原子性以此保证线程安全。

所有整体的秒杀流程如下图:请求到服务器时先执行用户购买权限校验的lua脚本,拿到脚本执行的结果后判断是否满足下单操作,如果满足则将订单信息存入MQ并返回订单id

四、lua脚本确保权限校验操作的原子性

首先我们在使用Java操作redis执行该lua脚本时先要考虑该脚本需要哪些参数呢,我们要判断库存是否足够,就需要传入该商品的信息,然后我们需要判断用户是否已经下过单就需要知道该用户的id,所以我们需要知道商品的id与用户的id

-- 获取参数
-- 1.商品id
local productId = ARGV[1];
-- 2.用户id
local userId = ARGV[2];

-- 构造缓存的key
-- 1.订单key
local orderKey = "secKill:order" .. productId;
-- 2.库存id
local stockKey = "secKill:stock" .. productId;

-- 判断库存是否足够
if (tonumber(redis.call('get',stockKey)) <= 0) then
    -- 库存不足 返回1
    return 1;
end

-- 判断是否下过单
if (redis.call('sismember',orderKey,userId) == 1) then
    -- 存在 返回2
    return 2;
end

-- 满足扣减库存
redis.call('incrby',stockKey,-1);
-- 下单:缓存订单中加入该用户
redis.call("sadd",orderKey,userId);
return 0;

然后我们可以在Java中调用API执行这段lua脚本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/546477.html

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

相关文章

chatgpt赋能Python-python3_打印

Python3 打印&#xff1a;一篇介绍性SEO文章 如果你是一名Python编程工程师&#xff0c;那么你一定知道在Python中打印是一项基本技能。在Python3中&#xff0c;打印已经发生了一些变化&#xff0c;本文将介绍Python3中打印的新特性和使用方法&#xff0c;并为您提供一些最佳实…

算法设计与分析:随机化算法(作业-必做)(头歌实验)

第1关&#xff1a;硬币实验 任务描述 本关任务&#xff1a;计算机产生的伪随机数来模拟抛硬币试验。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.如何获取数组的长度&#xff0c;2.如何遍历数组。 随机数 随机数在随机化算法设计中扮演着十分重要的角…

云原生CAx软件:gRPC

gRPC是Google基于HTTP/2协议开发的一套开源、跨平台的高性能RPC框架&#xff0c;可用于连接微服务架构内的各种服务&#xff0c;亦可以连接客户端与后端服务。 Ref. from gRPC gRPC is a modern open source high performance Remote Procedure Call (RPC) framework that can…

策划能力提升攻略:让你成为行业大咖

策划能力的提高是没有立竿见影的&#xff0c;首先你了解策划的本质吗?了解市场营销的本质吗?了解战略和策略的关系吗? 不是经常把什么IMC/USP/4P/4C/DNA/核心价值挂在嘴边&#xff0c;会做做波特SWOT分析、用用BCG的模型、MINKSY的7S模型这些就是策划了的。 别人的理论你可…

WEB AK赛

文章目录 web1_观字SSRF常见的URL绕过方式 web2_观星web3_观图web4_观心签到_观己 web1_观字 <?php#flag in http://192.168.7.68/flag if(isset($_GET[url])){$url $_GET[url];$protocol substr($url, 0,7);if($protocol!http://){die(仅限http协议访问);}if(preg_matc…

安装Maven 3.6.1:图文详细教程(适用于Windows系统)

一、官网下载对应版本 推荐使用maven3.6.1版本&#xff0c;对应下载链接&#xff1a; Maven3.6.1下载地址 或者&#xff0c;这里提供csdn下载地址&#xff0c;点击下载即可&#xff1a; Maven3.6.1直链下载 其他版本下载地址&#xff1a; 进入网址&#xff1a;http://mave…

【Linux之IO系统编程学习】01.open函数使用 代码实现touch命令效果

【Linux之IO系统编程学习】 项目代码获取&#xff1a;https://gitee.com/chenshao777/linux_-io.git &#xff08;麻烦点个免费的Star哦&#xff0c;您的Star就是我的写作动力&#xff01;&#xff09; 01.open函数使用 & 代码实现touch命令 一、open函数&#xff08;ma…

ARM处理器概论与组织

目录 1.ARM产品系列 2.体系结构 3.ARM指令集 定义&#xff1a; ARM的指令集&#xff1a; 4.编译原理 5.ARM存储模型 6.ARM的8种工作方式 ARM&#xff08;Advanced RISC Machines&#xff09;有三种含义 一个公司的名称、一类处理器的通称、一种技术&#xff0c;我们在这…

【中阳期货】人工智能AI与期货有什么 关系

人工智能&#xff08;AI&#xff09;和期货交易之间有许多相互影响的因素。AI可以帮助期货交易者在交易决策中更好地应对大量数据&#xff0c;加强交易系统预测能力&#xff0c;优化资产配置策略。以下是AI与期货交易的一些具体关系&#xff1a; 数据分析&#xff1a;AI有能力高…

python pickle反序列化分析

文章目录 前言Pickle的作用pickle反序列化pickletools和反序列化流程漏洞产生(__reduce__)R指令的绕过通过i和o指令触发 总结 前言 春秋杯中遇到了一道python题&#xff0c;使用的了numpy.loads()触发反序列化漏洞&#xff0c;百度学习了一下&#xff0c;发现numpy.load()会先…

【mysqlbinlog 恢复数据】

不小心把数据删掉了 首先要拿到binlog文件 命令行执行 /usr/local/mysql/bin/mysqlbinlog --base64-outputdecode-rows --start-datetime"2023-05-19 09:01:32" --stop-datetime"2023-05-19 09:01:35" -v /Users/zylong/Downloads/mysql-bin.003178 --re…

动态规划-状态机模型

大盗阿福 题目 链接&#xff1a;https://www.acwing.com/problem/content/1051/ 阿福是一名经验丰富的大盗。趁着月黑风高&#xff0c;阿福打算今晚洗劫一条街上的店铺。 这条街上一共有 N N N 家店铺&#xff0c;每家店中都有一些现金。 阿福事先调查得知&#xff0c;只…

chatgpt赋能Python-python3_9怎么下载

Python 3.9: 从哪里下载以及如何安装 Python是一种高级编程语言&#xff0c;被广泛使用于数据科学、人工智能、Web开发等领域。Python的最新版本是Python 3.9&#xff0c;它带来了一些新的特性和改进。对于那些希望尝试Python 3.9的人来说&#xff0c;了解如何下载和安装是很重…

chatgpt赋能Python-python3下载文件

Python3下载文件&#xff1a;从入门到实践 在Python编程语言中&#xff0c;下载文件是一个常见的需求。无论你是想下载图片、视频、文本文件或者其他类型的文件&#xff0c;Python都提供了强大的工具来实现这一操作。在本文中&#xff0c;我们将深入探讨如何使用Python3来下载…

pwn入门(二)环境搭建

一.前言 在上一篇中介绍了一下pwn和一些前置知识&#xff0c;但是呢以我的感觉&#xff0c;我觉得ctf还是得多做题的&#xff0c;所以呢&#xff0c;我选择边做边学&#xff0c;我觉得这样可以快速熟悉pwn还可以有成就感。 这一篇就是搭建环境的分享&#xff0c;同时还有大佬告…

【问题记录】USB monitor抓包工具显示音频数据CRC error

一&#xff0c;简介 在进行UAC2.0调试的过程中&#xff0c;使用USB monitor抓包工具抓取音频流数据出现数据错乱现象&#xff0c;本文对该问题进行分析记录。 二&#xff0c;问题记录及分析过程 2.1 先看下正常的抓包数据是什么样子&#xff1a; 从上图可以看出&#xff0c;…

VMware ESXi 6.0 多网卡接入 多网段绑定 虚机接入不同网段

网卡要与对应网段的网络联通。不同的网卡接入不同网段的网络。要为vmware esxi 6 的多个虚机配置不同网段的ip地址&#xff0c;首先选择主机对应的网口分别插上处于在不同网段的网线。 配置管理网络 多个网口接入&#xff0c;只可以配置一个管理网络&#xff0c;就是只有一个网…

基于XGBOOST模型预测货物运输耗时 - Part 2 通过方差分析了解文本型变量与数值型目标变量的关系

在分析数据之前&#xff0c;我们需要剔除异常值的影响&#xff0c;也就是在某个分组情况下&#xff0c;标准差过大&#xff08;标准差越大&#xff0c;证明情况越不稳定&#xff09;&#xff0c;如果标准差比较小&#xff0c;就算是最小值和最大值差的比较大&#xff0c;我也认…

chatgpt赋能Python-python3下载numpy包

Python3 下载numpy包教程 如果你是一名Python开发者&#xff0c;那你一定不会陌生于NumPy。NumPy是Python中的一个科学计算库&#xff0c;它主要用来处理数组和矩阵运算。本文将会教你如何在Python3中下载NumPy库。 步骤一&#xff1a;确认你已经安装了pip 如果你使用的是Py…

chatgpt赋能Python-python3__2__3

Python323 - 一个强大的编程工具 介绍 Python323 是一种高级编程语言&#xff0c;最初由 Guido van Rossum 在 1989 年创建。Python 3.2.3 是 Python 3 的其中一个发行版&#xff0c;它拥有很多新特性和改进。Python323 可以运行在多种操作系统上&#xff0c;包括 Windows、L…