秒杀实用方案

秒杀的场景一般就是秒杀开始的前几分钟,大量用户进入商品详情界面,不断刷新。这时候系统的其他功能压力会变大。实际上,基本都是秒杀参与人多,秒杀成功的人很少。如何设计秒杀系统:

1.页面静态化

因为要秒杀的哪些商品,价格等信息都已经在秒杀之前就已经确定了,所以我们可以把相关信息全部放到这个静态页面中,然后把这个页面传到CDN上进行预热,用CDN抗流量。

2.请求拦截

前端,点击按钮置灰,防止重复提交

网关,避免攻击脚本,对下单等接口按userId限流,几秒钟只允许请求一次,更有甚者,其实可以把绝大部分的请求直接在网关层拒绝掉,按秒杀失败处理。比如我们有200个库存,我们可以只放行200个请求到后端服务,同时200个请求不是一起放行的,每隔100ms放行10个,把请求分在在各个时间段,缓解后端服务器的压力。

秒杀过程网关压力会比较大,网关可以做成集群,多节点分摊访问压力。

3.后端服务设计

假如秒杀库存就有几百万个,放行的下单就有几万个,这时候压力就在数据库了,扣减库存压力,创建订单压力。

库存可以放在Redis里面,来提高扣减库存吞吐的能力,对于热点商品的库存可以利用Redis分片存储。

创建订单可以走异步消息队列。后端服务接到下单请求,直接放进消息队列,监听服务取出消息后,先将订单信息写入Redis,每隔100ms或者积攒100条订单,批量写入数据库一次。前端页面下单后定时向后端拉取订单信息,获取到订单信息后跳转到支付页面。用这种批量异步写入数据库的方式大幅减少了数据库写入频次,从而明显降低了订单数据库写入压力。

4.隔离

业务隔离。从业务上把秒杀和日常的售卖区分开来,把秒杀做为营销活动,要参与秒杀的商品需要提前报名参加活动,这样我们就能提前知道哪些商家哪些商品要参与秒杀,可以根据提报的商品提前生成静态页面并上传到CDN预热,提报的商品库存也需要提前预热,可以将商品库存在活动开始前预热到Redis,避免秒杀开始后大量的缓存穿透。

部署隔离。秒杀相关服务和日常服务要分组部署,不能因为秒杀出问题影响日常售卖业务。可以申请单独的秒杀域名,从网络入口层就开始分流。网关也单独部署,秒杀走自己单独的网关,从而避免日常网关受到影响。秒杀可以复用订单,库存,支付等日常服务,只是需要一些小的改造(比如下单流程走消息队列,批量写入订单库,以及在Redis中扣减库存)。

数据隔离。为了避免秒杀活动影响到日常售卖业务,Redis缓存需要单独部署,甚至数据库也需要单独部署!数据隔离后,秒杀剩余的库存怎么办?秒杀活动结束后,剩余库存可以归还到日常库存继续做为普通商品售卖。数据隔离后,秒杀订单和日常订单不在相同的数据库,之后的订单查询怎么展示?可以在创建秒杀订单后发消息到消息队列,日常订单服务采取拉的方式消费消息,这时日常订单服务是主动方,可以采用线程池的方式,根据机器的性能来增加或缩小线程池的大小,控制拉取消息的速度,来控制订单数据库的写入压力。

5.网络

秒杀前要和网络运营商、CDN服务商提前申请带宽。

Guess you like

Origin blog.csdn.net/Chen_leilei/article/details/119736449