高并发限时抢购秒杀

标签: 并发 抢购 | 发表时间:2021-01-22 07:00 | 作者:带瓦瓦
出处:https://juejin.cn/backend

一、方案介绍

介绍使用SpringBoot开发的高并发限时抢购秒杀系统,除了实现基本的登录、查看商品列表、秒杀、下单等功能,项目中还针对高并发情况实现了系统缓存、降级和限流。

二、开发工具

IntelliJ IDEA + Navicat + Git + Chrome

三、开发技术

调试工具 :Postman

后端技术 :SpringBoot + MyBatis + MySQL

中间件技术 : Druid + Redis + RabbitMQ + Guava

四、秒杀优化思路

  1. 将请求尽量拦截在系统上游:传统秒杀系统之所以挂,请求都压倒了后端数据层,数据读写锁冲突严重,几乎所有请求都超时,流量虽大,下单成功的有效流量甚小,我们可以通过限流、降级等措施来最大化减少对数据库的访问,从而保护系统。

  2. 充分利用缓存:秒杀商品是一个典型的读多写少的应用场景,充分利用缓存将大大提高并发量

五、核心使用的技术点

1. 两次MD5加密

将用户输入的密码和固定Salt通过MD5加密生成第一次加密后的密码,再讲该密码和随机生成的Salt通过MD5进行第二次加密,最后将第二次加密后的密码和第一次的固定Salt存数据库

好处:

  1. 第一次作用:防止用户明文密码在网络进行传输
  2. 第二次作用:防止数据库被盗,避免通过MD5反推出密码,双重保险

2. session共享

验证用户账号密码都正确情况下,通过UUID生成唯一id作为token,再将token作为key、用户信息作为value模拟session存储到redis,同时将token存储到cookie,保存登录状态

好处: 在分布式集群情况下,服务器间需要同步,定时同步各个服务器的session信息,会因为延迟到导致session不一致,使用redis把session数据集中存储起来,解决session不一致问题。

3. JSR303自定义参数验证

使用JSR303自定义校验器,实现对用户账号、密码的验证,使得验证逻辑从业务代码中脱离出来。

4. 全局异常统一处理

通过拦截所有异常,对各种异常进行相应的处理,当遇到异常就逐层上抛,一直抛到最终由一个统一的、专门负责异常处理的地方处理,这有利于对异常的维护。

5. 页面缓存 + 对象缓存 (不一定做。。。)

  1. 页面缓存:通过在手动渲染得到的html页面缓存到redis
  2. 对象缓存:包括对用户信息、商品信息、订单信息和token等数据进行缓存,利用缓存来减少对数据库的访问,大大加快查询速度。

6. 页面静态化 (不一定做。。。)

对商品详情和订单详情进行页面静态化处理,页面是存在html,动态数据是通过接口从服务端获取,实现前后端分离,静态页面无需连接数据库打开速度较动态页面会有明显提高

7. 本地标记 + redis预处理 + RabbitMQ异步下单 + 客户端轮询

描述:通过三级缓冲保护,

1、本地标记 

2、redis预处理 

3、RabbitMQ异步下单,最后才会访问数据库,这样做是为了最大力度减少对数据库的访问。

实现:

  1. 在秒杀阶段使用本地标记对用户秒杀过的商品做标记,若被标记过直接返回重复秒杀,未被标记才查询redis,通过本地标记来减少对redis的访问
  2. 抢购开始前,将商品和库存数据同步到redis中,所有的抢购操作都在redis中进行处理,通过Redis预减少库存减少数据库访问
  3. 为了保护系统不受高流量的冲击而导致系统崩溃的问题,使用RabbitMQ用异步队列处理下单,实际做了一层缓冲保护,做了一个窗口模型,窗口模型会实时的刷新用户秒杀的状态。
  4. client端用js轮询一个接口,用来获取处理状态

8. 解决超卖

描述:比如某商品的库存为1,此时用户1和用户2并发购买该商品,用户1提交订单后该商品的库存被修改为0,而此时用户2并不知道的情况下提交订单,该商品的库存再次被修改为-1,这就是超卖现象

实现:

  1. 对库存更新时,先对库存判断,只有当库存大于0才能更新库存
  2. 对用户id和商品id建立一个唯一索引,通过这种约束避免同一用户发同时两个请求秒杀到两件相同商品
  3. 实现乐观锁,给商品信息表增加一个version字段,为每一条数据加上版本。每次更新的时候version+1,并且更新时候带上版本号,当提交前版本号等于更新前版本号,说明此时没有被其他线程影响到,正常更新,如果冲突了则不会进行提交更新。当库存是足够的情况下发生乐观锁冲突就进行一定次数的重试。

9. 使用数学公式验证码

描述:点击秒杀前,先让用户输入数学公式验证码,验证正确才能进行秒杀。

好处:

  1. 防止恶意的机器人和爬虫
  2. 分散用户的请求

实现:

  1. 前端通过把商品id作为参数调用服务端创建验证码接口
  2. 服务端根据前端传过来的商品id和用户id生成验证码,并将商品id+用户id作为key,生成的验证码作为value存入redis,同时将生成的验证码输入图片写入imageIO让前端展示
  3. 将用户输入的验证码与根据商品id+用户id从redis查询到的验证码对比,相同就返回验证成功,进入秒杀;不同或从redis查询的验证码为空都返回验证失败,刷新验证码重试

