zookeeper 秒杀场景

秒杀一般有几个场景

1.电商秒杀商品 2.抢红包 3.抢票
2假设一个场景如下
     某电商公司搞活动,一折秒杀,推出几种秒杀的商品,每种商品1000个,预计100w人抢购 要求: 不能超卖.绝对不可以卖多了. 数据库要扣减库存,并且记录订单明细

2
难点分析
1.不能阻塞. 海量的请求就像血栓一样,遍走周身,一旦遇到瓶颈,就会堵塞整个血管. 所以一定要让海量的用户请求,尽快结束.
2.数据库单行更新 大量的 update 库存表 set 剩余数量=剩余数量-1 where 商品ID=? 这种单行更新,有行锁,会阻塞其他事务,占用宝贵的数据库处理能力.

解决思路
1.Web服务器集群层,卸载流量 海量的用户秒杀请求,本质上是一个排序,先到先得. 但是如此之多的请求,完全响应,难度又很大. 所以在Web服务器集群,可以考虑卸载流量. 比如每十个请求,随机抛弃九个,只放行一个请求到后续处理环节. 把秒杀的排序模式,变为随机抽奖的模式.


2.Web服务器集群层,缩小锁范围. 每次秒杀活动开始之前.先计算活动推出的商品数量,然后分配一个限额到每个Web服务器. 比如一个活动推出秒杀商品 电视,手机,衣服各1000件,那么每台服务器的限额就是125件. 将这个限额写入ZooKeeper,Web服务器监听到限额的变化,就会重新初始化各自的商品剩余数量.


模拟实例
private static ConcurrentHashMap<String,Integer> map=new ConcurrentHashMap<String, Integer>();    
    private void zooKeeperHandle(){
        //将ZooKeeper的变化,初始化到Web服务器全局容器
        map.put("电视机", 125);
        map.put("手机", 125);
        map.put("衣服", 125);
}


假设用户请求秒杀电视机,它只是锁了该Web服务器电视机的数量。(该Web服务器手机和衣服还可以继续并发处理,当然其他的Web服务器也在同时处理电视机的秒杀请求) 这样缩小了锁定的范围,增加了系统处理的吞吐量.

如果这个剩余数量大于零,则将用户ID放入电视机购买队列, 
然后告知用户秒杀成功如果这个剩余数量等于零,则告知用户秒杀失败. 
即便别的Web服务器还有电视机的剩余配额.


3.ZooKeeper层,ZooKeeper变更库存信息 假设活动期间,需要修改库存信息。 两种可能, 第一种,该商品已经卖了500件,电商不想继续卖了. 第二种,从仓库中又找到了一些积压库存..

两种情况,都直接修改ZooKeeper中相应商品的配额. 
Web服务器会监听变化,并重新初始化全局容器.


4.消息队列层,多消费者处理 
消费者主要是从队列获取购买请求,发送至数据库 
扣减数据库库存 
写订单明细记录


5.数据库层,使用存储过程代替JDBC调用 由于使用了多消费者处理同一队列,增加吞吐量,避免队列堆积过大. 但是多消费者,必然导致数据库出现单行更新问题(不推荐)

单行更新问题就是多个线程,并发修改同一条记录,导致事务相互阻塞.浪费了数据库宝贵的处理能力.


以上转载 
http://m.blog.itpub.net/29254281/viewspace-1800617/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值