什么是秒杀
秒杀场景一般会在电商网站举行的一些活动,例如:对于一些特价商品,在约定时间对其限量销售,因为商品的特殊性,会吸引大量用户前来抢购。
秒杀的特点:
- 大量用户在同一时间同时进行抢购,网站瞬间访问流量激增。
- 秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功。
可能会出现的问题
数据库安全
最主要的是数据库问题,数据库不能承受一瞬间的访问
- 每秒几万的QPS直接打到数据库,基本上会把数据库打挂掉 ;
- 数据库挂了之后,秒杀服务还可能涉及其他的业务,导致别的服务一起挂。
数据安全
- 超卖现象:卖出的商品多余库存
被薅羊毛
- 链接暴露:在秒杀活动前暴露秒杀的链接,可能会开发或者其他专业人士,利用脚本进行请求。
- 恶意请求:被其他用户利用脚本模拟多个用户进行请求
解决办法
设计思路
- 将请求拦截在系统上游,降低下游压力:秒杀系统特点是并发量极大,但实际秒杀成功的请求数量却很少,所以如果不在前端拦截很可能造成数据库读写锁冲突,最终请求超时
- 利用缓存:利用缓存可极大提高系统读写速度
- 消息队列:消息队列可以削峰,将拦截大量并发请求,这也是一个异步处理过程,后台业务根据自己的处理能力,从消息队列中主动的拉取请求消息进行业务处理
前端方案
页面静态化:将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素;通过CDN来抗峰值
禁止重复提交:用户提交之后按钮置灰,禁止重复提交
用户限流:在某一时间段内只允许用户提交一次请求,比如可以采取IP限流
后台
- 限制用户访问频率:虽然拦截了浏览器访问的请求,但针对某些恶意攻击或其它插件,在服务端控制层需要针对同一个访问的用户限制访问频率
上面只拦截了一部分访问请求,当秒杀的用户量很大时,即使每个用户只有一个请求,到服务层的请求数量还是很大;比如我们有10万用户同时抢10台手机,服务层并发请求压力至少为10万
采用消息队列缓存请求:既然服务层知道库存只有10台手机,那完全没有必要把10万个请求都传递到数据库,那么可以先把这些请求都写到消息队列缓存一下,数据库层订阅消息减库存,减库存成功的请求返回秒杀成功,失败的返回秒杀结束
利用缓存应对读请求:对类似于12306等购票业务和商品秒杀场景,是典型的读多写少业务,大部分请求是查询请求,所以可以利用缓存分担数据库压力
利用缓存应对写请求:缓存也是可以应对写请求的,比如我们就可以把数据库中的库存数据转移到Redis缓存中,所有减库存操作都在Redis中进行,然后再通过后台进程把Redis中的用户秒杀请求同步到数据库中
数据库
- 数据库:单独给秒杀建立一个数据库
整体逻辑架构
技术栈
- 前端:Thymeleaf、Bootstrap、JQuery
- 后端:SpringBoot、Mybatis
- 中间件:RabbitMQ、Redis、Druid
主要技术描述
- 使用分布式Seesion,让多台服务器也可以响应
- 使用redis做缓存提高访问速度和并发量,减少数据库压力
- 使用页面伪静态化,缓存页面至浏览器,前后端分离降低服务器压力
- 使用消息队列完成异步下单,提升用户体验,削峰和降流
- 安全性优化:双重md5密码校验,秒杀接口地址的隐藏,接口限流防刷,数学公式验证码
效果展示
版权声明:本文为qq_47902348原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。