10. 使用RateLimiter实现限流

描述:当我们去秒杀一些商品时,此时可能会因为访问量太大而导致系统崩溃,此时要使用限流来进行限制访问量,当达到限流阀值,后续请求会被降级;降级后的处理方案可以是:返回排队页面(高峰期访问太频繁,等一会重试)、错误页等。

实现:项目使用RateLimiter来实现限流,RateLimiter是guava提供的基于令牌桶算法的限流实现类,通过调整生成token的速率来限制用户频繁访问秒杀页面,从而达到防止超大流量冲垮系统。(令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务)

六、参与代码仓库

。。。

相关 [并发 抢购] 推荐:

高并发限时抢购秒杀

- - 掘金 后端
介绍使用SpringBoot开发的高并发限时抢购秒杀系统,除了实现基本的登录、查看商品列表、秒杀、下单等功能,项目中还针对高并发情况实现了系统缓存、降级和限流. 调试工具 :Postman. 后端技术 :SpringBoot + MyBatis + MySQL. 中间件技术 : Druid + Redis + RabbitMQ + Guava.

Web系统大规模并发——电商秒杀与抢购

- - 行业应用 - ITeye博客
电商的秒杀和抢购,对我们来说,都不是一个陌生的东西. 然而,从技术的角度来说,这对于Web系统是一个巨大的考验. 当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要. 这次我们会关注秒杀和抢购的技术实现和优化,同时,从技术层面揭开,为什么我们总是不容易抢到火车票的原因.

京东抢购服务高并发实践

- - 企业架构 - ITeye博客
限时抢购又称闪购,英文Flash sale,起源于法国网站Vente Privée. 闪购模式即是以互联网为媒介的B2C电子零售交易活动,以限时特卖的形式,定期定时推出国际知名品牌的商品,一般以原价1-5折的价格供专属会员限时抢购,每次特卖时间持续5-10天不等,先到先买,限时限量,售完即止. 顾客在指定时间内(一般为20分钟)必须付款,否则商品会重新放到待销售商品的行列里.

秒杀抢购思路以及高并发下数据安全

- - 编程学习网
我们通常衡量一个Web系统的吞吐率的指标是QPS(Query Per Second,每秒处理请求数),解决每秒数万次的高并发场景,这个指标非常关键. 举个例子,我们假设处理一个业务请求平均响应时间为100ms,同时,系统内有20台Apache的Web服务器,配置MaxClients为500个(表示Apache的最大连接数目).

redis实现高并发下的抢购/秒杀功能 - 周伯通的麦田 - 博客园

- -
高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:. 抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢. 查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数.

春运火车票抢购指南

- - 极客公园-GeekPark
[核心提示]一年几度的节日抢票又要上演了,从明天开始每天的 Todolist 里又要多一个“买票”事项,那么如何能够快速、方便地买上回家的票呢. 按照节前15天的春运方案,今年春运将从 1月26日开始了. 而在一周前 12306 的通知已经将火车票网络和电话预售时间提前到了 20 天,即从1月7日也就是明天开始,我们就可以通过网站和电话来预订春运火车票了.

高并发

- - 开源软件 - ITeye博客
垂直扩展是一种用于增加单个ActiveMQ代理连接数(因而也增加了负载能力)的技术.默认情况下,. ActiveMQ的被设计成尽可高效的传输消息以确保低延迟和良好的性能. 默认情况下,ActiveMQ使用阻塞IO来处理传输连接,这种方式为每一个连接分配一个线程. 你可以为ActiveMQ代理使用非阻塞IO(同时客户端可以使用默认的传输)以减少线程的使用.

并发导论

- - 并发编程网 - ifeve.com
由于之前工作中的疏忽,在使用Java多线程并发的时候出了问题,遂决心全面学习并发相关知识. 写作本文的意图只是希望在写作过程中把想不清楚或是一时无法掌握的地方反复揣摩记录下来. 写作本文参考的各种资料较多,抱歉的是文末的参考文献中对一些叫不上名字或没有出处的资料文献并未列举出来. 由于本人是初入职场的菜鸟,更是并发的门外汉,文中关于并发以及其他软硬件、程序设计语言的论据也许不够客观甚至不够正确.

苹果是如何控制排队抢购的?

- Summer - 每日鲜果精选
大家都知道苹果产品每每发布就排队抢购的事情. 往年iPod发布也这样,只是现在大家都有了所以就不去争了.而这个排队现象如何形成的呢?首先如果只有几个人去买肯定形成不了排队, 而在心理学上叫做Lining效应 , 排队效应. 这个就是一种人性的弱点, 好比你看一个饭馆排队下意识认为这个饭馆菜一定好吃..

惠普员工抢购TouchPad致网站瘫痪

- kxxoling - cnBeta.COM
由于已经宣布停产TouchPad平板电脑,惠普(微博)近日面向内部员工推出了优先购买计划,但由于需求旺盛而导致订购网站瘫痪. 惠普上个月宣布放弃webOS设备运营,包括TouchPad在内. 随后惠普将TouchPad售价下调至99.99美元,结果导致TouchPad在美国和加拿大被抢购一空.