什么是秒杀?秒杀场景一般是电商网站在节假日在12306网站举办一些活动或者抢票。对于电商网站上的一些稀缺或特价商品,电商网站一般会在约定的时间点限量发售,因为这些商品的特殊性,会吸引大量用户抢购购买它们,它们将在闪购页面上的约定时间点闪购同时出售。秒杀系统场景特点秒杀时大量用户同时抢购,网站流量瞬间暴增。在秒杀中,访问请求的数量远大于存量,只有小部分用户能够秒杀成功。秒杀的业务流程比较简单,一般就是下单,减少库存。秒杀架构设计理念限流:由于只有小部分用户能够成功秒杀,所以需要对大部分流量进行限流,只允许少量流量进入服务后台。削峰:秒杀系统瞬间会有大量用户涌入,所以在抢购开始的时候会有很高的瞬时峰值。高峰流量是压垮系统的一个很重要的原因,那么如何把瞬间的高流量变成一段时间内的稳定流量也是秒杀系统设计的一个重要思路。实现调峰的常用方法是使用缓存、消息中间件等技术。异步处理:秒杀系统是一个高并发系统。使用异步处理方式可以大大提高系统的并发度。实际上,异步处理是一种实现调峰的方式。内存缓存:秒杀系统最大的瓶颈一般是数据库读写。因为数据库读写属于磁盘IO,性能很低。如果能把一些数据或者业务逻辑转移到内存缓存中,效率会大大提高。可扩展性:当然,如果我们要支持更多的用户和更大的并发量,最好把系统设计得具有弹性和可扩展性。如果流量来了,就扩充机器。淘宝、京东等双十一活动期间,都会增加大量机器来应对交易高峰。设计思路是拦截系统上游的请求,减轻下游压力:秒杀系统的特点是并发量大,但实际秒杀成功的请求很少,所以如果不在前端拦截,很可能造成数据库读写锁冲突,甚至造成死锁,最终导致请求超时。充分利用缓存:使用缓存可以大大提高系统的读写速度。消息队列:消息队列可以削峰填谷,会拦截大量的并发请求。这也是一个异步处理过程。后台业务根据自身处理能力主动从消息队列中拉取请求消息进行业务处理。前端解决方案Browserside(js):pagestatic:将活动页面上所有可以静态的元素静态化,尽量减少动态元素。通过CDN防秒杀。禁止重复提交:用户提交后,按钮呈灰色,禁止重复提交Uid(UserID)访问频率:上面我们已经拦截了浏览器访问请求,但是对于一些恶意攻击或者其他插件,服务器控制层需要限制相同访问uid的访问频率。服务层只拦截了一部分访问请求。当有大量秒杀用户时,即使每个用户只有一次请求,对服务层的请求量仍然很大。比如我们有100W用户同时抢100台手机,服务层的并发请求压力至少有100W。使用消息队列缓存请求:既然服务层知道手机库存只有100部,没必要把100W个请求都传给数据库,那么可以先把这些请求写到消息队列中缓存,并且数据库层订阅减库存消息,减库存请求成功返回秒杀成功,失败返回秒杀结束。使用缓存处理读请求:对于12306等票务业务,是典型的读多写少的业务。大多数请求都是查询请求,所以可以使用缓存来分担数据库的压力。使用缓存来处理写请求:缓存也可以处理写请求。比如我们可以将数据库中的库存数据转移到Redis缓存中。所有的减库存操作都在Redis中进行,然后通过后台进程,将用户在Redis中的秒杀请求同步到数据库中。数据库层数据库层是最脆弱的层。通常,在应用设计时需要对请求进行上游拦截,数据库层只承担“力所能及”的访问请求。因此,通过在上面的服务层引入队列和缓存,底层的数据库就可以高枕无忧了。
