谈谈电商秒杀高并发的处理

谈谈电商秒杀高并发的处理众所周知现在连市场卖菜的大妈都快知道高并发了,哈哈,那么我们生活中是否接触过高并发呢。当然了哈哈,比如你给你女朋友抢秒杀的化妆品什么的了。秒杀最棘手的问题就是解决并发带来的问题。下面我们一起聊聊喽。首先我们来说下问题:秒杀高并发带来的最大问题,就是库存超卖。(如果你没看过我的文档,导致你写公司秒杀业务时库存超卖了,公司损失了,将你开除了,你会多么不开心,哈哈我来给你写稻草救救你)嘻嘻嘻嘻嘻…

大家好,又见面了,我是你们的朋友全栈君。

众所周知现在连市场卖菜的大妈都快知道高并发了,哈哈,那么我们生活中是否接触过高并发呢。当然了哈哈,比如你给你女朋友抢秒杀的化妆品什么的了。秒杀最棘手的问题就是解决并发带来的问题。下面我们一起聊聊喽。

首先我们来说下问题:秒杀高并发带来的最大问题,就是库存超卖。(如果你没看过我的文档,导致你写公司秒杀业务时库存超卖了,公司损失了,将你开除了,你会多么不开心,哈哈我来给你写稻草救救你)

嘻嘻嘻嘻嘻嘻嘻

解决方案:解决高并发导致库存超卖问题的核心思想就是,库存扣减要保证串行化操作

1.数据库层面解决方案:

    这种方式实现起来最简单,就是利用乐观锁。

    update product set num=num-1 where num-1>0 and pid=#{pid}

    使用此方法一定要注意,set num 时一定不要使用,set num=#{num},这样做的话不能保证原子化操作,并发还是会有问题(覆盖更新)。

    缺点:数据库存在瓶颈,首先是连接数,更重要是多个请求更新一条数据,会互相检查是否死锁(笛卡尔积)。而秒杀问题就是请求量大并发高。那怎么办?继续看小老弟说咯。

2.使用缓存(Redis等)解决方案:

    使用缓存确实可以解决数据库瓶颈的问题,例如Redis天然的串行化操作(Redis单线程),并且在数据内存中做操作很快。

    使用Redis的自增incr或自减decr操作库存,判断返回结果是否为0,如果为0表示秒杀失败。这样不就保证了库存的不超卖。

    此时你可能说,啊我明白了不就是用Redis的缓存来搞吗,简单简单。本大侠哈哈一笑,要是这样的话本大侠不也去BAT了。

=================下面才是关键=========================================

说说我们目前满意的Redis方案的问题吧。

先说一个优化的问题:

1.每次我们通过Redis查询库存都是通过远程连接的方式,虽然很快,但是并发大的时候,这里还是要优化一下的。

怎么优化?简单的说就是,当发现Redis库存为0时,我们在程序中设置一个标识位,秒杀逻辑中每次进来先判断标志位。这样库存为0时就直接返回,而不用再远程连接查询Redis了。

你可能会说这样就行了吧?对于一般的秒杀来说应该可以了,但我还要和大家说说更多的优化和优化时的问题,希望对大家的工作有好的提示或者帮助,那样我会很高兴的。哈哈

2.每次当我们秒杀成功后,会创建订单、通知库房、通知快递等一系列操作,如果我们把这些操作也放在秒杀时来处理,那么我们程序处理起来可想而知,会很慢的。那么这时我们就要优化,怎么优化?

实现异步处理,我们可以通过MQ(RocketMQ等消息队列)来实现异步处理,当用户秒杀成功后,我们发送消息给其他服务,然后返回给用户秒杀结果,这样是不是就很快了呢。对是快了。

那么问题来了:用户秒杀成功后需要付款,但是此时是异步操作,队列可能并没有处理完消息,怎么办怎么办?哈哈,这时我们需要在前端加一个轮询,轮询什么?轮询查询秒杀的结果(象征的意思意思用户,排队中什么什么的了)。下面代码

谈谈电商秒杀高并发的处理

