
秒杀活动是真,只是你从一开始就注定抢不到罢了!
为什么?
对电商来说,尤其是那种大型电商,每一次秒杀一定会有非常多用户参与,这一瞬间的访问量会成背书增加,即使后台扩容也不一定承受的那种。
于是,后台的程序员们就针对这类秒杀做了业务分析,确保商家跟平台的权益。
举个例子:双十一我们要卖10台这个手机,但是价格呢比官网要便宜200块,假设会有10000人来抢这台手机。你一听,这我们服务器扛不住啊,那么后台会思考哪些问题呢?
问题都预设出来了,那怎么设计才能扛得住大量用户涌入,让我们一起对症下药:
根据九章算法系统设计4S分析法,他的解决思路可以分为四步
篇幅有限,感兴趣的朋友也可以来我的《系统架构设计 System Design 2020 版》讲座交流学习。结尾会提供应对思路。
需要确定设计哪些功能,承受多大的访问量?
这里要知道秒杀系统的常见概念QPS(Queries Per Second),即一秒内可以处理的请求数量。
假如一个服务的RT(Response time)是20ms,则QPS为50(这里计算的是单机单线程QPS,如果要计算集群的话,需要考虑集群数量和线程数量)。
QPS = 100,用你的笔记本做Web服务器足矣。
QPS = 1k,用一台好点的Web服务器也差不多了。
QPS = 1m,则需要建设一个1000台Web服务器的集群。
QPS和服务器/数据库之间的关系:
一台服务器承受量约1k的QPS(考虑到逻辑处理时间以及数据库查询的瓶颈)
一台SQL Database承受量约1k的QPS(如果JOIN和INDEX query比较多的话,这个值会更小)
一台NoSQL Database(Casscandra)承受量约10k的QPS
一台NoSQL Database(Memcached)承受量约1M的QPS
服务可以认为是逻辑处理的整合。对于同一类问题的逻辑处理归并在一个服务中,整个系统可以细分为若干个小的服务。
这里秒杀系统服务设计大致如下:
数据是如何存储和访问的。为每个服务选择合适的存储结构,然后细化数据表结构。这个例子中,秒杀系统数据库设计如下
于是我们可以得到秒杀活动中,数据库之间的关系如图所示
对于秒杀系统来说,就是高并发场景下如何保证系统稳定和高可用,以及后续的优化。感兴趣的同学可以通过电商秒杀系统 - Spring项目实战进行实战演练,目前开放免费体验部分。
常用解决方法有两种:乐观锁和悲观锁
悲观锁的流程如下:在对于数据一致性要求非常高的场景中,一般用悲观锁。
乐观锁流程如下:
可以看到悲观锁的问题是会占用大量的线程资源,可能导致mysql的线程耗尽。而乐观锁在version变动频繁的情况下则不适用,所以秒杀系统就不太适合用乐观锁,因为version(库存)变化太快了。
把库存数据放入到缓存中,利用缓存的原子特性保证同时只有一个线程操作库存。
服务单一职责:
就是我们下单的时候是有一个订单服务,用户登录管理的,但我们秒杀的时候不能把他们放在一起,要单独建立数据库才行。
单一职责的好处就在于即使秒杀没抗住,系统崩了,也不会影响到其他服务的正常运行。
秒杀商品都有他们特定的模板,所以页面只通过前端传输,为了减轻秒杀带给服务器的压力,我们需要在开始之前将csn服务器放进去。
大家应该都能发现,每次秒杀前按钮他都是灰色的。只有时间到了才会变色点击。其实这是因为系统担心大家在最后击秒疯狂请求服务器,导致服务器还没开始就挂了。但如果设置了按钮,就会减轻许多压力。
一般后台程序员会对秒杀人数进行控制,如何实现呢?其实就是靠预约机制。
比如一场秒杀活动开始前有50000人预约,在预约完成后,秒杀开始前,服务器会给每个用户打标签,去掉高风险用户,去点已经参加过活动的用户,去点其他规则不认可的用户后,在剩下的人里进行秒杀抢购。这就是我为什么说,有的人一开始就注定抢不到的原因。
但这也几乎是每家电商公司都会去做的事,常规操作。
到这里其实就解释完了所有关于秒杀限购及为什么你抢不到的原因了。希望对你有所帮助。
