秒杀设计

业务背景

首页展示秒杀商品,用户参与秒杀的前提是有积分。在秒杀时间到用户可直接点击兑换此秒杀商品,秒杀成功则生成对应订单且扣除用户积分。

架构图

业务流程

在架构层采用单一职责的设计,单独秒杀系统服务、单独的库表。数据库读写分离(MaxScale),mysql集群部署采用MHA方式 ​

下单执行的流程是:用户点击下单请求经过openresty,openresty会查询redis缓存验证一些前置校验(验证码,活动是否已结束、是否黑名单、库存是否充足等) ​

当满足openresty前置验证条件会进入tomcat服务端,在服务端会采用sentinel做限流熔断降级的保护 ​

执行扣缓存中的用户积分、库存和生成一个状态是处理中的订单返回给浏览器(前端3秒一次轮询查询订单成功或失败)。

​异步执行扣积分、扣库存、更新订单状态此三步通过Stata TCC事务模型处理,当事务执行成功则发送订单创建成功消息(如冗余的商家对订单表的创建、物流系统处理、统计分析系统处理)。 ​

如果订单失败则返还积分、库存、更新订单状态失败状态。

业务流程图

问题解析

  1. 业务系统很依赖redis缓存,服务端是先扣缓存中的库存和积分,之后是异步处理真实的扣库存和积分,如果缓存服务器挂了怎么解决?出现缓存中积分剩余7,真实数据库还是10, 在异步执行时,缓存服务器挂了,用户查询是是10积分(此时异步执行真实扣除积分:执行成功会真正的扣除用户积分,用户刷新即看到自己剩余7积分,执行失败则不做任何处理,不影响积分的展示。
  2. 超卖的解决方案:更新时数据库采用乐观锁如要扣除2个库存 update stock set num = num -2 where id = id and stock - 2 >= 0
  3. 限流降级:访问过多会在openresty层和服务层都会做限流,openresty层拦截则直接提示售卖完成,服务端则提升服务繁忙,请稍后重试
  4. 在异步执行扣积分、库存、更新订单,某一步骤挂了会怎么样?(会回滚缓存中的库存+积分,也有重试机制可以保证一致性)
  5. 如果生成订单在异步失败,用户是否还能在下单(可以下单,校验是通过活动id+订单状态来决定)
  6. 库存验证可以说详细一点,如何保证扣减和验证的原子性(将get和set放到redis lua脚本执行保证原则性)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值