简单讲讲这段代码:首先判断登录就不说了,后面通过用户名查询下当前用户是否秒杀成功了,然后然后问题来了,哈哈为什么我下面要使用了数据库查询?而不是查询缓存中的商品数量是否为0,因为还是之前的问题,队列没有消化完,用户秒杀成功的记录还没有生成,如果查询数据库商品没有了,那就代表队列已经处理完了,代表你秒杀失败了GG。如果还有库存,那么返回success(0)告诉用户排队中。直到数据库中库存没有了,那么代表队列处理完了,这时候你在查询Redis应该有订单信息的,如果没有那么你真的是秒杀失败了。讲到这里可能大家理会的差不多了,但是这段代码中还是存在问题?什么问题呢,那就是当他查询Redis时队列消息还是没处理她的消息,当他查询数据库之前,队列处理完了,这样你查数据库发现库存没有了,你就会返回秒杀失败,但其实你是秒杀成功的。这样还是会影响用户体验的。你可能会说不能吧,那么巧。哈哈我就是要和你说高并发下这种情况出现很正常。所以呢,我们要防止,怎么防止呢?

终极解决方案:

谈谈电商秒杀高并发的处理

我们在查数据库判断库存为0时(标记:数据库库存为0,消息肯定处理完了,也就是redis肯定有订单了,因为有妹子问了,我必须更新一下哈哈),我们再次查询Redis里是否已经有生成的订单了,这样就避免了问题咯。这也就是江湖中传闻的江湖秘诀,双重校验锁,哈哈,其实关于秒杀啊高并发的问题还有很多,这类问题每一行代码都是要考虑很多情况的,希望我再这里能给大家一个抛砖引玉的作用。小老弟要睡觉了,如果哪里说得不对别喷啊,都同行哈哈哈。

   

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138411.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • onedrive申请1T免费空间_onedrive如何升级空间

    onedrive申请1T免费空间_onedrive如何升级空间最近想要备份一下数据,但是硬盘备份容易坏不放心,百度网盘更恶心。听说Onedrive可以通过学生身份注册账号得到1T的免费空间,故尝试了一下,非常顺利。总结如下:账号注册网址:https://www.microsoft.com/zh-cn/education/products/office/default.aspx输入学生邮件地址正常注册即可查看剩余空间windows上的剩余空间查看出了问题:这里找到了一种更加通用的方法:https://zhida…

  • html限制输入文本长度_get请求url长度限制多少位

    html限制输入文本长度_get请求url长度限制多少位http响应报文,如果响应的内容比较大,客户端怎么样判断接收完了呢?1.http协议有正文大小说明的content-length2.或者分块传输chunked的话读到0\r\n\r\n就是读完了http响应内容比较大的话,会分成多个tcpsegment发送,不是最后一个segment的话,tcp的payload不会有httpheader字段,如果是最后一个tcpse…

  • MySQL为什么用B+树,而不用B树?

    MySQL为什么用B+树,而不用B树?

  • java.lang.Integer

    java.lang.IntegerpublicstaticintbitCount(intarg0)//二进制中出现1的数量publicbytebyteValue()//转化为bytepublicstaticintco

  • 路由器刷机教程图解_小米路由器刷机教程[通俗易懂]

    路由器刷机教程图解_小米路由器刷机教程[通俗易懂]小米路由器刷机教程小米路由器刷机教程登陆路由器设置页面,刷新官方固件.使用路由器助手,自动检查并自动更新固件.使用u-boot模式,可刷新任何固件.小编温馨提示:你需要先在小米官网下载好相应固件到本地,再进入路由器设置,进入系统升级,选择下载好的固件进行系统升级….其他2016/06/10小米助手刷机教程小米助手刷机教程小米助手的刷机功能只能算是小米MIUI系统升级功能,如果无法开机…

  • 分布式系列——分布系统的一些技术

    这一个系列会总结和整理自己在公司使用的技术和一些比较流行的分布式系统用的技术! 这一个系列的学习会一直持续,让自己成长,让自己走出舒适区!看过这一句话:大部分的害怕是多数是因为懒惰!!!在路上,少年,不卑不亢!

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号