电商秒杀场景的解决策略与具体实现方案
程序员文章站
2024-03-19 13:43:52
...
问题场景:某电商网站,po了一个活动宣传活动,3月8号,1元秒杀iphone7 ,限量10台,看你手速哦,快来抢吧。
广大吃瓜群众:
程序员:
程序员说 | 受不了 | 怎么办? |
---|---|---|
短时间的大访问量 | 网站服务器 | 同网站,不同项目部署,/独立域名 避免对网站造成影响 |
高并发问题,不停刷新 | 数据库 | 页面静态化 |
带宽 200k的页面 并发1w次 ,带宽为2G | 带宽 | 秒杀页缓存cdn 租借临时带宽,反向代理服务器,nginx ,甚至用户浏览器。(cookie) |
不能提前下单 | 服务器 | url动态化,+随机数 |
下单之后的抢的问题 | sql | 乐观锁 |
应该还是比较好理解的,下面对下单开始/结束,和 抢单的后端处理具体分析一下。
- 抢单开始和结束的控制
在上表中列出来的解决方案中看出,利用页面静态化、数据静态化,反向代理
等方法可以避免带宽和sql压力
,但是随之而来一个问题,页面抢单按钮也不会刷新了,可以把js
文件单独放在js服务器上,由另外一台服务器写定时任务
来控制js 推送。
另外还有一个问题,js文件会被大部分浏览器缓存,我们可以使用xxx.js?v=随机数
的方式来避免js被缓存。
-
抢单的后端处理
本文中 ,iphone7的数量为10 ,可以把第一次的请求放到安比加10 ,我们这里就设置为50。利用redis 的队列,进行这50个请求的控制,
这里还有一个分叉,如果是依次的请求,可以依次判断,如果是一次性的,可以随机取50个请求,放入队列中。再对这50个数据进行二次过滤,也就是入库之前的处理,从而尽量的保证公平和完整。
这里采用到乐观锁来实现,也就是数据版本记录机制。
给数据加上版本,当更新时的版本与读取的版本相同时,才更新版本+1。这样两条相同的更新数据就不会冲突。
php文件乐观锁的实现:flock 锁上一个文件,执行前判断文件锁状态,执行完毕,解锁,这样执行前只有没有锁才能执行。
拓展:
数据库的并发量问题
数据库集群 : 每个节点 可以分摊 多少 内存 数据库并发 并不能用 在线人数等同 。这两者之间没有明确的对应关系 。
并发是指:同一时刻有多少请求在 数据库 上跑 。
查询方面可以用sphinx + 索引来实现
写入方面,索引+触发器
硬件方面:cpu 影响较小 ,可以从以下方面来设置
mysql 的 innodb 数据表 时, 20个商家 ,每个人各像他下1000单子,时间在55ms左右 。
innodb_buffer_pool_size=2G
innodb_buffer_pool_instances=1
innodb_buffer_pool_size
这个值 可以设置到物理机的80% 比方你的宿主为4G内存 ,就可以到3.2G 。用来缓存索引和 行数据
推荐阅读