咱们知道如今的京东、淘宝、以及相似购物的一些项目,他们都会按期或者不按期的举行秒杀活动,以次来提升消费者的购买力,可是咱们知道秒杀这个功能怎么实现的嘛?实现过程会遇到什么难题嘛?如今跟随小编的脚步,让咱们一块儿迈进秒杀系统的实现分析。前端
这一流程虽然看似简单,可是里面仍是存在着问题的,由于咱们知道秒杀活动不是只有一我的在对该商品进行操做,而是上万、上十万以上的消费者在对一类商品进行操做,这样就会产生高并发的问题,而且假若有10万个消费者在对一类商品进行秒杀购买,那么请求接口的次数就不止是10万那么少了,多是50万,也可能更高,由于全部人在参与点击秒杀时候,都会尝试屡次点击,期待增长成功的机会。nginx
解决这一问题,咱们能够在前端进行按钮频繁点击操做的限制,防止重复提交,减小90%的重复请求。就是让用户点击一次后,就不让他点击了。如图相似:redis
就算对前端页面按钮操做进行了控制,那么也会有很大的接口请求量涌入,此时若是如此巨大的接口请求量一定会对服务器产生巨大的损害。sql
解决这一问题,就要考虑到负载均衡了,负载均衡简单来讲就是将多个请求平均分发给多台服务器,由这些服务器共同处理用户请求,到达减缓服务器负载的效果。负载均衡有硬件和软件的解决方案,硬件可使用lvs、F五、Radware等,软件可使用nginx,能够实现多个tomcat的负载均衡。除了此方式,还可使用限制流量、分散流量等操做。数据库
修改库表,主要是修改该商品做为秒杀商品提供总的商品数量,可是毕竟是秒杀活动,因此该商品的数量是固定的,而如此大用户量的秒杀,可能会形成商品数据呈现负数的状况。tomcat
解决这一问题,可使用分布式锁,分布式锁是一种悲观锁的形式,有些状况下也可使用乐观锁。能够给sql一个条件,当商品数量减一的结果大于或者等于0的时候,才给予修改商品数量,若是小于0,则不给予修改。服务器
例如该SQL:update tb_miaosha set goods_num=goods_num-1 where goods_code='' and goods_num>=0.并发
将用户信息和商品信息添加到秒杀表,这里又会出现一个问题,可能会产生,同一类商品,均由同一个用户购买,那么一块儿来参加秒杀的小伙伴们可能不乐意啦,一块儿来秒杀商品的,凭什么都由你一我的购买了。负载均衡
解决这一问题,而前台咱们可使用nginx进行ip限制,后台代码就要使用到redis-------key-value型的非关系型数据库了,对用户进行限制,好比限制该用户20秒以内,只能秒杀一次,从而解决这一问题,若是redis中没有这个key,那么就设置,而且设置过时时间,若是redis中存在这个key,那么就不进行设置。组合命令 set key valye EX time NX异步
EX:设置过时时间
time:过时时间
NX:判断redis数据库中是否有这个key
后台代码:jedis.set("要设置的key","该key的值","NX","EX",10);
若是使用了redis进行用户的限制,但仍是会出现数据库还承受不了过滤以后的请求量,这时候,应该怎么办勒?这时候确定会有小伙伴提出弄个数据库集群呀,这种方法是好,可是有没有不用花钱买服务器弄数据库集群就能够实现的呢?办法仍是有的。
解决方法,可使用令牌机制, 咱们知道商品数量是有限的,能秒杀成功的请求较少,咱们能够预先(异步)初始化一个和商品数量相同的令牌池放入到内存中,当用户发来请求,就去令牌池中取令牌,令牌数量有限,先到先得,拿到令牌的能够请求操做数据库,从而减缓数据库的压力。
当用户登录的时候,让客户端携带token,发送请求到服务器端,验证成功后让用户登陆成功,当用户进入到秒杀页面,用户点击秒杀按钮的时候,让客户端也携带token,而且在服务器端设置一个令牌池,令牌池数量为秒杀商品数量,当用户每点击秒杀按钮,就去令牌池中去令牌,先到先得,直到令牌池数量为空。
很是感谢腾讯课堂的Tony老师视频教材!!!!