# 第19节:扫描库表补偿发货单MQ消息

作者:小傅哥
博客:https://bugstack.cn (opens new window)

沉淀、分享、成长,让自己和他人都能有所收获!

# 一、开发日志

  • 由于本章节需要用到 Redis 所以我们在云服务器搭建 Redis 服务,这样可以更加方便的使用。如果你暂时还没有云服务器,那么在本地搭建 Redis 也可以,只是少了一些云环境的配置练习 云服务器地址 (opens new window)
  • 在抽奖系统中引入 Redis 模块,优化用户参与抽奖活动。因为只要有大量的用户参与抽奖,那么这个就属于秒杀场景。所以需要使用 Redis 分布式锁的方式来处理集中化库存扣减的问题,否则在 TPS 达到1k-2k,就会把数据库拖垮。
  • 在设计秒杀流程时,优化锁的颗粒度力度,不要把锁直接放到活动编号上,这样在极端临界情况下会出现秒杀解锁失败,导致库存有剩余但不能下单的情况。所以需要增加锁的颗粒度,以滑动库存剩余编号的方式进行加锁,例如 100001_1、100001_2、100001_3,以此类推,具体看代码实现。
  • 增加缓存扣减库存后,发送 MQ 消息进行异步更新数据库中活动库存,做最终数据一致性处理。这一部分如果你的系统并发体量较大,还需要把 MQ 的数据不要直接对库更新,而是更新到缓存中,再由任务最阶段同步,以此减少对数据库表的操作

# 二、扣减流程

  • 优化活动领域,活动参与流程中的库存扣减操作,这部分我们原来是使用数据库行级锁🔐 处理的库存扣减,但因为会存在并发问题所以这里优化为 Redis 分布式锁进行处理。
  • 活动领取完成后,其实这个时候只是把缓存的库存扣掉了,但数据库中的库存并没有扣减,所以我们需要发送一个 MQ 消息,来对数据库中的库存进行处理。因为 MQ 可以消峰因此在降低 MQ 分片的情况下,消费效率有所下降,并不会对数据库造成压力,保证最终数据一致性即可。但也有例外,所以我们提到可以使用定时任务来更新数据库库存