大促秒杀场景技术方案
背景
每年各大电商都会有大促秒杀活动,秒杀活动主要特点:商品数量有限、流量超级大。秒杀形式分为集中抢购或分多个时间段进行售卖。
系统架构
系统设计面临挑战
系统稳定性:在大流量冲击下,如何保证系统稳定不宕机。
数据一致性问题:秒杀商品必定涉及库存,如何保证商品不会超卖。
防刷:防止黑产用户直接刷接口,拦截无效请求。
解决方案
限流:
客户端
考虑在活动开始前按钮置灰。
秒杀前用户是无法获取秒杀 url。活动开始后,后台通过 md5 加密随机字符生成 url,前端通过调接口获取 url,服务端校验通过后才可继续秒杀。
在购买页增加验证码/滑块/答题达到错峰效果。
服务端
风控校验:利用大数据给用户画像,通过分析设备及 IP 信息,筛选出风控用户。
签名校验:前端在秒杀前将特征数据加密,生成签名保存在服务端,作为下一次是否合法请求依据(防黑产用户跳过页面,直接刷接口)。
频率锁校验:对用户访问频率设限。
黑白名单校验:利用黑白名单机制,支持运营配置。非法请求特殊认定:当前端有滑块或答题方式,基本可以把 0.5 秒内的所有请求拦截)来防止刷单。
登录校验:利用 token 识别请求来源是否是真实用户。
应用层
利用令牌桶、计数器算法实现应用级限流。
缓存:
客户端
页面静态化,缓存到 CDN,避免对服务器直接访问。
服务端
活动预热。
库存及热点数据可以放入 redis 缓存,活动描述及须知甚至可以通过军刀系统存储在本地缓存中,减少数据库压力。
异步:
a. 用户抢购成功立即返回,通过消息队列异步处理后续逻辑,包括:更新数据库、数据上报、通知用户等,缓解服务器压力。
b. 采用多线程编程。
分流:
a. 应用服务采用集群部署,通过负载均衡共同处理前端请求。
b. 采用 redis 集群,提升性能。
熔断:
a. 调用服务故障时,设置超时时间及重试次数。
b. 采用断路器方式阻断对故障服务调用。
降级:
a. 秒杀过程出现宕机,做好后备工作,快速降级问题接口。
b. 至少要有万能出错页:访问量太大,稍后重试。
防止商品超卖策略
针对并发量较大的抢购,通常采用先扣减 redis 库存方式。如果还有库存,先发送 mq。通过异步处理消息并保证幂等性,更新数据库库存及后续抢购逻辑。
如果并发量不大,可以不采用 mq。直接利用乐观锁(update good set stock=stock-1 where id=#{id} and version=#{version} and stock>0),直接对数据库进行库存扣减,扣减成功后,再更新缓存。以上操作放到同一事务中,防止超卖。如果是少卖,可以放到下轮秒杀中。
总结
为保证系统稳定性,需要通过以下手段:
解耦:秒杀系统与业务系统隔离。
限流:通过各种判断条件,过滤到非正常流量。
缓存:通过页面静态化、活动预热、热点数据缓存等方式提高系统性能,缓解服务器压力。
异步:多线程编程或采用 MQ 方式处理。
幂等性:服务重复调用不可避免,必须保证服务重复请求和调用一次产生的结果相同(例如:设置请求防重锁、防止 MQ 重复消费等)。
数据一致性:商品库存采用合适策略防止超卖。如果流量不大,可以采用乐观锁方式,将缓存和数据库操作放在同一事务中。针对大流量,可以通过分布式事务补偿机制,通过执行业务逻辑逆操作,保证数据最终一致性。
熔断:当某个服务故障时,继续调用会导致请求阻塞,增加资源消耗。可以设置调用超时时间及次数。更进一步可以采用断路器方式阻断对故障服务调用。
集群:应用采用集群部署,通过负载均衡策略处理请求。甚至可采用异地多活多机房架构策略。
报警:系统上各种监控。报警方式包括:邮件、手机短信、手机语音,即使在夜间也能及时通知,迅速响应。
降级:如果超出最初设想,有相应降级预案。最起码要有访问量太大稍后重试等友好提示。
版权声明: 本文为 InfoQ 作者【Mars】的原创文章。
原文链接:【http://xie.infoq.cn/article/757d92363268393f497cb2ef3】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论