秒杀场景的处理方式
https://www.cnblogs.com/mengxw/p/9288678.html
因为业务的关系,曾经在2年前经历过一些秒杀的场景,现在简单总结一下:
业务背景:工具性产品,因为产品的关系需要搞一些活动,增加用户的粘性以及品牌传播等效果;秒杀就是其中一个需求。
量级:系统的DAU大概是千万+,秒杀活动在H5页端实现,通过客户端内配置入口的方式以及消息推送引导用户参与活动。
总结:个人感觉秒杀分两种场景:库存量大的和库存量小的。
1、库存量小的:经历过雅马哈摩托车、iphone等手机的秒杀场景,这种一般库存很小
限流使用cas的atomicLong计数器,在不同框架的拦截器进行计数器的加减操作,配置合适的阀值,放特定的流量进入后续库存竞争流程,
减库存:使用sql语句:update prize_table set stock = stock -1 where stock > 0 and prizeId=?,返回数字1则减库存成功,否则失败,可以避免并发场景下的超卖行为。
2、库存量大的:经历过优惠码的派发等。
方案一:将库存数据存储到分布式缓存中,在缓存中利用原子操作进行减库存行为,可以承受更大的库存量。同时可以对库存进行分组,使库存操作分布到不同服务器。
方案二:利用数据库的分库分表,将库存进行打散,如果数据库服务器配置较好,数据库能承受的qps也是很高的,可以请教DBA给出建议,通过数据库的方式可以对库存的控制更精准。
其他:总结的部分基本只是针对应用层面的一些处理,还是有很多细节要考虑,即使按照这种方式,可能一个代码的bug也会造成超卖,所以要严格的测试,对可能抛出的异常进行代码review,是否考虑到了各类异常和边界场景。
之所以没有提路由层的一些设置,主要是在当时的业务场景下,路由集群足够强大,同时也开启了限流,路由承受的量如果全部打入到秒杀应用集群,应用集群是承受不住的。从业务上来说也不需要每个来的请求都要进行处理。