网站首页 > 博客文章 正文
图/文:迷神
在企业中,特别是商城系统,秒杀是常见的应用,我们经常会遇到这样的场景,比如:秒杀活动中,有10万人抢购,如果我们只卖100件下面这个婴儿纸尿裤,那该怎么办法,这么多直接打DB上,肯定直接挂了,如果能保证库存不超发呢?
一般情况下,在企业应用开发过程中,执行抢购的逻辑流程如下:
但凡是个秒杀,都怕超卖,秒杀的特点就是这样时间极短、 瞬间用户量大,
假如100纸尿裤,现在还剩下最后2个,第一个购买请求来了,买1个,从数据库中读取到库存有2个,数量够,可以买,减库存后,更新库存为1个。
接下来第二个购买来了,想买2个,发现库存为1,不够就不可以买了。
这样是没问题的,但在在商城开发过程中,特别是大流量高并发情况下,这2个购买请求很可能是一起来的,他们都读到库存是2,都可以买,都去减库存,结果库存变成 -1了,此时就出现超发了。
还辛亏不值什么钱,如果是iPhoneX MAX,没有处理好,100个结果给卖出了200件,那估计就亏大发了。而你作为开发的程序员,也只能祭天了。
超发的解决方案:
第一种悲观锁
悲观锁主要是查询时添加更新锁,如果一个线程读库存时就将数据锁定,不允许别的线程进行读写操作,直到库存修改完成才释放锁,那么就不会出现超发问题了。
// 这里db事务开始
select id, product_name, stock, ...
from goods
where id={id} for update
update goods
set stock = stock - {quantity}
where id = {id}
// 事务db结束
这种方式的优点:
代码实现,思路都简单,主要从数据库层面解决了超发问题。
缺点为:独占锁对数据库性能影响较大。
第二种乐观锁
主要实现是通过版本号方式实现。程序主要是先获取数据库的当前版本号,执行完业务流程进行库存更新时,判断当前线程持有的版本号是否与数据库中的版本号相同,如一致则更新库存并增加版本号。
演示代码:
update goods set stock = stock - {num}, ver = ver +1 where id = {id} and ver = {version}
他的优点呢,性能相对于悲观锁好一些,没什么阻塞,但是缺点就是要可能添加重试几次的逻辑。
第三种Redis(+lua)机制实现
我们知道,使用数据库的方式和使用内存的读写速度是不在一个量级别上的,如果使用Redis,那速度肯定快很多的。
我们把第一种方案的悲观锁的数据库换为redis,把查询库存的操作与更新库存的操作绑定在一起,不被其他线程影响。
我以lua脚本为例,lua脚本读写,redis执行lua,也可以保证原子一致性,lua脚本逻辑:
具体示例代码:
我们可以用户购买请求的时候,调用lua处理。上面的处理流程中有一步”把购买记录写入 redis“,我们还是需要把数据同步到数据库中,可以使用一个定时程序,把 redis 中的记录写入数据库。或者,我们可以把购买记录写入消息队列,然后通过消费者同步到数据库。
Redis方式的优点:
性能最优,读写速度非常快,实现简单。
Redis方式的缺点:
Redis方式,需要处理数据库的同步问题,如果并发量再大,还需要保证 redis 本身是高可用的,更多的时候需要,做redis集群等。
总结:
其实,秒杀在开发过程中,要做充分的流量预估。比如使用的Redis,单机的Redis我感觉3-4W的QPS还是能顶得住的,如果更大量的请求进来,我们需要考虑的点就很多了,缓存雪崩,缓存击穿,缓存穿透等,Redis集群,主从同步等。限流方面,包括前端限流和后端限流。等等,太多细节要考虑了。
最后附上一个不错的大神搞的总结图,还不错,值得收藏,整个思路就是如下,更多流程细节,尽在图中啦。
高并发秒杀实际要做的远我们说的要多,后续会继续分享。觉得不错,记得请多多转发,关注哦。后续迷神会继续分享更多的精彩内容哦。
猜你喜欢
- 2024-10-01 「秒杀系统」从零开始打造简易秒杀系统(一):防止超卖
- 2024-10-01 「系统架构」如何设计秒杀服务的限流策略
- 2024-10-01 电商网站中,50W-100W高并发,秒杀功能是怎么实现的?
- 2024-10-01 Java商城秒杀系统的设计与实战教程(SpringBoot版)
- 2024-10-01 秒杀和抢单系统的设计思路(秒杀抢单软件)
- 2024-10-01 双十一电商秒杀系统架构设计解决方案
- 2024-10-01 一个极简高效的秒杀系统(战术实践篇)
- 2024-10-01 文心快码帮你解大厂面试题:设计一个秒杀系统,并明确指出关键点
- 2024-10-01 阿里P8架构师谈:实战讲解高并发和秒杀抢购系统设计
- 2024-10-01 「读书笔记」如何设计一个秒杀系统
你 发表评论:
欢迎- 最近发表
-
- 给3D Slicer添加Python第三方插件库
- Python自动化——pytest常用插件详解
- Pycharm下安装MicroPython Tools插件(ESP32开发板)
- IntelliJ IDEA 2025.1.3 发布(idea 2020)
- IDEA+Continue插件+DeepSeek:开发者效率飙升的「三体组合」!
- Cursor:提升Python开发效率的必备IDE及插件安装指南
- 日本旅行时想借厕所、买香烟怎么办?便利商店里能解决大问题!
- 11天!日本史上最长黄金周来了!旅游万金句总结!
- 北川景子&DAIGO缘定1.11 召开记者会宣布结婚
- PIKO‘PPAP’ 洗脑歌登上美国告示牌
- 标签列表
-
- ifneq (61)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)