秒杀系统设计优化

12306抢票,票是有限的,库存一份,瞬时流量很是多,都读相同的库存,读写冲突,锁很是严重;
小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量多是几百几千万;
这是秒杀业务难的地方。那咱们怎么优化秒杀系统呢?html

1、难点

(1)高并发
用户在秒杀开始前,经过不停刷新浏览器页面以保证不会错过秒杀,这些请求若是按照通常的网站应用架构,访问应用服务器、链接数据库,会对应用服务器和数据库服务器形成负载压力。
(2)超卖
因为库存并发更新的问题,致使在实际库存已经不足的状况下,库存依然在减,致使卖家的商品卖得件数超过秒杀的预期。数据库

2、架构

常见的站点架构基本是这样的:
(1)浏览器端,最上层,会执行到一些JS代码
(2)站点层,这一层会访问后端数据,拼HTML页面返回给浏览器
(3)服务层,向上游屏蔽底层数据细节,提供数据访问
(4)数据层,最终的库存是存在这里的小程序

3、思路

(1)将请求尽可能拦截在上游:传统秒杀系统之因此挂,请求都压倒了后端数据层,数据库读写锁冲突严重,致使响应慢,下单基本不能成功
(2)利用缓存:这是一个典型的读多些少的应用场景,很是适合使用缓存后端

4、解决方案

(1)浏览器层请求拦截
1.产品层面,用户点击“查询”或“购票”后,按钮置灰,禁止用户重复提交请求
2.js层面,限制用户在n秒以内只能提交一次请求
(2)站点层请求拦截与页面缓存
1.静态化,将活动页面上的全部能够静态的元素所有静态化,并尽可能减小动态元素
2.限频率,同一个UID,限制访问频率,作页面缓存,n秒内到达站点层的请求,均返回同一页面
(3)服务层请求拦截与数据缓存
1.对于写请求,将全部写请求在缓存(Redis或Memcached)中,作请求单队列排队,每次只透过有限的写请求异步写入到数据层,若是均成功再放下一批,若是库存不够则队列里的写请求所有返回“已售完”
2.对于读请求,用Redis或Memcached
缓存写性能和读性能都远高于MySQL,只有很是少的写和读缓存的请求会透到数据层去
(4)数据层
1.尝试扣减库存,扣减库存成功才会进行下单逻辑(因为MySQL事务的特性,不可能彻底避免超卖)微信小程序

UPDATE table_name SET n=n-1 WHERE n>1;

2.扣减库存后进行检查,保证减完不能等于负数
查看更多:
开发一个微信小程序实例教程
HTTP协议整理
PHP安全之Web攻击
MySQL优化
Linux下常见的IO模型

参考资料:
https://my.oschina.net/xianggao/blog/524943
http://www.infoq.com/cn/articles/flash-deal-architecture-optimization浏览器

相关文章
相关标签/搜索