关于秒杀,第一反应都是实现起来比较复杂。难点在于:并发读+并发写+设计兜底方案的实现。
比如QQ,虽然数据量很大,但是多数的数据都是细粒度的数据查询,锁冲突比较少;但12306涉及到大量的读写操作,对可用性,高性能,数据一致都有要求。
在开始前,先说一些基本概念,通常互联网的应用包含了:
nginx代理层
tomcat站点层
rpc service服务层
数据层(cache和db)
方向上,降低数据层锁冲突,具体两大要点:
-
缓存降读
-
降低写的频率,将请求拦截在系统上游
所以,优化的方向,也是从上面几层展开。
一:优化方案:
1:端上的请求拦截(浏览器/app)
比如通过答题延长请求发出时间
js做一些基本性的校验等
2:站点层的请求拦截
同一个uid xxS内才可以请求,比如计数和限速
这里可以看到,站点层可能承担了大部分的流量和压力,所以站点层需要设计成无状态服务,通过水平扩展的方式,分担压力;
但是站点层如何限速呢?
-
如果使用redis,那么redis需要做proxy切分
-
当然,也可以通过nginx七层路由,相同的id落地到相同的tomcat站点上,做内存计数
3:服务层的请求拦截
流量削峰,比如根据你的数据库抗压能力,计算出tps,或者通过业务库存计算等
流量削峰解决了什么问题:
-
服务端处理变得更加平稳
-
节省服务器的资源成本
如何削峰:
-
排队:通过消息队列来缓冲瞬时流量
4:数据库处理
分库分表,热点数据隔离,读写分离等等
二:12306产品方案:
-
对于秒杀系统来说,下单与支付可以分离,所以支付系统基本上可以不用特殊处理
-
不同的地域分时售票等
三:兜底方案
1:降级
比如当秒杀流量达到5W/s时,把一些无关紧要的查询记录从之前的100条,降低为10条,这个可以直接由参数来控制
2:拒绝服务
当系统达到一定的阈值时,设置过载保护,比如在nginx层上做限制,直接返回503 code码等
更多交流,也欢迎您关注我的微信公众号: