开发者社区> 问答> 正文

关于高并发下单

最近有看到博文说高并发下单解决方案使用缓存+异步的方式。下单的时候从缓存中获取用户数据和商品数据,然后生成订单号,通过消息队列异步完成订单入库。不明白的地方,如何异步下单如何确保订单入库成功?订单成功之后,用户看到的订单数据是从数据库查询还是在缓存中获取?

展开
收起
wolf、heart 2018-01-27 22:07:44 5086 0
3 条回答
写回答
取消 提交回答
  • 使用缓存+中间件的目的主要是为了提升下单接口的吞吐能力,至于怎么解决的我们分析下流程,有什么问题在交流不对的地方指正一下。

    1. 商品详情页-购买-订单确认页(此时还没有生产订单只是商品数据可来自缓存)-提交订单(执行2-7逻辑)-支付页
    2. 缓存中预热的(提前从数据库中把数据放入缓存)是要参加秒杀商品信息(包括库存数量),并对商品设置过期时间,这个时间应该是秒杀商品的结束时间,这么做主要是缓解数据库压力提升响应速度。
    3. 并发秒杀(提交订单)时候先从缓存中查询是否有此商品,没有说明秒杀结束了,有的话去预扣商品的库存数量。
    4. 如果预扣成功说明库存充足可以下单,响应给前端一个状态,并去发消息到消息中间件,订单服务去消费此消息然后开始真正的数据库库存扣减,扣减成功开始生成订单并入库。异步解耦订单生成逻辑提升下单接口吞吐量。
    5. 前端订单确认页面可以去轮询查询订单生成结果,一般有三种结果:生成订单失败既秒杀失败或者还未消费到消息(排队中)如果成功则去支付页面。
    6. 这里的异步生成订单不存在分布式事务问题,因为预扣库存仅仅是去缓存中扣减库存数量,如果此时失败并不会发送消息,如果成功那么消息也应该被消费。由于采用是轮询结果的方式所以即便订单生成失败用户重新下单即可并不是必须要保证最终一致的场景。
    7. 订单成功后是从数据库获取的订单信息缓存中并没有。
    2019-07-17 21:56:34
    赞同 展开评论 打赏
  • 先将基础数据落booking库,订单具体处理、支付回调在order库中处理,用消息异步解耦。

    2019-07-17 21:56:34
    赞同 展开评论 打赏
  • 你问的东西要回答清楚可不是一二句话的事情,这里简单介绍下。

    一般来说,你所谓的缓存一般可以缓存用户数据和热点商品数据,而商品通用标签模型可选用分布式集群的NoSQL进行存储,重要的数据需要做实时或异步刷磁盘持久化操作,大多数系统下单时并不是从缓存拿库存(缓存存取库存需要保证一致性,一般要求强一致性,业务实现复杂度相对较高,部分业务场景在设计时会考虑弱一致性,比如非热点店铺非热点商品的库存展示可以使用较短间隔的缓存)。
    异步的目标是削峰填谷,提高单位时间内系统通行量,突破高并发时的系统瓶颈,下单过程部分数据选用了异步就一定要做好最终一致性,保证异步的数据最终都能同步成功,否则不适合异步。

    类似这样的系统,解决方案是:减少不必要的请求(缓存+按需开启or关闭入口)+内存计算&存储+事件MQ异步解耦拆分+业务服务和数据服务拆分等方式实现。

    2019-07-17 21:56:34
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
徐雷-Java为王,互联网高并发架构设计与选型之路6.0 立即下载
Redis 的高并发实战:抢购系统 立即下载
MySQL高并发场景实战 立即下载